diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 3f89245..df459d1 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -47,8 +47,6 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/generated/engine.dart';
@@ -198,6 +196,10 @@
     return _onAnalysisStartedController.stream;
   }
 
+  String get sdkPath {
+    return sdkManager.defaultSdkDirectory;
+  }
+
   /// The socket from which requests are being read has been closed.
   void done() {}
 
@@ -205,17 +207,6 @@
   /// read.
   void error(argument) {}
 
-  /// Return one of the SDKs that has been created, or `null` if no SDKs have
-  /// been created yet.
-  DartSdk findSdk() {
-    var sdk = sdkManager.anySdk;
-    if (sdk != null) {
-      return sdk;
-    }
-    // TODO(brianwilkerson) Should we create an SDK using the default options?
-    return null;
-  }
-
   /// Return the cached analysis result for the file with the given [path].
   /// If there is no cached result, return `null`.
   ResolvedUnitResult getCachedResolvedUnit(String path) {
@@ -388,7 +379,6 @@
   /// projects/contexts support.
   void setAnalysisRoots(String requestId, List<String> includedPaths,
       List<String> excludedPaths) {
-    declarationsTracker?.discardContexts();
     if (notificationManager != null) {
       notificationManager.setAnalysisRoots(includedPaths, excludedPaths);
     }
@@ -397,7 +387,6 @@
     } on UnimplementedError catch (e) {
       throw RequestFailure(Response.unsupportedFeature(requestId, e.message));
     }
-    addContextsToDeclarationsTracker();
     analysisDriverScheduler.transitionToAnalyzingToIdleIfNoFilesToAnalyze();
   }
 
@@ -408,29 +397,13 @@
       notificationManager.setSubscriptions(subscriptions);
     }
     analysisServices = subscriptions;
-    var allNewFiles = subscriptions.values.expand((files) => files).toSet();
-    for (var file in allNewFiles) {
-      // The result will be produced by the "results" stream with
-      // the fully resolved unit, and processed with sending analysis
-      // notifications as it happens after content changes.
-      if (AnalysisEngine.isDartFileName(file)) {
-        getResolvedUnit(file, sendCachedToStream: true);
-      }
-    }
+    _sendSubscriptions(analysis: true);
   }
 
   /// Implementation for `flutter.setSubscriptions`.
   void setFlutterSubscriptions(Map<FlutterService, Set<String>> subscriptions) {
     flutterServices = subscriptions;
-    var allNewFiles = subscriptions.values.expand((files) => files).toSet();
-    for (var file in allNewFiles) {
-      // The result will be produced by the "results" stream with
-      // the fully resolved unit, and processed with sending analysis
-      // notifications as it happens after content changes.
-      if (AnalysisEngine.isDartFileName(file)) {
-        getResolvedUnit(file, sendCachedToStream: true);
-      }
-    }
+    _sendSubscriptions(flutter: true);
   }
 
   /// Implementation for `analysis.setGeneralSubscriptions`.
@@ -467,8 +440,7 @@
     // during normal analysis (for example dot folders are skipped over in
     // _handleWatchEventImpl).
     return contextManager.isInAnalysisRoot(file) &&
-        !contextManager.isContainedInDotFolder(file) &&
-        !contextManager.isIgnored(file);
+        !contextManager.isContainedInDotFolder(file);
   }
 
   Future<void> shutdown() {
@@ -596,6 +568,31 @@
       scheduleImplementedNotification(this, files);
     }
   }
+
+  void _sendSubscriptions({bool analysis = false, bool flutter = false}) {
+    var files = <String>{};
+
+    if (analysis) {
+      analysisServices.values.forEach((serviceFiles) {
+        files.addAll(serviceFiles);
+      });
+    }
+
+    if (flutter) {
+      flutterServices.values.forEach((serviceFiles) {
+        files.addAll(serviceFiles);
+      });
+    }
+
+    for (var file in files) {
+      // The result will be produced by the "results" stream with
+      // the fully resolved unit, and processed with sending analysis
+      // notifications as it happens after content changes.
+      if (AnalysisEngine.isDartFileName(file)) {
+        getResolvedUnit(file, sendCachedToStream: true);
+      }
+    }
+  }
 }
 
 /// Various IDE options.
@@ -642,14 +639,30 @@
       analysisServer.notificationManager;
 
   @override
-  nd.AnalysisDriver addAnalysisDriver(Folder folder, ContextRoot contextRoot) {
-    var builder = createContextBuilder(folder);
-    var workspace = ContextBuilder.createWorkspace(
-      resourceProvider: resourceProvider,
-      options: builder.builderOptions,
-      rootPath: folder.path,
-    );
-    var analysisDriver = builder.buildDriver(contextRoot, workspace);
+  void afterContextsCreated() {
+    analysisServer.addContextsToDeclarationsTracker();
+    analysisServer._sendSubscriptions(analysis: true, flutter: true);
+  }
+
+  @override
+  void afterWatchEvent(WatchEvent event) {
+    analysisServer._onAnalysisSetChangedController.add(null);
+  }
+
+  @override
+  void applyFileRemoved(String file) {
+    sendAnalysisNotificationFlushResults(analysisServer, [file]);
+  }
+
+  @override
+  void broadcastWatchEvent(WatchEvent event) {
+    analysisServer.notifyDeclarationsTracker(event.path);
+    analysisServer.notifyFlutterWidgetDescriptions(event.path);
+    analysisServer.pluginManager.broadcastWatchEvent(event);
+  }
+
+  @override
+  void listenAnalysisDriver(nd.AnalysisDriver analysisDriver) {
     analysisDriver.results.listen((result) {
       var notificationManager = analysisServer.notificationManager;
       var path = result.path;
@@ -757,66 +770,6 @@
     });
     analysisDriver.exceptions.listen(analysisServer.logExceptionResult);
     analysisDriver.priorityFiles = analysisServer.priorityFiles.toList();
-    analysisServer.driverMap[folder] = analysisDriver;
-    return analysisDriver;
-  }
-
-  @override
-  void afterContextRefresh() {
-    analysisServer.addContextsToDeclarationsTracker();
-  }
-
-  @override
-  void afterWatchEvent(WatchEvent event) {
-    analysisServer._onAnalysisSetChangedController.add(null);
-  }
-
-  @override
-  void analysisOptionsUpdated(nd.AnalysisDriver driver) {
-    analysisServer.updateContextInDeclarationsTracker(driver);
-  }
-
-  @override
-  void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
-    var analysisDriver = analysisServer.driverMap[contextFolder];
-    if (analysisDriver != null) {
-      changeSet.addedFiles.forEach((path) {
-        analysisDriver.addFile(path);
-      });
-      changeSet.changedFiles.forEach((path) {
-        analysisDriver.changeFile(path);
-      });
-      changeSet.removedFiles.forEach((path) {
-        analysisDriver.removeFile(path);
-      });
-    }
-  }
-
-  @override
-  void applyFileRemoved(nd.AnalysisDriver driver, String file) {
-    driver.removeFile(file);
-    sendAnalysisNotificationFlushResults(analysisServer, [file]);
-  }
-
-  @override
-  void broadcastWatchEvent(WatchEvent event) {
-    analysisServer.notifyDeclarationsTracker(event.path);
-    analysisServer.notifyFlutterWidgetDescriptions(event.path);
-    analysisServer.pluginManager.broadcastWatchEvent(event);
-  }
-
-  @override
-  ContextBuilder createContextBuilder(Folder folder) {
-    var builderOptions = ContextBuilderOptions();
-    var builder = ContextBuilder(
-        resourceProvider, analysisServer.sdkManager, null,
-        options: builderOptions);
-    builder.analysisDriverScheduler = analysisServer.analysisDriverScheduler;
-    builder.performanceLog = analysisServer.analysisPerformanceLogger;
-    builder.byteStore = analysisServer.byteStore;
-    builder.enableIndex = true;
-    builder.lookForBazelBuildFileSubstitutes = false;
-    return builder;
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index a5744ac..7d4584e 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -177,8 +177,15 @@
           CompletionLibrariesWorker(declarationsTracker);
     }
 
-    contextManager = ContextManagerImpl(resourceProvider, sdkManager,
-        analyzedFilesGlobs, instrumentationService);
+    contextManager = ContextManagerImpl(
+      resourceProvider,
+      sdkManager,
+      byteStore,
+      analysisPerformanceLogger,
+      analysisDriverScheduler,
+      analyzedFilesGlobs,
+      instrumentationService,
+    );
     searchEngine = SearchEngineImpl(driverMap.values);
   }
 
@@ -217,6 +224,7 @@
   }
 
   void addContextsToDeclarationsTracker() {
+    declarationsTracker?.discardContexts();
     for (var driver in driverMap.values) {
       declarationsTracker?.addContext(driver.analysisContext);
       driver.resetUriResolution();
@@ -409,11 +417,6 @@
     bool fatal = false,
   });
 
-  void updateContextInDeclarationsTracker(nd.AnalysisDriver driver) {
-    declarationsTracker?.discardContext(driver.analysisContext);
-    declarationsTracker?.addContext(driver.analysisContext);
-  }
-
   /// Return the path to the location of the byte store on disk, or `null` if
   /// there is no on-disk byte store.
   String _getByteStorePath() {
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index fbca822..4430ee5 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -5,17 +5,18 @@
 import 'dart:async';
 import 'dart:collection';
 import 'dart:core';
+import 'dart:io';
 
 import 'package:analysis_server/src/plugin/notification_manager.dart';
 import 'package:analysis_server/src/services/correction/fix/data_driven/transform_set_parser.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/context/packages.dart';
+import 'package:analyzer/src/dart/analysis/analysis_context_collection.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/driver_based_analysis_context.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -25,11 +26,8 @@
 import 'package:analyzer/src/lint/pub.dart';
 import 'package:analyzer/src/manifest/manifest_validator.dart';
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
-import 'package:analyzer/src/source/package_map_resolver.dart';
-import 'package:analyzer/src/source/path_filter.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/util/glob.dart';
-import 'package:analyzer/src/util/yaml.dart';
 import 'package:analyzer/src/workspace/bazel.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
@@ -45,153 +43,6 @@
 /// Not private to enable testing.
 var experimentalEnableBazelWatching = false;
 
-/// An indication of which files have been added, changed, removed, or deleted.
-///
-/// No file should be added to the change set more than once, either with the
-/// same or a different kind of change. It does not make sense, for example,
-/// for a file to be both added and removed.
-class ChangeSet {
-  /// A list containing paths of added files.
-  final List<String> addedFiles = [];
-
-  /// A list containing paths of changed files.
-  final List<String> changedFiles = [];
-
-  /// A list containing paths of removed files.
-  final List<String> removedFiles = [];
-
-  /// Record that the file with the specified [path] has been added.
-  void addedSource(String path) {
-    addedFiles.add(path);
-  }
-
-  /// Record that the file with the specified [path] has been removed.
-  void removedSource(String path) {
-    removedFiles.add(path);
-  }
-}
-
-/// Information tracked by the [ContextManager] for each context.
-class ContextInfo {
-  /// The [Folder] for which this information object is created.
-  final Folder folder;
-
-  /// The [PathFilter] used to filter sources from being analyzed.
-  final PathFilter pathFilter;
-
-  /// The enclosed pubspec-based contexts.
-  final List<ContextInfo> children = <ContextInfo>[];
-
-  /// The [ContextInfo] that encloses this one, or `null` if this is the virtual
-  /// [ContextInfo] object that acts as the ancestor of all other [ContextInfo]
-  /// objects.
-  ContextInfo parent;
-
-  /// The package description file path for this context.
-  String packageDescriptionPath;
-
-  /// The folder disposition for this context.
-  final FolderDisposition disposition;
-
-  /// Paths to files which determine the folder disposition and package map.
-  ///
-  /// TODO(paulberry): if any of these files are outside of [folder], they won't
-  /// be watched for changes.  I believe the use case for watching these files
-  /// is no longer relevant.
-  Set<String> _dependencies = <String>{};
-
-  /// The analysis driver that was created for the [folder].
-  AnalysisDriver analysisDriver;
-
-  /// Map from full path to the [Source] object, for each source that has been
-  /// added to the context.
-  Map<String, Source> sources = HashMap<String, Source>();
-
-  ContextInfo(ContextManagerImpl contextManager, this.parent, this.folder,
-      File packagespecFile, this.disposition)
-      : pathFilter = PathFilter(
-            folder.path, null, contextManager.resourceProvider.pathContext) {
-    packageDescriptionPath = packagespecFile.path;
-    parent.children.add(this);
-  }
-
-  /// Create the virtual [ContextInfo] which acts as an ancestor to all other
-  /// [ContextInfo]s.
-  ContextInfo._root()
-      : folder = null,
-        pathFilter = null,
-        disposition = null;
-
-  /// Iterate through all [children] and their children, recursively.
-  Iterable<ContextInfo> get descendants sync* {
-    for (var child in children) {
-      yield child;
-      yield* child.descendants;
-    }
-  }
-
-  /// Returns `true` if this is a "top level" context, meaning that the folder
-  /// associated with it is not contained within any other folders that have an
-  /// associated context.
-  bool get isTopLevel => parent.parent == null;
-
-  /// Returns `true` if [path] is excluded, as it is in one of the children.
-  bool excludes(String path) {
-    return children.any((child) {
-      return child.folder.contains(path);
-    });
-  }
-
-  /// Returns `true` if [resource] is excluded, as it is in one of the children.
-  bool excludesResource(Resource resource) => excludes(resource.path);
-
-  /// Return the first [ContextInfo] in [children] whose associated folder is or
-  /// contains [path].  If there is no such [ContextInfo], return `null`.
-  ContextInfo findChildInfoFor(String path) {
-    for (var info in children) {
-      if (info.folder.isOrContains(path)) {
-        return info;
-      }
-    }
-    return null;
-  }
-
-  /// Determine if the given [path] is one of the dependencies most recently
-  /// passed to [setDependencies].
-  bool hasDependency(String path) => _dependencies.contains(path);
-
-  /// Returns `true` if  [path] should be ignored.
-  bool ignored(String path) => pathFilter.ignored(path);
-
-  /// Update the set of dependencies for this context.
-  void setDependencies(Iterable<String> newDependencies) {
-    _dependencies = newDependencies.toSet();
-  }
-
-  /// Return `true` if the given [path] is managed by this context or by
-  /// any of its children.
-  bool _managesOrHasChildThatManages(String path) {
-    if (parent == null) {
-      for (var child in children) {
-        if (child._managesOrHasChildThatManages(path)) {
-          return true;
-        }
-      }
-      return false;
-    } else {
-      if (!folder.isOrContains(path)) {
-        return false;
-      }
-      for (var child in children) {
-        if (child._managesOrHasChildThatManages(path)) {
-          return true;
-        }
-      }
-      return !pathFilter.ignored(path);
-    }
-  }
-}
-
 /// Class that maintains a mapping from included/excluded paths to a set of
 /// folders that should correspond to analysis contexts.
 abstract class ContextManager {
@@ -224,16 +75,10 @@
   /// to [setRoots].
   List<String> get includedPaths;
 
-  /// Like [getDriverFor], but returns the [Folder] which allows plugins to
-  /// create & manage their own tree of drivers just like using [getDriverFor].
-  ///
-  /// This folder should be the root of analysis context, not just the
-  /// containing folder of the path (like basename), as this is NOT just a file
-  /// API.
-  ///
-  /// This exists at least temporarily, for plugin support until the new API is
-  /// ready.
-  Folder getContextFolderFor(String path);
+  /// Return the existing analysis context that should be used to analyze the
+  /// given [path], or `null` if the [path] is not analyzed in any of the
+  /// created analysis contexts.
+  DriverBasedAnalysisContext getContextFor(String path);
 
   /// Return the [AnalysisDriver] for the "innermost" context whose associated
   /// folder is or contains the given path.  ("innermost" refers to the nesting
@@ -244,32 +89,19 @@
   /// If no driver contains the given path, `null` is returned.
   AnalysisDriver getDriverFor(String path);
 
-  /// Return a list of all of the analysis drivers reachable from the given
-  /// [analysisRoot] (the driver associated with [analysisRoot] and all of its
-  /// descendants).
-  List<AnalysisDriver> getDriversInAnalysisRoot(Folder analysisRoot);
-
   /// Determine whether the given [path], when interpreted relative to innermost
   /// context root, contains a folder whose name starts with '.'.
+  ///
+  /// TODO(scheglov) Remove it, just [isInAnalysisRoot] should be enough.
   bool isContainedInDotFolder(String path);
 
-  /// Return `true` if the given [path] is ignored by a [ContextInfo] whose
-  /// folder contains it.
-  bool isIgnored(String path);
-
   /// Return `true` if the given absolute [path] is in one of the current
   /// root folders and is not excluded.
   bool isInAnalysisRoot(String path);
 
-  /// Return the number of contexts reachable from the given [analysisRoot] (the
-  /// context associated with [analysisRoot] and all of its descendants).
-  int numberOfContextsInAnalysisRoot(Folder analysisRoot);
-
   /// Rebuild the set of contexts from scratch based on the data last sent to
-  /// [setRoots]. Only contexts contained in the given list of analysis [roots]
-  /// will be rebuilt, unless the list is `null`, in which case every context
-  /// will be rebuilt.
-  void refresh(List<Resource> roots);
+  /// [setRoots].
+  void refresh();
 
   /// Change the set of paths which should be used as starting points to
   /// determine the context directories.
@@ -288,34 +120,23 @@
   /// Return the notification manager associated with the server.
   AbstractNotificationManager get notificationManager;
 
-  /// Create and return a new analysis driver rooted at the given [folder].
-  AnalysisDriver addAnalysisDriver(Folder folder, ContextRoot contextRoot);
-
   /// Called after contexts are rebuilt, such as after recovering from a watcher
   /// failure.
-  void afterContextRefresh();
+  void afterContextsCreated();
 
   /// An [event] was processed, so analysis state might be different now.
   void afterWatchEvent(WatchEvent event);
 
-  /// Called when analysis options or URI resolution in the [driver] are
-  /// changed.
-  void analysisOptionsUpdated(AnalysisDriver driver);
-
-  /// Called when the set of files associated with a context have changed (or
-  /// some of those files have been modified).  [changeSet] is the set of
-  /// changes that need to be applied to the context.
-  void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
-
-  /// The given [file] was removed from the folder analyzed in the [driver].
-  void applyFileRemoved(AnalysisDriver driver, String file);
+  /// The given [file] was removed.
+  void applyFileRemoved(String file);
 
   /// Sent the given watch [event] to any interested plugins.
   void broadcastWatchEvent(WatchEvent event);
 
-  /// Create and return a context builder that can be used to create a context
-  /// for the files in the given [folder].
-  ContextBuilder createContextBuilder(Folder folder);
+  /// Add listeners to the [driver]. This must be the only listener.
+  ///
+  /// TODO(scheglov) Just pass results in here?
+  void listenAnalysisDriver(AnalysisDriver driver);
 
   /// Remove the context associated with the given [folder].  [flushedFiles] is
   /// a list of the files which will be "orphaned" by removing this context
@@ -348,6 +169,18 @@
   /// particular context.
   final DartSdkManager sdkManager;
 
+  /// The storage for cached results.
+  final ByteStore _byteStore;
+
+  /// The logger used to create analysis contexts.
+  final PerformanceLog _performanceLog;
+
+  /// The scheduler used to create analysis contexts, and report status.
+  final AnalysisDriverScheduler _scheduler;
+
+  /// The current set of analysis contexts.
+  AnalysisContextCollectionImpl _collection;
+
   /// The context used to work with file system paths.
   pathos.Context pathContext;
 
@@ -370,10 +203,6 @@
   @override
   ContextManagerCallbacks callbacks;
 
-  /// Virtual [ContextInfo] which acts as the ancestor of all other
-  /// [ContextInfo]s.
-  final ContextInfo rootInfo = ContextInfo._root();
-
   @override
   final Map<Folder, AnalysisDriver> driverMap =
       HashMap<Folder, AnalysisDriver>();
@@ -391,6 +220,9 @@
   ContextManagerImpl(
     this.resourceProvider,
     this.sdkManager,
+    this._byteStore,
+    this._performanceLog,
+    this._scheduler,
     this.analyzedFilesGlobs,
     this._instrumentationService,
   ) {
@@ -398,313 +230,50 @@
   }
 
   @override
-  Folder getContextFolderFor(String path) {
-    return _getInnermostContextInfoFor(path)?.folder;
-  }
-
-  /// For testing: get the [ContextInfo] object for the given [folder], if any.
-  ContextInfo getContextInfoFor(Folder folder) {
-    var info = _getInnermostContextInfoFor(folder.path);
-    if (info != null && folder == info.folder) {
-      return info;
+  DriverBasedAnalysisContext getContextFor(String path) {
+    try {
+      return _collection?.contextFor(path);
+    } on StateError {
+      return null;
     }
-    return null;
   }
 
   @override
   AnalysisDriver getDriverFor(String path) {
-    return _getInnermostContextInfoFor(path)?.analysisDriver;
-  }
-
-  @override
-  List<AnalysisDriver> getDriversInAnalysisRoot(Folder analysisRoot) {
-    var drivers = <AnalysisDriver>[];
-    void addContextAndDescendants(ContextInfo info) {
-      drivers.add(info.analysisDriver);
-      info.children.forEach(addContextAndDescendants);
-    }
-
-    var innermostContainingInfo =
-        _getInnermostContextInfoFor(analysisRoot.path);
-    if (innermostContainingInfo != null) {
-      if (analysisRoot == innermostContainingInfo.folder) {
-        addContextAndDescendants(innermostContainingInfo);
-      } else {
-        for (var info in innermostContainingInfo.children) {
-          if (analysisRoot.isOrContains(info.folder.path)) {
-            addContextAndDescendants(info);
-          }
-        }
-      }
-    }
-    return drivers;
+    return getContextFor(path)?.driver;
   }
 
   /// Determine whether the given [path], when interpreted relative to innermost
   /// context root, contains a folder whose name starts with '.'.
   @override
   bool isContainedInDotFolder(String path) {
-    var info = _getInnermostContextInfoFor(path);
-    return info != null && _isContainedInDotFolder(info.folder.path, path);
-  }
-
-  @override
-  bool isIgnored(String path) {
-    var info = rootInfo;
-    do {
-      info = info.findChildInfoFor(path);
-      if (info == null) {
-        return false;
-      }
-      if (info.ignored(path)) {
-        return true;
-      }
-    } while (true);
-  }
-
-  @override
-  bool isInAnalysisRoot(String path) {
-    // check if excluded
-    if (_isExcluded(path)) {
-      return false;
-    }
-    // check if in one of the roots
-    for (var info in rootInfo.children) {
-      if (info.folder.contains(path)) {
+    for (var analysisContext in _collection.contexts) {
+      var contextImpl = analysisContext as DriverBasedAnalysisContext;
+      if (_isContainedInDotFolder(contextImpl.contextRoot.root.path, path)) {
         return true;
       }
     }
-    // no
     return false;
   }
 
   @override
-  int numberOfContextsInAnalysisRoot(Folder analysisRoot) {
-    var count = 0;
-    void addContextAndDescendants(ContextInfo info) {
-      count++;
-      info.children.forEach(addContextAndDescendants);
-    }
-
-    var innermostContainingInfo =
-        _getInnermostContextInfoFor(analysisRoot.path);
-    if (innermostContainingInfo != null) {
-      if (analysisRoot == innermostContainingInfo.folder) {
-        addContextAndDescendants(innermostContainingInfo);
-      } else {
-        for (var info in innermostContainingInfo.children) {
-          if (analysisRoot.isOrContains(info.folder.path)) {
-            addContextAndDescendants(info);
-          }
-        }
-      }
-    }
-    return count;
-  }
-
-  /// Process [options] for the given context [info].
-  void processOptionsForDriver(
-      ContextInfo info, AnalysisOptionsImpl analysisOptions, YamlMap options) {
-    if (options == null) {
-      return;
-    }
-
-    // Check for embedded options.
-    var embeddedOptions = _getEmbeddedOptions(info);
-    if (embeddedOptions != null) {
-      options = Merger().merge(embeddedOptions, options);
-    }
-
-    applyToAnalysisOptions(analysisOptions, options);
-
-    if (analysisOptions.excludePatterns != null) {
-      // Set ignore patterns.
-      setIgnorePatternsForContext(info, analysisOptions.excludePatterns);
-    }
+  bool isInAnalysisRoot(String path) {
+    return _collection.contexts.any(
+      (context) => context.contextRoot.isAnalyzed(path),
+    );
   }
 
   @override
-  void refresh(List<Resource> roots) {
-    // Destroy old contexts
-    var contextInfos = rootInfo.descendants.toList();
-    if (roots == null) {
-      contextInfos.forEach(_destroyContext);
-    } else {
-      roots.forEach((Resource resource) {
-        contextInfos.forEach((ContextInfo contextInfo) {
-          if (resource is Folder &&
-              resource.isOrContains(contextInfo.folder.path)) {
-            _destroyContext(contextInfo);
-          }
-        });
-      });
-    }
-
-    // Rebuild contexts based on the data last sent to setRoots().
-    setRoots(includedPaths, excludedPaths);
-
-    callbacks.afterContextRefresh();
-  }
-
-  /// Sets the [ignorePatterns] for the context having info [info].
-  void setIgnorePatternsForContext(
-      ContextInfo info, List<String> ignorePatterns) {
-    info.pathFilter.setIgnorePatterns(ignorePatterns);
+  void refresh() {
+    _createAnalysisContexts();
   }
 
   @override
   void setRoots(List<String> includedPaths, List<String> excludedPaths) {
-    var contextInfos = rootInfo.descendants.toList();
-    // included
-    var includedFolders = <Folder>[];
-    {
-      // Sort paths to ensure that outer roots are handled before inner roots,
-      // so we can correctly ignore inner roots, which are already managed
-      // by outer roots.
-      var uniqueIncludedPaths = LinkedHashSet<String>.from(includedPaths);
-      var sortedIncludedPaths = uniqueIncludedPaths.toList();
-      sortedIncludedPaths.sort((a, b) => a.length - b.length);
-      // Convert paths to folders.
-      for (var path in sortedIncludedPaths) {
-        var resource = resourceProvider.getResource(path);
-        if (resource is Folder) {
-          includedFolders.add(resource);
-        } else if (!resource.exists) {
-          // Non-existent resources are ignored.  TODO(paulberry): we should set
-          // up a watcher to ensure that if the resource appears later, we will
-          // begin analyzing it.
-        } else {
-          // TODO(scheglov) implemented separate files analysis
-          throw UnimplementedError('$path is not a folder. '
-              'Only support for folder analysis is implemented currently.');
-        }
-      }
-    }
     this.includedPaths = includedPaths;
-    // excluded
-    var oldExcludedPaths = this.excludedPaths;
     this.excludedPaths = excludedPaths;
-    // destroy old contexts
-    for (var contextInfo in contextInfos) {
-      var isIncluded = includedFolders.any((folder) {
-        return folder.isOrContains(contextInfo.folder.path);
-      });
-      if (!isIncluded) {
-        _destroyContext(contextInfo);
-      }
-    }
-    // create new contexts
-    for (var includedFolder in includedFolders) {
-      var includedPath = includedFolder.path;
-      var isManaged = rootInfo._managesOrHasChildThatManages(includedPath);
-      if (!isManaged) {
-        var parent = _getParentForNewContext(includedPath);
-        changeSubscriptions[includedFolder] = includedFolder.changes
-            .listen(_handleWatchEvent, onError: _handleWatchInterruption);
-        _createContexts(parent, includedFolder, excludedPaths, false);
-      }
-    }
-    // remove newly excluded sources
-    for (var info in rootInfo.descendants) {
-      // prepare excluded sources
-      Map<String, Source> excludedSources = HashMap<String, Source>();
-      info.sources.forEach((String path, Source source) {
-        if (_isExcludedBy(excludedPaths, path) &&
-            !_isExcludedBy(oldExcludedPaths, path)) {
-          excludedSources[path] = source;
-        }
-      });
-      // apply exclusion
-      var changeSet = ChangeSet();
-      excludedSources.forEach((String path, Source source) {
-        info.sources.remove(path);
-        changeSet.removedSource(path);
-      });
-      callbacks.applyChangesToContext(info.folder, changeSet);
-    }
-    // add previously excluded sources
-    for (var info in rootInfo.descendants) {
-      var changeSet = ChangeSet();
-      _addPreviouslyExcludedSources(
-          info, changeSet, info.folder, oldExcludedPaths);
-      callbacks.applyChangesToContext(info.folder, changeSet);
-    }
-  }
 
-  /// Recursively adds all Dart and HTML files to the [changeSet].
-  void _addPreviouslyExcludedSources(ContextInfo info, ChangeSet changeSet,
-      Folder folder, List<String> oldExcludedPaths) {
-    if (info.excludesResource(folder)) {
-      return;
-    }
-    List<Resource> children;
-    try {
-      children = folder.getChildren();
-    } on FileSystemException {
-      // The folder no longer exists, or cannot be read, to there's nothing to
-      // do.
-      return;
-    }
-    for (var child in children) {
-      var path = child.path;
-      // Path is being ignored.
-      if (info.ignored(path)) {
-        continue;
-      }
-      // add files, recurse into folders
-      if (child is File) {
-        // ignore if should not be analyzed at all
-        if (!_shouldFileBeAnalyzed(child)) {
-          continue;
-        }
-        // ignore if was not excluded
-        var wasExcluded = _isExcludedBy(oldExcludedPaths, path) &&
-            !_isExcludedBy(excludedPaths, path);
-        if (!wasExcluded) {
-          continue;
-        }
-        // do add the file
-        var source = createSourceInContext(info.analysisDriver, child);
-        changeSet.addedSource(child.path);
-        info.sources[path] = source;
-      } else if (child is Folder) {
-        _addPreviouslyExcludedSources(info, changeSet, child, oldExcludedPaths);
-      }
-    }
-  }
-
-  /// Recursively adds all Dart and HTML files to the [changeSet].
-  void _addSourceFiles(ChangeSet changeSet, Folder folder, ContextInfo info) {
-    if (info.excludesResource(folder) ||
-        folder.shortName.startsWith('.') ||
-        _isInTopLevelDocDir(info.folder.path, folder.path)) {
-      return;
-    }
-    List<Resource> children;
-    try {
-      children = folder.getChildren();
-    } on FileSystemException {
-      // The directory either doesn't exist or cannot be read. Either way, there
-      // are no children that need to be added.
-      return;
-    }
-    for (var child in children) {
-      var path = child.path;
-      // ignore excluded files or folders
-      if (_isExcluded(path) || info.excludes(path) || info.ignored(path)) {
-        continue;
-      }
-      // add files, recurse into folders
-      if (child is File) {
-        if (_shouldFileBeAnalyzed(child)) {
-          var source = createSourceInContext(info.analysisDriver, child);
-          changeSet.addedSource(child.path);
-          info.sources[path] = source;
-        }
-      } else if (child is Folder) {
-        _addSourceFiles(changeSet, child, info);
-      }
-    }
+    _createAnalysisContexts();
   }
 
   /// Use the given analysis [driver] to analyze the content of the analysis
@@ -839,387 +408,120 @@
         convertedErrors ?? <protocol.AnalysisError>[]);
   }
 
-  void _checkForAnalysisOptionsUpdate(String path, ContextInfo info) {
-    if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
-      var driver = info.analysisDriver;
-      if (driver == null) {
-        // I suspect that this happens as a result of a race condition: server
-        // has determined that the file (at [path]) is in a context, but hasn't
-        // yet created a driver for that context.
-        return;
-      }
-      // TODO(brianwilkerson) Set exclusion patterns.
-      _analyzeAnalysisOptionsFile(driver, path);
-      _updateAnalysisOptions(info);
-    }
-  }
-
-  void _checkForDataFileUpdate(String path, ContextInfo info) {
+  void _checkForDataFileUpdate(String path) {
     if (_isDataFile(path)) {
-      var driver = info.analysisDriver;
-      if (driver == null) {
-        // I suspect that this happens as a result of a race condition: server
-        // has determined that the file (at [path]) is in a context, but hasn't
-        // yet created a driver for that context.
-        return;
-      }
+      var context = getContextFor(path);
+      var driver = context.driver;
       _analyzeDataFile(driver, path);
     }
   }
 
-  void _checkForManifestUpdate(String path, ContextInfo info) {
+  void _checkForManifestUpdate(String path) {
     if (_isManifest(path)) {
-      var driver = info.analysisDriver;
-      if (driver == null) {
-        // I suspect that this happens as a result of a race condition: server
-        // has determined that the file (at [path]) is in a context, but hasn't
-        // yet created a driver for that context.
-        return;
-      }
+      var context = getContextFor(path);
+      var driver = context.driver;
       _analyzeManifestFile(driver, path);
     }
   }
 
-  void _checkForPackagespecUpdate(String path, ContextInfo info) {
-    // Check to see if this is `.dart_tool/package_config.json` or `.packages`
-    // file for this context and if so, update the context's source factory.
-    if (_isPackageConfigJsonFilePath(path) || _isDotPackagesFilePath(path)) {
-      var driver = info.analysisDriver;
-      if (driver == null) {
-        // I suspect that this happens as a result of a race condition: server
-        // has determined that the file (at [path]) is in a context, but hasn't
-        // yet created a driver for that context.
-        return;
-      }
-
-      _updateAnalysisOptions(info);
-      final optionsFile = info?.analysisDriver?.contextRoot?.optionsFilePath;
-      if (optionsFile != null) {
-        _analyzeAnalysisOptionsFile(driver, optionsFile);
-      }
-    }
-  }
-
-  void _checkForPubspecUpdate(String path, ContextInfo info) {
-    if (_isPubspec(path)) {
-      var driver = info.analysisDriver;
-      if (driver == null) {
-        // I suspect that this happens as a result of a race condition: server
-        // has determined that the file (at [path]) is in a context, but hasn't
-        // yet created a driver for that context.
-        return;
-      }
-      _analyzePubspecFile(driver, path);
-      _updateAnalysisOptions(info);
-    }
-  }
-
-  /// Compute the set of files that are being flushed, this is defined as
-  /// the set of sources in the removed context (context.sources), that are
-  /// orphaned by this context being removed (no other context includes this
-  /// file.)
-  List<String> _computeFlushedFiles(ContextInfo info) {
-    var flushedFiles = info.analysisDriver.addedFiles.toSet();
-    for (var contextInfo in rootInfo.descendants) {
-      var other = contextInfo.analysisDriver;
-      if (other != info.analysisDriver) {
-        flushedFiles.removeAll(other.addedFiles);
-      }
-    }
-    return flushedFiles.toList(growable: false);
-  }
-
-  /// Compute the appropriate [FolderDisposition] for [folder].  Use
-  /// [addDependency] to indicate which files needed to be consulted in order to
-  /// figure out the [FolderDisposition]; these dependencies will be watched in
-  /// order to determine when it is necessary to call this function again.
-  ///
-  /// TODO(paulberry): use [addDependency] for tracking all folder disposition
-  /// dependencies (currently we only use it to track "pub list" dependencies).
-  FolderDisposition _computeFolderDisposition(Folder folder,
-      void Function(String path) addDependency, File packagespecFile) {
-    // Try .packages first.
-    if (pathContext.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
-      var packages = parsePackagesFile(
-        resourceProvider,
-        packagespecFile,
-      );
-      return PackagesFileDisposition(packages);
-    }
-
-    return NoPackageFolderDisposition();
-  }
-
   /// Compute line information for the given [content].
   LineInfo _computeLineInfo(String content) {
     var lineStarts = StringUtilities.computeLineStarts(content);
     return LineInfo(lineStarts);
   }
 
-  /// Create an object that can be used to find and read the analysis options
-  /// file for code being analyzed using the given [packages].
-  AnalysisOptionsProvider _createAnalysisOptionsProvider(Packages packages) {
-    var packageMap = <String, List<Folder>>{};
-    if (packages != null) {
-      for (var package in packages.packages) {
-        packageMap[package.name] = [package.libFolder];
+  void _createAnalysisContexts() {
+    if (_collection != null) {
+      for (var analysisContext in _collection.contexts) {
+        var contextImpl = analysisContext as DriverBasedAnalysisContext;
+        _destroyContext(contextImpl);
       }
     }
 
-    var resolvers = <UriResolver>[
-      ResourceUriResolver(resourceProvider),
-      PackageMapUriResolver(resourceProvider, packageMap),
-    ];
-    var sourceFactory = SourceFactory(resolvers);
-    return AnalysisOptionsProvider(sourceFactory);
-  }
-
-  /// Create a new empty context associated with [folder], having parent
-  /// [parent] and using [packagesFile] to resolve package URI's.
-  ContextInfo _createContext(ContextInfo parent, Folder folder,
-      List<String> excludedPaths, File packagesFile) {
-    var dependencies = <String>[];
-    var disposition =
-        _computeFolderDisposition(folder, dependencies.add, packagesFile);
-    var info = ContextInfo(this, parent, folder, packagesFile, disposition);
-
-    File optionsFile;
-    YamlMap optionMap;
-    try {
-      var provider = _createAnalysisOptionsProvider(disposition.packages);
-      optionsFile = provider.getOptionsFile(info.folder);
-      if (optionsFile != null) {
-        optionMap = provider.getOptionsFromFile(optionsFile);
-      }
-    } catch (_) {
-      // Parse errors are reported elsewhere.
-    }
-    var options = AnalysisOptionsImpl();
-    applyToAnalysisOptions(options, optionMap);
-
-    info.setDependencies(dependencies);
-    var includedPath = folder.path;
-    var containedExcludedPaths = excludedPaths
-        .where((String excludedPath) =>
-            pathContext.isWithin(includedPath, excludedPath))
-        .toList();
-    processOptionsForDriver(info, options, optionMap);
-    var contextRoot = ContextRoot(folder.path, containedExcludedPaths,
-        pathContext: pathContext);
-    if (optionsFile != null) {
-      contextRoot.optionsFilePath = optionsFile.path;
-    }
-    info.analysisDriver = callbacks.addAnalysisDriver(folder, contextRoot);
-    _watchBazelFilesIfNeeded(folder, info.analysisDriver);
-    if (optionsFile != null) {
-      _analyzeAnalysisOptionsFile(info.analysisDriver, optionsFile.path);
-    }
-    var dataFile =
-        folder.getChildAssumingFolder('lib').getChildAssumingFile(dataFileName);
-    if (dataFile.exists) {
-      _analyzeDataFile(info.analysisDriver, dataFile.path);
-    }
-    var pubspecFile = folder.getChildAssumingFile(PUBSPEC_NAME);
-    if (pubspecFile.exists) {
-      _analyzePubspecFile(info.analysisDriver, pubspecFile.path);
-    }
-
-    void checkManifestFilesIn(Folder folder) {
-      // Don't traverse into dot directories.
-      if (folder.shortName.startsWith('.')) {
-        return;
-      }
-
-      for (var child in folder.getChildren()) {
-        if (child is File) {
-          if (child.shortName == MANIFEST_NAME &&
-              !excludedPaths.contains(child.path)) {
-            _analyzeManifestFile(info.analysisDriver, child.path);
-          }
-        } else if (child is Folder) {
-          if (!excludedPaths.contains(child.path)) {
-            checkManifestFilesIn(child);
-          }
-        }
-      }
-    }
-
-    checkManifestFilesIn(folder);
-    return info;
-  }
-
-  /// Potentially create a new context associated with the given [folder].
-  ///
-  /// If there are subfolders with 'pubspec.yaml' files, separate contexts are
-  /// created for them and excluded from the context associated with the
-  /// [folder].
-  ///
-  /// If [withPackageSpecOnly] is `true`, a context will be created only if
-  /// there is a 'pubspec.yaml' or '.packages' file in the [folder].
-  ///
-  /// [parent] should be the parent of any contexts that are created.
-  void _createContexts(ContextInfo parent, Folder folder,
-      List<String> excludedPaths, bool withPackageSpecOnly) {
-    if (_isExcluded(folder.path) || folder.shortName.startsWith('.')) {
-      return;
-    }
-    // Decide whether a context needs to be created for [folder] here, and if
-    // so, create it.
-    var packageSpec = _findPackageSpecFile(folder);
-    var createContext = packageSpec.exists || !withPackageSpecOnly;
-    if (withPackageSpecOnly &&
-        packageSpec.exists &&
-        parent != null &&
-        parent.ignored(packageSpec.path)) {
-      // Don't create a context if the package spec is required and ignored.
-      createContext = false;
-    }
-    if (createContext) {
-      parent = _createContext(parent, folder, excludedPaths, packageSpec);
-    }
-
-    // Try to find subfolders with pubspecs or .packages files.
-    try {
-      for (var child in folder.getChildren()) {
-        if (child is Folder) {
-          if (!parent.ignored(child.path)) {
-            _createContexts(parent, child, excludedPaths, true);
-          }
-        }
-      }
-    } on FileSystemException {
-      // The directory either doesn't exist or cannot be read. Either way, there
-      // are no subfolders that need to be added.
-    }
-
-    if (createContext) {
-      // Now that the child contexts have been created, add the sources that
-      // don't belong to the children.
-      var changeSet = ChangeSet();
-      _addSourceFiles(changeSet, folder, parent);
-      callbacks.applyChangesToContext(folder, changeSet);
-    }
-  }
-
-  /// Set up a [SourceFactory] that resolves packages as appropriate for the
-  /// given [folder].
-  SourceFactory _createSourceFactory(Folder folder) {
-    var builder = callbacks.createContextBuilder(folder);
-    var workspace = ContextBuilder.createWorkspace(
+    _collection = AnalysisContextCollectionImpl(
+      includedPaths: includedPaths,
+      excludedPaths: excludedPaths,
+      byteStore: _byteStore,
+      drainStreams: false,
+      enableIndex: true,
+      performanceLog: _performanceLog,
       resourceProvider: resourceProvider,
-      options: builder.builderOptions,
-      rootPath: folder.path,
-      lookForBazelBuildFileSubstitutes: false,
+      scheduler: _scheduler,
+      sdkPath: sdkManager.defaultSdkDirectory,
     );
-    return builder.createSourceFactory(folder.path, workspace);
+
+    for (var context in _collection.contexts) {
+      var contextImpl = context as DriverBasedAnalysisContext;
+      var driver = contextImpl.driver;
+
+      callbacks.listenAnalysisDriver(driver);
+
+      var rootFolder = contextImpl.contextRoot.root;
+      driverMap[rootFolder] = driver;
+
+      changeSubscriptions[rootFolder] = rootFolder.changes
+          .listen(_handleWatchEvent, onError: _handleWatchInterruption);
+
+      _watchBazelFilesIfNeeded(rootFolder, driver);
+
+      for (var file in contextImpl.contextRoot.analyzedFiles()) {
+        if (_isContainedInDotFolder(contextImpl.contextRoot.root.path, file)) {
+          continue;
+        }
+        driver.addFile(file);
+      }
+
+      var optionsFile = context.contextRoot.optionsFile;
+      if (optionsFile != null) {
+        _analyzeAnalysisOptionsFile(driver, optionsFile.path);
+      }
+
+      var dataFile = rootFolder
+          .getChildAssumingFolder('lib')
+          .getChildAssumingFile(dataFileName);
+      if (dataFile.exists) {
+        _analyzeDataFile(driver, dataFile.path);
+      }
+
+      var pubspecFile = rootFolder.getChildAssumingFile(PUBSPEC_NAME);
+      if (pubspecFile.exists) {
+        _analyzePubspecFile(driver, pubspecFile.path);
+      }
+
+      void checkManifestFilesIn(Folder folder) {
+        // Don't traverse into dot directories.
+        if (folder.shortName.startsWith('.')) {
+          return;
+        }
+
+        for (var child in folder.getChildren()) {
+          if (child is File) {
+            if (child.shortName == MANIFEST_NAME &&
+                !excludedPaths.contains(child.path)) {
+              _analyzeManifestFile(driver, child.path);
+            }
+          } else if (child is Folder) {
+            if (!excludedPaths.contains(child.path)) {
+              checkManifestFilesIn(child);
+            }
+          }
+        }
+      }
+
+      checkManifestFilesIn(rootFolder);
+    }
+
+    callbacks.afterContextsCreated();
   }
 
   /// Clean up and destroy the context associated with the given folder.
-  void _destroyContext(ContextInfo info) {
-    changeSubscriptions.remove(info.folder)?.cancel();
-    bazelSubscriptions.remove(info.folder)?.cancel();
-    callbacks.removeContext(info.folder, _computeFlushedFiles(info));
-    var wasRemoved = info.parent.children.remove(info);
-    assert(wasRemoved);
-  }
+  void _destroyContext(DriverBasedAnalysisContext context) {
+    var rootFolder = context.contextRoot.root;
+    changeSubscriptions.remove(rootFolder)?.cancel();
+    bazelSubscriptions.remove(rootFolder)?.cancel();
 
-  /// Extract a new [packagespecFile]-based context from [oldInfo].
-  void _extractContext(ContextInfo oldInfo, File packagespecFile) {
-    var newFolder = packagespecFile.parent2;
-    var newInfo =
-        _createContext(oldInfo, newFolder, excludedPaths, packagespecFile);
-    // prepare sources to extract
-    Map<String, Source> extractedSources = HashMap<String, Source>();
-    oldInfo.sources.forEach((path, source) {
-      if (newFolder.contains(path)) {
-        extractedSources[path] = source;
-      }
-    });
-    // update new context
-    {
-      var changeSet = ChangeSet();
-      extractedSources.forEach((path, source) {
-        newInfo.sources[path] = source;
-        changeSet.addedSource(path);
-      });
-      callbacks.applyChangesToContext(newFolder, changeSet);
-    }
-    // update old context
-    {
-      var changeSet = ChangeSet();
-      extractedSources.forEach((path, source) {
-        oldInfo.sources.remove(path);
-        changeSet.removedSource(path);
-      });
-      callbacks.applyChangesToContext(oldInfo.folder, changeSet);
-    }
-    // TODO(paulberry): every context that was previously a child of oldInfo is
-    // is still a child of oldInfo.  This is wrong--some of them ought to be
-    // adopted by newInfo now.
-  }
-
-  /// Find the file that should be used to determine whether a context needs to
-  /// be created here--this is either the ".packages" file or the "pubspec.yaml"
-  /// file.
-  File _findPackageSpecFile(Folder folder) {
-    // Decide whether a context needs to be created for [folder] here, and if
-    // so, create it.
-    File packageSpec;
-
-    // Start by looking for .packages.
-    packageSpec = folder.getChild(PACKAGE_SPEC_NAME);
-
-    // Fall back to looking for a pubspec.
-    if (packageSpec == null || !packageSpec.exists) {
-      packageSpec = folder.getChild(PUBSPEC_NAME);
-    }
-    return packageSpec;
-  }
-
-  /// Get analysis options inherited from an `_embedder.yaml` (deprecated)
-  /// and/or a package specified configuration.  If more than one
-  /// `_embedder.yaml` is associated with the given context, the embedder is
-  /// skipped.
-  ///
-  /// Returns null if there are no embedded/configured options.
-  YamlMap _getEmbeddedOptions(ContextInfo info) {
-    Map embeddedOptions;
-    var locator = info.disposition.getEmbedderLocator(resourceProvider);
-    var maps = locator.embedderYamls.values;
-    if (maps.length == 1) {
-      embeddedOptions = maps.first;
-    }
-    return embeddedOptions;
-  }
-
-  /// Return the [ContextInfo] for the "innermost" context whose associated
-  /// folder is or contains the given path.  ("innermost" refers to the nesting
-  /// of contexts, so if there is a context for path /foo and a context for
-  /// path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
-  /// the context for /foo/bar.)
-  ///
-  /// If no context contains the given path, `null` is returned.
-  ContextInfo _getInnermostContextInfoFor(String path) {
-    var info = rootInfo.findChildInfoFor(path);
-    if (info == null) {
-      return null;
-    }
-    while (true) {
-      var childInfo = info.findChildInfoFor(path);
-      if (childInfo == null) {
-        return info;
-      }
-      info = childInfo;
-    }
-  }
-
-  /// Return the parent for a new [ContextInfo] with the given [path] folder.
-  ContextInfo _getParentForNewContext(String path) {
-    var parent = _getInnermostContextInfoFor(path);
-    if (parent != null) {
-      return parent;
-    }
-    return rootInfo;
+    var flushedFiles = context.driver.addedFiles.toList();
+    callbacks.removeContext(rootFolder, flushedFiles);
   }
 
   /// Establishes watch(es) for the Bazel generated files provided in
@@ -1277,129 +579,48 @@
     // that's the only context that's watching the file).
     var path = event.path;
     var type = event.type;
-    var info = _getInnermostContextInfoFor(path);
-    if (info == null) {
-      // This event doesn't apply to any context.  This could happen due to a
-      // race condition (e.g. a context was removed while one of its events was
-      // in the event loop).  The event is inapplicable now, so just ignore it.
+
+    _instrumentationService.logWatchEvent('<unknown>', path, type.toString());
+
+    if (_isPackageConfigJsonFilePath(path) ||
+        _isDotPackagesFilePath(path) ||
+        _isPubspec(path) ||
+        AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
+      _createAnalysisContexts();
       return;
     }
-    _instrumentationService.logWatchEvent(
-        info.folder.path, path, type.toString());
-    // First handle changes that affect folderDisposition (since these need to
-    // be processed regardless of whether they are part of an excluded/ignored
-    // path).
-    if (info.hasDependency(path)) {
-      _recomputeFolderDisposition(info);
-    }
 
-    _checkForPackagespecUpdate(path, info);
-
-    // maybe excluded globally
-    if (_isExcluded(path) ||
-        _isContainedInDotFolder(info.folder.path, path,
-            exclude: {'.dart_tool'}) ||
-        _isInTopLevelDocDir(info.folder.path, path)) {
-      return;
-    }
-    // maybe excluded from the context, so other context will handle it
-    if (info.excludes(path)) {
-      return;
-    }
-    // handle the change
-    switch (type) {
-      case ChangeType.ADD:
-        var resource = resourceProvider.getResource(path);
-
-        var directoryPath = pathContext.dirname(path);
-
-        // Check to see if we need to create a new context.
-        if (info.isTopLevel) {
-          // Only create a new context if this is not the same directory
-          // described by our info object.
-          if (info.folder.path != directoryPath) {
-            if (_isPubspec(path)) {
-              // Check for a sibling .packages file.
-              if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
-                  .exists) {
-                _extractContext(info, resource);
-                return;
-              }
+    if (path.endsWith('.dart')) {
+      for (var analysisContext_ in _collection.contexts) {
+        var analysisContext = analysisContext_ as DriverBasedAnalysisContext;
+        switch (type) {
+          case ChangeType.ADD:
+            // TODO(scheglov) Why not `isInAnalysisRoot()`?
+            if (_isContainedInDotFolder(
+                analysisContext.contextRoot.root.path, path)) {
+              return;
             }
-            if (_isDotPackagesFilePath(path)) {
-              // Check for a sibling pubspec.yaml file.
-              if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
-                  .exists) {
-                _extractContext(info, resource);
-                return;
-              }
-            }
-          }
-        }
-
-        // If the file went away and was replaced by a folder before we
-        // had a chance to process the event, resource might be a Folder. In
-        // that case don't add it.
-        if (resource is File) {
-          if (_shouldFileBeAnalyzed(resource)) {
-            info.analysisDriver.addFile(path);
-          }
-        }
-        break;
-      case ChangeType.REMOVE:
-        // If package spec info is removed, check to see if we can merge
-        // contexts. Note that it's important to verify that there is NEITHER a
-        // .packages nor a lingering pubspec.yaml before merging.
-        if (!info.isTopLevel) {
-          var directoryPath = pathContext.dirname(path);
-
-          // Only merge if this is the same directory described by our info
-          // object.
-          if (info.folder.path == directoryPath) {
-            if (_isPubspec(path)) {
-              // Check for a sibling .packages file.
-              if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PACKAGE_SPEC_NAME))
-                  .exists) {
-                _mergeContext(info);
-                return;
-              }
-            }
-            if (_isDotPackagesFilePath(path)) {
-              // Check for a sibling pubspec.yaml file.
-              if (!resourceProvider
-                  .getFile(pathContext.join(directoryPath, PUBSPEC_NAME))
-                  .exists) {
-                _mergeContext(info);
-                return;
-              }
-            }
-          }
-        }
-
-        var resource = resourceProvider.getResource(path);
-        if (resource is File &&
-            _shouldFileBeAnalyzed(resource, mustExist: false)) {
-          callbacks.applyFileRemoved(info.analysisDriver, path);
-        }
-        break;
-      case ChangeType.MODIFY:
-        var resource = resourceProvider.getResource(path);
-        if (resource is File) {
-          if (_shouldFileBeAnalyzed(resource)) {
-            for (var driver in driverMap.values) {
-              driver.changeFile(path);
+            analysisContext.driver.addFile(path);
+            break;
+          case ChangeType.MODIFY:
+            analysisContext.driver.changeFile(path);
+            break;
+          case ChangeType.REMOVE:
+            analysisContext.driver.removeFile(path);
+            // TODO(scheglov) Why not `isInAnalysisRoot()`?
+            // TODO(scheglov) Why not always?
+            var resource = resourceProvider.getResource(path);
+            if (resource is File &&
+                _shouldFileBeAnalyzed(resource, mustExist: false)) {
+              callbacks.applyFileRemoved(path);
             }
             break;
-          }
         }
+      }
     }
-    _checkForAnalysisOptionsUpdate(path, info);
-    _checkForDataFileUpdate(path, info);
-    _checkForPubspecUpdate(path, info);
-    _checkForManifestUpdate(path, info);
+
+    _checkForManifestUpdate(path);
+    _checkForDataFileUpdate(path);
   }
 
   /// On windows, the directory watcher may overflow, and we must recover.
@@ -1408,7 +629,7 @@
     AnalysisEngine.instance.instrumentationService
         .logError('Watcher error; refreshing contexts.\n$error\n$stackTrace');
     // TODO(mfairhurst): Optimize this, or perhaps be less complete.
-    refresh(null);
+    refresh();
   }
 
   /// Determine whether the given [path], when interpreted relative to the
@@ -1438,31 +659,6 @@
     return pathContext.basename(path) == PACKAGE_SPEC_NAME;
   }
 
-  /// Returns `true` if the given [path] is excluded by [excludedPaths].
-  bool _isExcluded(String path) => _isExcludedBy(excludedPaths, path);
-
-  /// Returns `true` if the given [path] is excluded by [excludedPaths].
-  bool _isExcludedBy(List<String> excludedPaths, String path) {
-    return excludedPaths.any((excludedPath) {
-      if (pathContext.isWithin(excludedPath, path)) {
-        return true;
-      }
-      return path == excludedPath;
-    });
-  }
-
-  /// Determine whether the given [path] is in the direct 'doc' folder of the
-  /// context root [root].
-  bool _isInTopLevelDocDir(String root, String path) {
-    var rootPrefix = root + pathContext.separator;
-    if (path.startsWith(rootPrefix)) {
-      var suffix = path.substring(rootPrefix.length);
-      return suffix == DOC_DIR_NAME ||
-          suffix.startsWith(DOC_DIR_NAME + pathContext.separator);
-    }
-    return false;
-  }
-
   bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME;
 
   bool _isPackageConfigJsonFilePath(String path) {
@@ -1474,41 +670,12 @@
 
   bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
 
-  /// Merges [info] context into its parent.
-  void _mergeContext(ContextInfo info) {
-    // destroy the context
-    _destroyContext(info);
-    // add files to the parent context
-    var parentInfo = info.parent;
-    if (parentInfo != null) {
-      parentInfo.children.remove(info);
-      var changeSet = ChangeSet();
-      info.sources.forEach((path, source) {
-        parentInfo.sources[path] = source;
-        changeSet.addedSource(path);
-      });
-      callbacks.applyChangesToContext(parentInfo.folder, changeSet);
-    }
-  }
-
   /// Read the contents of the file at the given [path], or throw an exception
   /// if the contents cannot be read.
   String _readFile(String path) {
     return resourceProvider.getFile(path).readAsStringSync();
   }
 
-  /// Recompute the [FolderDisposition] for the context described by [info],
-  /// and update the client appropriately.
-  void _recomputeFolderDisposition(ContextInfo info) {
-    // TODO(paulberry): when computePackageMap is changed into an
-    // asynchronous API call, we'll want to suspend analysis for this context
-    // while we're rerunning "pub list", since any analysis we complete while
-    // "pub list" is in progress is just going to get thrown away anyhow.
-    var dependencies = <String>[];
-    info.setDependencies(dependencies);
-    _updateContextPackageUriResolver(info.folder);
-  }
-
   /// Return `true` if the given [file] should be analyzed.
   bool _shouldFileBeAnalyzed(File file, {bool mustExist = true}) {
     for (var glob in analyzedFilesGlobs) {
@@ -1525,39 +692,6 @@
     return false;
   }
 
-  void _updateAnalysisOptions(ContextInfo info) {
-    var driver = info.analysisDriver;
-    var contextRoot = info.folder.path;
-    var builder = callbacks.createContextBuilder(info.folder);
-    var workspace = ContextBuilder.createWorkspace(
-      resourceProvider: resourceProvider,
-      options: builder.builderOptions,
-      rootPath: contextRoot,
-      lookForBazelBuildFileSubstitutes: false,
-    );
-    var options = builder.getAnalysisOptions(contextRoot, workspace,
-        contextRoot: driver.contextRoot);
-    var packages = ContextBuilder.createPackageMap(
-      resourceProvider: builder.resourceProvider,
-      options: builder.builderOptions,
-      rootPath: contextRoot,
-    );
-    var factory = builder.createSourceFactory(contextRoot, workspace);
-    driver.configure(
-      analysisOptions: options,
-      packages: packages,
-      sourceFactory: factory,
-    );
-    callbacks.analysisOptionsUpdated(driver);
-  }
-
-  void _updateContextPackageUriResolver(Folder contextFolder) {
-    var info = getContextInfoFor(contextFolder);
-    var driver = info.analysisDriver;
-    var sourceFactory = _createSourceFactory(contextFolder);
-    driver.configure(sourceFactory: sourceFactory);
-  }
-
   /// Listens to files generated by Bazel that were found or searched for.
   ///
   /// This is handled specially because the files are outside the package
@@ -1589,85 +723,6 @@
   }
 }
 
-/// An instance of the class [FolderDisposition] represents the information
-/// gathered by the [ContextManagerImpl] to determine how to create an analysis
-/// driver for a given folder.
-///
-/// Note: [ContextManagerImpl] may use equality testing and hash codes to
-/// determine when two folders should share the same context, so derived classes
-/// may need to override operator== and hashCode() if object identity is
-/// insufficient.
-///
-/// TODO(paulberry): consider adding a flag to indicate that it is not necessary
-/// to recurse into the given folder looking for additional contexts to create
-/// or files to analyze (this could help avoid unnecessarily weighing down the
-/// system with file watchers).
-abstract class FolderDisposition {
-  /// If this [FolderDisposition] was created based on a package root
-  /// folder, the absolute path to that folder.  Otherwise `null`.
-  String get packageRoot;
-
-  /// If contexts governed by this [FolderDisposition] should resolve packages
-  /// using the ".packages" file mechanism (DEP 5), retrieve the [Packages]
-  /// object that resulted from parsing the ".packages" file.
-  Packages get packages;
-
-  /// Return the locator used to locate the _embedder.yaml file used to
-  /// configure the SDK. The [resourceProvider] is used to access the file
-  /// system in cases where that is necessary.
-  EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider);
-}
-
-/// Concrete [FolderDisposition] object indicating that the context for a given
-/// folder should not resolve "package:" URIs at all.
-class NoPackageFolderDisposition extends FolderDisposition {
-  @override
-  final String packageRoot;
-
-  NoPackageFolderDisposition({this.packageRoot});
-
-  @override
-  Packages get packages => null;
-
-  @override
-  EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) =>
-      EmbedderYamlLocator(null);
-}
-
-/// Concrete [FolderDisposition] object indicating that the context for a given
-/// folder should resolve packages using a ".packages" file.
-class PackagesFileDisposition extends FolderDisposition {
-  @override
-  final Packages packages;
-
-  Map<String, List<Folder>> packageMap;
-
-  EmbedderYamlLocator _embedderLocator;
-
-  PackagesFileDisposition(this.packages);
-
-  @override
-  String get packageRoot => null;
-
-  Map<String, List<Folder>> buildPackageMap(ResourceProvider resourceProvider) {
-    if (packageMap == null) {
-      packageMap = <String, List<Folder>>{};
-      if (packages != null) {
-        for (var package in packages.packages) {
-          packageMap[package.name] = [package.libFolder];
-        }
-      }
-    }
-    return packageMap;
-  }
-
-  @override
-  EmbedderYamlLocator getEmbedderLocator(ResourceProvider resourceProvider) {
-    _embedderLocator ??= EmbedderYamlLocator(buildPackageMap(resourceProvider));
-    return _embedderLocator;
-  }
-}
-
 /// A watcher with subscription used to detect changes to some file.
 class _BazelFilesSubscription {
   final BazelFileWatcher watcher;
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index fa3c671..574c964 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -78,16 +78,20 @@
     // used to generate errors that can then be fixed.
     // TODO(danrubel): Rework to use a different approach if this command
     // will be used from within the IDE.
-    contextManager.refresh(null);
+    contextManager.refresh();
 
     for (var filePath in params.included) {
       if (!server.isValidFilePath(filePath)) {
         return Response.invalidFilePathFormat(request, filePath);
       }
+
+      var analysisContext = contextManager.getContextFor(filePath);
+      if (analysisContext == null) {
+        return Response.fileNotAnalyzed(request, filePath);
+      }
+
       var res = resourceProvider.getResource(filePath);
-      if (!res.exists ||
-          !(contextManager.includedPaths.contains(filePath) ||
-              contextManager.isInAnalysisRoot(filePath))) {
+      if (!res.exists) {
         return Response.fileNotAnalyzed(request, filePath);
       }
 
@@ -95,16 +99,16 @@
       // within an IDE, then this will cause the lint results to change.
       // TODO(danrubel): Rework to use a different approach if this command
       // will be used from within the IDE.
-      var driver = contextManager.getDriverFor(filePath);
+      var driver = analysisContext.driver;
       var analysisOptions = driver.analysisOptions as AnalysisOptionsImpl;
       analysisOptions.lint = true;
       analysisOptions.lintRules = linters;
 
-      var contextFolder = contextManager.getContextFolderFor(filePath);
-      var pkgFolder = findPkgFolder(contextFolder);
-      if (pkgFolder != null && !pkgFolders.contains(pkgFolder)) {
+      var pkgFolder = analysisContext.contextRoot.root;
+      if (!pkgFolders.contains(pkgFolder)) {
         pkgFolders.add(pkgFolder);
       }
+
       if (res is Folder) {
         fixFolders.add(res);
       } else {
@@ -171,8 +175,7 @@
       if (res is Folder) {
         for (var child in res.getChildren()) {
           if (!child.shortName.startsWith('.') &&
-              contextManager.isInAnalysisRoot(child.path) &&
-              !contextManager.isIgnored(child.path)) {
+              contextManager.isInAnalysisRoot(child.path)) {
             resources.add(child);
           }
         }
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index fe63631..6cbe8fa 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -45,7 +45,6 @@
 import 'package:analyzer/src/dart/analysis/results.dart' as engine;
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine;
-import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/exception/exception.dart';
 import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:analyzer/src/generated/engine.dart';
@@ -108,15 +107,10 @@
       var processor = BulkFixProcessor(server.instrumentationService, workspace,
           useConfigFiles: params.inTestMode);
 
-      String sdkPath;
-      var sdk = server.findSdk();
-      if (sdk is FolderBasedDartSdk) {
-        sdkPath = sdk.directory.path;
-      }
       var collection = AnalysisContextCollectionImpl(
         includedPaths: params.included,
         resourceProvider: server.resourceProvider,
-        sdkPath: sdkPath,
+        sdkPath: server.sdkPath,
       );
       var changeBuilder = await processor.fixErrors(collection.contexts);
 
diff --git a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
index cc0212f..993388c 100644
--- a/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
+++ b/pkg/analysis_server/lib/src/lsp/lsp_analysis_server.dart
@@ -39,8 +39,6 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/line_info.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/context/context_root.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart' as nd;
 import 'package:analyzer/src/dart/analysis/status.dart' as nd;
 import 'package:analyzer/src/generated/engine.dart';
@@ -345,8 +343,7 @@
   bool isAnalyzedFile(String file) {
     return contextManager.isInAnalysisRoot(file) &&
         // Dot folders are not analyzed (skipped over in _handleWatchEventImpl)
-        !contextManager.isContainedInDotFolder(file) &&
-        !contextManager.isIgnored(file);
+        !contextManager.isContainedInDotFolder(file);
   }
 
   /// Logs the error on the client using window/logMessage.
@@ -705,11 +702,9 @@
     _lastIncludedRootPaths = includedPaths;
     _lastExcludedRootPaths = excludedPaths;
 
-    declarationsTracker?.discardContexts();
     notificationManager.setAnalysisRoots(
         includedPaths.toList(), excludedPaths.toList());
     contextManager.setRoots(includedPaths.toList(), excludedPaths.toList());
-    addContextsToDeclarationsTracker();
   }
 
   void _updateDriversAndPluginsPriorityFiles() {
@@ -780,14 +775,32 @@
       analysisServer.notificationManager;
 
   @override
-  nd.AnalysisDriver addAnalysisDriver(Folder folder, ContextRoot contextRoot) {
-    var builder = createContextBuilder(folder);
-    var workspace = ContextBuilder.createWorkspace(
-      resourceProvider: resourceProvider,
-      options: builder.builderOptions,
-      rootPath: folder.path,
-    );
-    var analysisDriver = builder.buildDriver(contextRoot, workspace);
+  void afterContextsCreated() {
+    analysisServer.addContextsToDeclarationsTracker();
+  }
+
+  @override
+  void afterWatchEvent(WatchEvent event) {
+    // TODO: implement afterWatchEvent
+  }
+
+  @override
+  void applyFileRemoved(String file) {
+    analysisServer.publishDiagnostics(file, []);
+  }
+
+  @override
+  void broadcastWatchEvent(WatchEvent event) {
+    analysisServer.notifyDeclarationsTracker(event.path);
+    analysisServer.notifyFlutterWidgetDescriptions(event.path);
+    analysisServer.pluginManager.broadcastWatchEvent(event);
+  }
+
+  @override
+  void listenAnalysisDriver(nd.AnalysisDriver analysisDriver) {
+    analysisServer.declarationsTracker
+        ?.addContext(analysisDriver.analysisContext);
+
     final textDocumentCapabilities =
         analysisServer.clientCapabilities?.textDocument;
     final supportedDiagnosticTags = HashSet<DiagnosticTag>.of(
@@ -835,66 +848,6 @@
     });
     analysisDriver.exceptions.listen(analysisServer.logExceptionResult);
     analysisDriver.priorityFiles = analysisServer.priorityFiles.toList();
-    analysisServer.driverMap[folder] = analysisDriver;
-    return analysisDriver;
-  }
-
-  @override
-  void afterContextRefresh() {
-    analysisServer.addContextsToDeclarationsTracker();
-  }
-
-  @override
-  void afterWatchEvent(WatchEvent event) {
-    // TODO: implement afterWatchEvent
-  }
-
-  @override
-  void analysisOptionsUpdated(nd.AnalysisDriver driver) {
-    // TODO: implement analysisOptionsUpdated
-  }
-
-  @override
-  void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
-    var analysisDriver = analysisServer.driverMap[contextFolder];
-    if (analysisDriver != null) {
-      changeSet.addedFiles.forEach((path) {
-        analysisDriver.addFile(path);
-      });
-      changeSet.changedFiles.forEach((path) {
-        analysisDriver.changeFile(path);
-      });
-      changeSet.removedFiles.forEach((path) {
-        analysisDriver.removeFile(path);
-      });
-    }
-  }
-
-  @override
-  void applyFileRemoved(nd.AnalysisDriver driver, String file) {
-    driver.removeFile(file);
-    analysisServer.publishDiagnostics(file, []);
-  }
-
-  @override
-  void broadcastWatchEvent(WatchEvent event) {
-    analysisServer.notifyDeclarationsTracker(event.path);
-    analysisServer.notifyFlutterWidgetDescriptions(event.path);
-    analysisServer.pluginManager.broadcastWatchEvent(event);
-  }
-
-  @override
-  ContextBuilder createContextBuilder(Folder folder) {
-    var builderOptions = ContextBuilderOptions();
-    var builder = ContextBuilder(
-        resourceProvider, analysisServer.sdkManager, null,
-        options: builderOptions);
-    builder.analysisDriverScheduler = analysisServer.analysisDriverScheduler;
-    builder.performanceLog = analysisServer.analysisPerformanceLogger;
-    builder.byteStore = analysisServer.byteStore;
-    builder.enableIndex = true;
-    builder.lookForBazelBuildFileSubstitutes = false;
-    return builder;
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index df8ec96..7ed705f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -94,13 +94,6 @@
   }
 
   @override
-  void visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    if (opType.includeTypeNameSuggestions) {
-      builder.suggestTypeAlias(element, prefix: prefix);
-    }
-  }
-
-  @override
   void visitLibraryElement(LibraryElement element) {
     if (visitedLibraries.add(element)) {
       element.visitChildren(this);
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 5614cd3..9438324 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -128,10 +128,7 @@
   /// Creates a project [projectPath].
   void createProject({Map<String, String> packageRoots}) {
     newFolder(projectPath);
-    var request = AnalysisSetAnalysisRootsParams([projectPath], [],
-            packageRoots: packageRoots)
-        .toRequest('0');
-    handleSuccessfulRequest(request, handler: analysisHandler);
+    setRoots(included: [projectPath], excluded: []);
   }
 
   void doAllDeclarationsTrackerWork() {
@@ -190,6 +187,18 @@
     handleSuccessfulRequest(request);
   }
 
+  void setRoots({
+    @required List<String> included,
+    @required List<String> excluded,
+  }) {
+    var includedConverted = included.map(convertPath).toList();
+    var excludedConverted = excluded.map(convertPath).toList();
+    var request = AnalysisSetAnalysisRootsParams(
+        includedConverted, excludedConverted,
+        packageRoots: {}).toRequest('0');
+    handleSuccessfulRequest(request, handler: analysisHandler);
+  }
+
   @mustCallSuper
   void setUp() {
     serverChannel = MockServerChannel();
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
deleted file mode 100644
index 7acd0c6..0000000
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ /dev/null
@@ -1,2399 +0,0 @@
-// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analysis_server/src/context_manager.dart';
-import 'package:analysis_server/src/plugin/notification_manager.dart';
-import 'package:analysis_server/src/utilities/null_string_sink.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
-import 'package:analyzer/src/dart/analysis/driver.dart';
-import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
-import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/test_utilities/mock_sdk.dart';
-import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
-import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
-import 'package:analyzer/src/util/glob.dart';
-import 'package:linter/src/rules.dart';
-import 'package:linter/src/rules/avoid_as.dart';
-import 'package:path/path.dart' as path;
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:watcher/watcher.dart';
-
-import 'src/plugin/plugin_manager_test.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AbstractContextManagerTest);
-    defineReflectiveTests(ContextManagerWithOptionsTest);
-  });
-}
-
-/// Wrapper around the test package's `fail` function.
-///
-/// Unlike the test package's `fail` function, this function is not annotated
-/// with @alwaysThrows, so we can call it at the top of a test method without
-/// causing the rest of the method to be flagged as dead code.
-void _fail(String message) {
-  fail(message);
-}
-
-@reflectiveTest
-class AbstractContextManagerTest extends ContextManagerTest {
-  void test_contextsInAnalysisRoot_nestedContext() {
-    var subProjPath = join(projPath, 'subproj');
-    var subProjFolder = newFolder(subProjPath);
-    newFile(join(subProjPath, 'pubspec.yaml'), content: 'contents');
-    var subProjFilePath = join(subProjPath, 'file.dart');
-    newFile(subProjFilePath, content: 'contents');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // Make sure that there really are contexts for both the main project and
-    // the subproject.
-    var projectFolder = getFolder(projPath);
-    var projContextInfo = manager.getContextInfoFor(projectFolder);
-    expect(projContextInfo, isNotNull);
-    expect(projContextInfo.folder, projectFolder);
-    var subProjContextInfo = manager.getContextInfoFor(subProjFolder);
-    expect(subProjContextInfo, isNotNull);
-    expect(subProjContextInfo.folder, subProjFolder);
-    expect(projContextInfo.analysisDriver,
-        isNot(equals(subProjContextInfo.analysisDriver)));
-    // Check that getDriversInAnalysisRoot() works.
-    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, isNotNull);
-    expect(drivers, hasLength(2));
-    expect(drivers, contains(projContextInfo.analysisDriver));
-    expect(drivers, contains(subProjContextInfo.analysisDriver));
-  }
-
-  @failingTest
-  Future<void> test_embedder_added() async {
-    // NoSuchMethodError: The getter 'apiSignature' was called on null.
-    // Receiver: null
-    // Tried calling: apiSignature
-    // dart:core                                                          Object.noSuchMethod
-    // package:analyzer/src/dart/analysis/driver.dart 460:20              AnalysisDriver.configure
-    // package:analysis_server/src/context_manager.dart 1043:16           ContextManagerImpl._checkForPackagespecUpdate
-    // package:analysis_server/src/context_manager.dart 1553:5            ContextManagerImpl._handleWatchEvent
-    //return super.test_embedder_added();
-    _fail('NoSuchMethodError');
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    newFile('$libPath/nope.dart');
-    var embedderPath = '$projPath/embedder';
-    newFile('$embedderPath/entry.dart');
-    var embedderSrcPath = '$projPath/embedder/src';
-    newFile('$embedderSrcPath/part.dart');
-
-    // Setup _embedder.yaml.
-    newFile('$libPath/_embedder.yaml', content: r'''
-embedded_libs:
-  "dart:foobar": "../embedder/entry.dart"
-  "dart:typed_data": "../embedder/src/part"
-  ''');
-
-    var projectFolder = newFolder(projPath);
-
-    // NOTE that this is Not in our package path yet.
-
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-    // Confirm that one driver / context was created.
-    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, isNotNull);
-    expect(drivers, hasLength(1));
-
-    // No embedded libs yet.
-    expect(sourceFactory.forUri('dart:typed_data'), isNull);
-
-    // Add .packages file that introduces a dependency with embedded libs.
-    newFile('$projPath/.packages', content: r'''
-test_pack:lib/''');
-
-    await pumpEventQueue();
-
-    // Confirm that we still have just one driver / context.
-    drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, isNotNull);
-    expect(drivers, hasLength(1));
-
-    // Embedded lib should be defined now.
-    expect(sourceFactory.forUri('dart:typed_data'), isNotNull);
-  }
-
-  Future<void> test_embedder_packagespec() async {
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    newFile('$libPath/nope.dart');
-    var sdkExtPath = '$projPath/sdk_ext';
-    newFile('$sdkExtPath/entry.dart');
-    var sdkExtSrcPath = '$projPath/sdk_ext/src';
-    newFile('$sdkExtSrcPath/part.dart');
-    // Setup _embedder.yaml.
-    newFile('$libPath/_embedder.yaml', content: r'''
-embedded_libs:
-  "dart:foobar": "../sdk_ext/entry.dart"
-  "dart:typed_data": "../sdk_ext/src/part"
-  ''');
-    // Setup .packages file
-    newFile('$projPath/.packages', content: r'''
-sky_engine:lib/''');
-    // Setup context.
-
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-    // Confirm that one context was created.
-    var count = manager.numberOfContextsInAnalysisRoot(newFolder(projPath));
-    expect(count, equals(1));
-    var source = sourceFactory.forUri('dart:foobar');
-    expect(source, isNotNull);
-    expect(source.fullName, convertPath('/my/proj/sdk_ext/entry.dart'));
-    // We can't find dart:core because we didn't list it in our
-    // embedded_libs map.
-    expect(sourceFactory.forUri('dart:core'), isNull);
-    // We can find dart:typed_data because we listed it in our
-    // embedded_libs map.
-    expect(sourceFactory.forUri('dart:typed_data'), isNotNull);
-  }
-
-  void test_isInAnalysisRoot_excluded() {
-    // prepare paths
-    var project = convertPath('/project');
-    var excludedFolder = convertPath('$project/excluded');
-    // set roots
-    newFolder(project);
-    newFolder(excludedFolder);
-    manager.setRoots(<String>[project], <String>[excludedFolder]);
-    // verify
-    expect(manager.isInAnalysisRoot(convertPath('$excludedFolder/test.dart')),
-        isFalse);
-  }
-
-  void test_isInAnalysisRoot_inNestedContext() {
-    var subProjPath = join(projPath, 'subproj');
-    var subProjFolder = newFolder(subProjPath);
-    newFile(join(subProjPath, 'pubspec.yaml'), content: 'contents');
-    var subProjFilePath = join(subProjPath, 'file.dart');
-    newFile(subProjFilePath, content: 'contents');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // Make sure that there really is a context for the subproject.
-    var subProjContextInfo = manager.getContextInfoFor(subProjFolder);
-    expect(subProjContextInfo, isNotNull);
-    expect(subProjContextInfo.folder, subProjFolder);
-    // Check that isInAnalysisRoot() works.
-    expect(manager.isInAnalysisRoot(subProjFilePath), isTrue);
-  }
-
-  void test_isInAnalysisRoot_inRoot() {
-    manager.setRoots(<String>[projPath], <String>[]);
-    expect(manager.isInAnalysisRoot('$projPath/test.dart'), isTrue);
-  }
-
-  void test_isInAnalysisRoot_notInRoot() {
-    manager.setRoots(<String>[projPath], <String>[]);
-    expect(manager.isInAnalysisRoot('/test.dart'), isFalse);
-  }
-
-  Future<void> test_packagesFolder_areAnalyzed() {
-    // create a context with a pubspec.yaml file
-    var pubspecPath = join(projPath, 'pubspec.yaml');
-    newFile(pubspecPath, content: 'pubspec');
-    // create a file in the "packages" folder
-    var filePath1 = join(projPath, 'packages', 'file1.dart');
-    var file1 = newFile(filePath1, content: 'contents');
-    manager.setRoots(<String>[projPath], <String>[]);
-    expect(callbacks.currentFilePaths, unorderedEquals([file1.path]));
-    var filePath2 = join(projPath, 'packages', 'file2.dart');
-    var file2 = newFile(filePath2, content: 'contents');
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentFilePaths,
-          unorderedEquals([file1.path, file2.path]));
-    });
-  }
-
-  Future<void> test_refresh_folder_with_packagespec() {
-    // create a context with a .packages file
-    var packagespecFile = join(projPath, '.packages');
-    newFile(packagespecFile, content: '');
-    manager.setRoots(<String>[projPath], <String>[]);
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-      callbacks.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
-      });
-    });
-  }
-
-  // TODO(paulberry): This test only tests PackagesFileDisposition.
-  // Once http://dartbug.com/23909 is fixed, add a test for sdk extensions
-  // and PackageMapDisposition.
-  Future<void> test_refresh_folder_with_packagespec_subfolders() {
-    // Create a folder with no .packages file, containing two subfolders with
-    // .packages files.
-    var subdir1Path = join(projPath, 'subdir1');
-    var subdir2Path = join(projPath, 'subdir2');
-    var packagespec1Path = join(subdir1Path, '.packages');
-    var packagespec2Path = join(subdir2Path, '.packages');
-    newFile(packagespec1Path, content: '');
-    newFile(packagespec2Path, content: '');
-    manager.setRoots(<String>[projPath], <String>[]);
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentContextRoots,
-          unorderedEquals([subdir1Path, subdir2Path, projPath]));
-      callbacks.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(callbacks.currentContextRoots,
-            unorderedEquals([subdir1Path, subdir2Path, projPath]));
-        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
-        expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now);
-        expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now);
-      });
-    });
-  }
-
-  Future<void> test_refresh_folder_with_pubspec() {
-    // create a context with a pubspec.yaml file
-    var pubspecPath = join(projPath, 'pubspec.yaml');
-    newFile(pubspecPath, content: 'pubspec');
-    manager.setRoots(<String>[projPath], <String>[]);
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-      callbacks.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
-      });
-    });
-  }
-
-  Future<void> test_refresh_folder_with_pubspec_subfolders() {
-    // Create a folder with no pubspec.yaml, containing two subfolders with
-    // pubspec.yaml files.
-    var subdir1Path = join(projPath, 'subdir1');
-    var subdir2Path = join(projPath, 'subdir2');
-    var pubspec1Path = join(subdir1Path, 'pubspec.yaml');
-    var pubspec2Path = join(subdir2Path, 'pubspec.yaml');
-    newFile(pubspec1Path, content: 'pubspec');
-    newFile(pubspec2Path, content: 'pubspec');
-    manager.setRoots(<String>[projPath], <String>[]);
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentContextRoots,
-          unorderedEquals([subdir1Path, subdir2Path, projPath]));
-      callbacks.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(callbacks.currentContextRoots,
-            unorderedEquals([subdir1Path, subdir2Path, projPath]));
-        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
-        expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now);
-        expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now);
-      });
-    });
-  }
-
-  Future<void> test_refresh_oneContext() {
-    // create two contexts with pubspec.yaml files
-    var pubspecPath = join(projPath, 'pubspec.yaml');
-    newFile(pubspecPath, content: 'pubspec1');
-
-    var proj2Path = convertPath('/my/proj2');
-    newFolder(proj2Path);
-    var pubspec2Path = join(proj2Path, 'pubspec.yaml');
-    newFile(pubspec2Path, content: 'pubspec2');
-
-    var roots = <String>[projPath, proj2Path];
-    manager.setRoots(roots, <String>[]);
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentContextRoots, unorderedEquals(roots));
-      var then = callbacks.now;
-      callbacks.now++;
-      manager.refresh([getFolder(proj2Path)]);
-      return pumpEventQueue().then((_) {
-        expect(callbacks.currentContextRoots, unorderedEquals(roots));
-        expect(callbacks.currentContextTimestamps[projPath], then);
-        expect(callbacks.currentContextTimestamps[proj2Path], callbacks.now);
-      });
-    });
-  }
-
-  void test_setRoots_addFolderWithDartFile() {
-    var filePath = join(projPath, 'foo.dart');
-    newFile(filePath, content: 'contents');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    var filePaths = callbacks.currentFilePaths;
-    expect(filePaths, hasLength(1));
-    expect(filePaths, contains(filePath));
-    var drivers = manager.getDriversInAnalysisRoot(newFolder(projPath));
-    expect(drivers, hasLength(1));
-    expect(drivers[0], isNotNull);
-    var result = sourceFactory.forUri('dart:async');
-    expect(result, isNotNull);
-  }
-
-  void test_setRoots_addFolderWithDartFileInSubfolder() {
-    var filePath = join(projPath, 'foo', 'bar.dart');
-    newFile(filePath, content: 'contents');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    var filePaths = callbacks.currentFilePaths;
-    expect(filePaths, hasLength(1));
-    expect(filePaths, contains(filePath));
-  }
-
-  void test_setRoots_addFolderWithDummyLink() {
-    var filePath = join(projPath, 'foo.dart');
-    resourceProvider.newDummyLink(filePath);
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    expect(callbacks.currentFilePaths, isEmpty);
-  }
-
-  void test_setRoots_addFolderWithNestedPackageSpec() {
-    var examplePath =
-        convertPath('$projPath/${ContextManagerTest.EXAMPLE_NAME}');
-    var libPath = convertPath('$projPath/${ContextManagerTest.LIB_NAME}');
-
-    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}');
-    newFile('$libPath/main.dart');
-    newFile('$examplePath/${ContextManagerImpl.PACKAGE_SPEC_NAME}');
-    newFile('$examplePath/example.dart');
-
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    expect(callbacks.currentContextRoots, hasLength(2));
-
-    expect(callbacks.currentContextRoots, contains(projPath));
-    var projSources = callbacks.currentFileSources(projPath);
-    expect(projSources, hasLength(1));
-    expect(projSources.first.uri, toUri('$libPath/main.dart'));
-
-    expect(callbacks.currentContextRoots, contains(examplePath));
-    var exampleSources = callbacks.currentFileSources(examplePath);
-    expect(exampleSources, hasLength(1));
-    expect(exampleSources.first.uri, toUri('$examplePath/example.dart'));
-  }
-
-  void test_setRoots_addFolderWithNestedPubspec() {
-    var examplePath =
-        convertPath('$projPath/${ContextManagerTest.EXAMPLE_NAME}');
-    var libPath = convertPath('$projPath/${ContextManagerTest.LIB_NAME}');
-
-    newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
-    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
-        content: 'proj:lib/');
-    newFile('$libPath/main.dart');
-    newFile('$examplePath/${ContextManagerImpl.PUBSPEC_NAME}');
-    newFile('$examplePath/example.dart');
-
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    expect(callbacks.currentContextRoots, hasLength(2));
-
-    expect(callbacks.currentContextRoots, contains(projPath));
-    var projSources = callbacks.currentFileSources(projPath);
-    expect(projSources, hasLength(1));
-    expect(projSources.first.uri.toString(), 'package:proj/main.dart');
-
-    expect(callbacks.currentContextRoots, contains(examplePath));
-    var exampleSources = callbacks.currentFileSources(examplePath);
-    expect(exampleSources, hasLength(1));
-    expect(exampleSources.first.uri, toUri('$examplePath/example.dart'));
-  }
-
-  void test_setRoots_addFolderWithoutPubspec() {
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
-  void test_setRoots_addFolderWithPackagespec() {
-    var packagespecPath = join(projPath, '.packages');
-    var testLib = convertPath('/home/somebody/.pub/cache/unittest-0.9.9/lib');
-    newFile(packagespecPath, content: 'unittest:${toUriStr(testLib)}');
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    var mainFile = newFile('$libPath/main.dart');
-    var source = mainFile.createSource();
-
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // verify
-    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-    expect(callbacks.currentFilePaths, hasLength(1));
-
-    // smoketest resolution
-    var resolvedSource =
-        sourceFactory.resolveUri(source, 'package:unittest/unittest.dart');
-    expect(resolvedSource, isNotNull);
-    expect(resolvedSource.fullName, convertPath('$testLib/unittest.dart'));
-  }
-
-  void test_setRoots_addFolderWithPubspec() {
-    var pubspecPath = join(projPath, 'pubspec.yaml');
-    newFile(pubspecPath, content: 'pubspec');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
-  void test_setRoots_addFolderWithPubspec_andPackagespec() {
-    var pubspecPath = join(projPath, 'pubspec.yaml');
-    var packagespecPath = join(projPath, '.packages');
-    newFile(pubspecPath, content: 'pubspec');
-    newFile(packagespecPath, content: '');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    callbacks.assertContextPaths([projPath]);
-  }
-
-  void test_setRoots_addFolderWithPubspecAndLib() {
-    var binPath = '$projPath/${ContextManagerTest.BIN_NAME}';
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    var srcPath = '$libPath/${ContextManagerTest.SRC_NAME}';
-    var testPath = '$projPath/${ContextManagerTest.TEST_NAME}';
-
-    newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
-    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
-        content: 'proj:lib/');
-    var appPath = newFile('$binPath/app.dart').path;
-    newFile('$libPath/main.dart');
-    newFile('$srcPath/internal.dart');
-    var testFilePath = newFile('$testPath/main_test.dart').path;
-
-    manager.setRoots(<String>[projPath], <String>[]);
-    var sources = callbacks.currentFileSources(projPath);
-
-    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
-    expect(sources, hasLength(4));
-    var uris = sources.map((Source source) => source.uri.toString()).toList();
-    expect(uris, contains(toUriStr(appPath)));
-    expect(uris, contains('package:proj/main.dart'));
-    expect(uris, contains('package:proj/src/internal.dart'));
-    expect(uris, contains(toUriStr(testFilePath)));
-  }
-
-  void test_setRoots_addFolderWithPubspecAndPackagespecFolders() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProjectA = convertPath('$root/sub/aaa');
-    var subProjectB = convertPath('$root/sub/sub2/bbb');
-    var subProjectA_file = convertPath('$subProjectA/bin/a.dart');
-    var subProjectB_file = convertPath('$subProjectB/bin/b.dart');
-    // create files
-    newFile('$subProjectA/pubspec.yaml', content: 'pubspec');
-    newFile('$subProjectB/pubspec.yaml', content: 'pubspec');
-    newFile('$subProjectA/.packages');
-    newFile('$subProjectB/.packages');
-
-    newFile(rootFile, content: 'library root;');
-    newFile(subProjectA_file, content: 'library a;');
-    newFile(subProjectB_file, content: 'library b;');
-
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, subProjectA, subProjectB]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
-    callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
-  }
-
-  void test_setRoots_addFolderWithPubspecFolders() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var projectA = convertPath('$root/sub/aaa');
-    var projectALib = convertPath('$root/sub/aaa/lib');
-    var subProjectA_file = convertPath('$projectA/bin/a.dart');
-    var projectB = convertPath('$root/sub/sub2/bbb');
-    var projectBLib = convertPath('$root/sub/sub2/bbb/lib');
-    var subProjectB_file = convertPath('$projectB/bin/b.dart');
-    // create files
-    newFile('$projectA/${ContextManagerImpl.PUBSPEC_NAME}');
-    newFile('$projectA/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
-        content: 'foo:lib/');
-    newFile('$projectB/${ContextManagerImpl.PUBSPEC_NAME}');
-    newFile('$projectB/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
-        content: 'bar:lib/');
-    newFile(rootFile, content: 'library root;');
-    newFile(subProjectA_file, content: 'library a;');
-    newFile(subProjectB_file, content: 'library b;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, projectA, projectB]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(projectA, [subProjectA_file]);
-    callbacks.assertContextFiles(projectB, [subProjectB_file]);
-    // verify package maps
-    expect(_packageMap(root), isEmpty);
-    expect(
-        _packageMap(projectA),
-        equals({
-          'foo': [getFolder(projectALib)]
-        }));
-    expect(
-        _packageMap(projectB),
-        equals({
-          'bar': [getFolder(projectBLib)]
-        }));
-  }
-
-  void test_setRoots_exclude_newRoot_withExcludedFile() {
-    // prepare paths
-    var project = convertPath('/project');
-    var file1 = convertPath('$project/file1.dart');
-    var file2 = convertPath('$project/file2.dart');
-    // create files
-    newFile(file1, content: '// 1');
-    newFile(file2, content: '// 2');
-    // set roots
-    manager.setRoots(<String>[project], <String>[file1]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [file2]);
-  }
-
-  void test_setRoots_exclude_newRoot_withExcludedFolder() {
-    // prepare paths
-    var project = convertPath('/project');
-    var folderA = convertPath('$project/aaa');
-    var folderB = convertPath('$project/bbb');
-    var fileA = convertPath('$folderA/a.dart');
-    var fileB = convertPath('$folderB/b.dart');
-    // create files
-    newFile(fileA, content: 'library a;');
-    newFile(fileB, content: 'library b;');
-    // set roots
-    manager.setRoots(<String>[project], <String>[folderB]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-  }
-
-  void test_setRoots_exclude_sameRoot_addExcludedFile() {
-    // prepare paths
-    var project = convertPath('/project');
-    var file1 = convertPath('$project/file1.dart');
-    var file2 = convertPath('$project/file2.dart');
-    // create files
-    newFile(file1, content: '// 1');
-    newFile(file2, content: '// 2');
-    // set roots
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [file1, file2]);
-    // exclude "2"
-    manager.setRoots(<String>[project], <String>[file2]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [file1]);
-  }
-
-  void test_setRoots_exclude_sameRoot_addExcludedFolder() {
-    // prepare paths
-    var project = convertPath('/project');
-    var folderA = convertPath('$project/aaa');
-    var folderB = convertPath('$project/bbb');
-    var fileA = convertPath('$folderA/a.dart');
-    var fileB = convertPath('$folderB/b.dart');
-    // create files
-    newFile(fileA, content: 'library a;');
-    newFile(fileB, content: 'library b;');
-    // initially both "aaa/a" and "bbb/b" are included
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA, fileB]);
-    // exclude "bbb/"
-    manager.setRoots(<String>[project], <String>[folderB]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-  }
-
-  void test_setRoots_exclude_sameRoot_removeExcludedFile() {
-    // prepare paths
-    var project = convertPath('/project');
-    var file1 = convertPath('$project/file1.dart');
-    var file2 = convertPath('$project/file2.dart');
-    // create files
-    newFile(file1, content: '// 1');
-    newFile(file2, content: '// 2');
-    // set roots
-    manager.setRoots(<String>[project], <String>[file2]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [file1]);
-    // stop excluding "2"
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [file1, file2]);
-  }
-
-  void test_setRoots_exclude_sameRoot_removeExcludedFile_inFolder() {
-    // prepare paths
-    var project = convertPath('/project');
-    var file1 = convertPath('$project/bin/file1.dart');
-    var file2 = convertPath('$project/bin/file2.dart');
-    // create files
-    newFile(file1, content: '// 1');
-    newFile(file2, content: '// 2');
-    // set roots
-    manager.setRoots(<String>[project], <String>[file2]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [file1]);
-    // stop excluding "2"
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [file1, file2]);
-  }
-
-  void test_setRoots_exclude_sameRoot_removeExcludedFolder() {
-    // prepare paths
-    var project = convertPath('/project');
-    var folderA = convertPath('$project/aaa');
-    var folderB = convertPath('$project/bbb');
-    var fileA = convertPath('$folderA/a.dart');
-    var fileB = convertPath('$folderB/b.dart');
-    // create files
-    newFile(fileA, content: 'library a;');
-    newFile(fileB, content: 'library b;');
-    // exclude "bbb/"
-    manager.setRoots(<String>[project], <String>[folderB]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-    // stop excluding "bbb/"
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA, fileB]);
-  }
-
-  void test_setRoots_ignoreDocFolder() {
-    var project = convertPath('/project');
-    var fileA = convertPath('$project/foo.dart');
-    var fileB = convertPath('$project/lib/doc/bar.dart');
-    var fileC = convertPath('$project/doc/bar.dart');
-    newFile(fileA, content: '');
-    newFile(fileB, content: '');
-    newFile(fileC, content: '');
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA, fileB]);
-  }
-
-  void test_setRoots_nested_includedByOuter_innerFirst() {
-    var project = convertPath('/project');
-    var projectPubspec = convertPath('$project/pubspec.yaml');
-    var example = convertPath('$project/example');
-    var examplePubspec = convertPath('$example/pubspec.yaml');
-    // create files
-    newFile(projectPubspec, content: 'name: project');
-    newFile(examplePubspec, content: 'name: example');
-    manager.setRoots(<String>[example, project], <String>[]);
-    // verify
-    {
-      var rootInfo = manager.rootInfo;
-      expect(rootInfo.children, hasLength(1));
-      {
-        var projectInfo = rootInfo.children[0];
-        expect(projectInfo.folder.path, project);
-        expect(projectInfo.children, hasLength(1));
-        {
-          var exampleInfo = projectInfo.children[0];
-          expect(exampleInfo.folder.path, example);
-          expect(exampleInfo.children, isEmpty);
-        }
-      }
-    }
-    expect(callbacks.currentContextRoots, unorderedEquals([project, example]));
-  }
-
-  void test_setRoots_nested_includedByOuter_outerPubspec() {
-    var project = convertPath('/project');
-    var projectPubspec = convertPath('$project/pubspec.yaml');
-    var example = convertPath('$project/example');
-    // create files
-    newFile(projectPubspec, content: 'name: project');
-    newFolder(example);
-    manager.setRoots(<String>[project, example], <String>[]);
-    // verify
-    {
-      var rootInfo = manager.rootInfo;
-      expect(rootInfo.children, hasLength(1));
-      {
-        var projectInfo = rootInfo.children[0];
-        expect(projectInfo.folder.path, project);
-        expect(projectInfo.children, isEmpty);
-      }
-    }
-    expect(callbacks.currentContextRoots, unorderedEquals([project]));
-  }
-
-  void test_setRoots_nested_includedByOuter_twoPubspecs() {
-    var project = convertPath('/project');
-    var projectPubspec = convertPath('$project/pubspec.yaml');
-    var example = convertPath('$project/example');
-    var examplePubspec = convertPath('$example/pubspec.yaml');
-    // create files
-    newFile(projectPubspec, content: 'name: project');
-    newFile(examplePubspec, content: 'name: example');
-    manager.setRoots(<String>[project, example], <String>[]);
-    // verify
-    {
-      var rootInfo = manager.rootInfo;
-      expect(rootInfo.children, hasLength(1));
-      {
-        var projectInfo = rootInfo.children[0];
-        expect(projectInfo.folder.path, project);
-        expect(projectInfo.children, hasLength(1));
-        {
-          var exampleInfo = projectInfo.children[0];
-          expect(exampleInfo.folder.path, example);
-          expect(exampleInfo.children, isEmpty);
-        }
-      }
-    }
-    expect(callbacks.currentContextRoots, unorderedEquals([project, example]));
-  }
-
-  void test_setRoots_newlyAddedFoldersGetProperPackageMap() {
-    var packagePath = convertPath('/package/foo');
-    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
-        content: 'foo:${toUriStr('/package/foo')}');
-    var packageFolder = newFolder(packagePath);
-    manager.setRoots(<String>[projPath], <String>[]);
-    expect(
-        _currentPackageMap,
-        equals({
-          'foo': [packageFolder]
-        }));
-  }
-
-  void test_setRoots_noContext_excludedFolder() {
-    // prepare paths
-    var project = convertPath('/project');
-    var excludedFolder = convertPath('$project/excluded');
-    var excludedPubspec = convertPath('$excludedFolder/pubspec.yaml');
-    // create files
-    newFile(excludedPubspec, content: 'name: ignore-me');
-    // set "/project", and exclude "/project/excluded"
-    manager.setRoots(<String>[project], <String>[excludedFolder]);
-    callbacks.assertContextPaths([project]);
-  }
-
-  void test_setRoots_noContext_inDotFolder() {
-    var pubspecPath = join(projPath, '.pub', 'pubspec.yaml');
-    newFile(pubspecPath, content: 'name: test');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    expect(callbacks.currentContextRoots, hasLength(1));
-    expect(callbacks.currentContextRoots, contains(projPath));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
-  void test_setRoots_packageResolver() {
-    var filePath = join(projPath, 'lib', 'foo.dart');
-    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
-        content: 'foo:lib/');
-    newFile(filePath, content: 'contents');
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    var drivers = manager.getDriversInAnalysisRoot(newFolder(projPath));
-    expect(drivers, hasLength(1));
-    expect(drivers[0], isNotNull);
-    var result = sourceFactory.forUri('package:foo/foo.dart');
-    expect(result.fullName, filePath);
-  }
-
-  void test_setRoots_packagesFolder_hasContext() {
-    var pubspecPath = join(projPath, 'packages', 'pubspec.yaml');
-    newFile(pubspecPath, content: 'name: test');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // verify
-    expect(callbacks.currentContextRoots, hasLength(2));
-    expect(callbacks.currentContextRoots, contains(projPath));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
-  void test_setRoots_pathContainsDotFile() {
-    // If the path to a file (relative to the context root) contains a folder
-    // whose name begins with '.', then the file is ignored.
-    var project = convertPath('/project');
-    var fileA = convertPath('$project/foo.dart');
-    var fileB = convertPath('$project/.pub/bar.dart');
-    newFile(fileA, content: '');
-    newFile(fileB, content: '');
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-  }
-
-  void test_setRoots_removeFolderWithoutPubspec() {
-    // add one root - there is a context
-    manager.setRoots(<String>[projPath], <String>[]);
-    expect(callbacks.currentContextRoots, hasLength(1));
-    // set empty roots - no contexts
-    manager.setRoots(<String>[], <String>[]);
-    expect(callbacks.currentContextRoots, hasLength(0));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
-  void test_setRoots_removeFolderWithPackagespec() {
-    // create a pubspec
-    var pubspecPath = join(projPath, '.packages');
-    newFile(pubspecPath, content: '');
-    // add one root - there is a context
-    manager.setRoots(<String>[projPath], <String>[]);
-    expect(manager.changeSubscriptions, hasLength(1));
-    expect(callbacks.currentContextRoots, hasLength(1));
-    // set empty roots - no contexts
-    manager.setRoots(<String>[], <String>[]);
-    expect(manager.changeSubscriptions, hasLength(0));
-    expect(callbacks.currentContextRoots, hasLength(0));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
-  void test_setRoots_removeFolderWithPackagespecFolder() {
-    // prepare paths
-    var projectA = convertPath('/projectA');
-    var projectB = convertPath('/projectB');
-    var subProjectA = convertPath('$projectA/sub');
-    var subProjectB = convertPath('$projectB/sub');
-    var projectA_file = convertPath('$projectA/a.dart');
-    var projectB_file = convertPath('$projectB/a.dart');
-    var subProjectA_pubspec = convertPath('$subProjectA/.packages');
-    var subProjectB_pubspec = convertPath('$subProjectB/.packages');
-    var subProjectA_file = convertPath('$subProjectA/bin/sub_a.dart');
-    var subProjectB_file = convertPath('$subProjectB/bin/sub_b.dart');
-    // create files
-    newFile(projectA_file, content: '// a');
-    newFile(projectB_file, content: '// b');
-    newFile(subProjectA_pubspec, content: '');
-    newFile(subProjectB_pubspec, content: '');
-    newFile(subProjectA_file, content: '// sub-a');
-    newFile(subProjectB_file, content: '// sub-b');
-    // set roots
-    manager.setRoots(<String>[projectA, projectB], <String>[]);
-    callbacks
-        .assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
-    callbacks.assertContextFiles(projectA, [projectA_file]);
-    callbacks.assertContextFiles(projectB, [projectB_file]);
-    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
-    callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
-    // remove "projectB"
-    manager.setRoots(<String>[projectA], <String>[]);
-    callbacks.assertContextPaths([projectA, subProjectA]);
-    callbacks.assertContextFiles(projectA, [projectA_file]);
-    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
-  }
-
-  void test_setRoots_removeFolderWithPubspec() {
-    // create a pubspec
-    var pubspecPath = join(projPath, 'pubspec.yaml');
-    newFile(pubspecPath, content: 'pubspec');
-    // add one root - there is a context
-    manager.setRoots(<String>[projPath], <String>[]);
-    expect(callbacks.currentContextRoots, hasLength(1));
-    // set empty roots - no contexts
-    manager.setRoots(<String>[], <String>[]);
-    expect(callbacks.currentContextRoots, hasLength(0));
-    expect(callbacks.currentFilePaths, hasLength(0));
-  }
-
-  void test_setRoots_removeFolderWithPubspecFolder() {
-    // prepare paths
-    var projectA = convertPath('/projectA');
-    var projectB = convertPath('/projectB');
-    var subProjectA = convertPath('$projectA/sub');
-    var subProjectB = convertPath('$projectB/sub');
-    var projectA_file = convertPath('$projectA/a.dart');
-    var projectB_file = convertPath('$projectB/a.dart');
-    var subProjectA_pubspec = convertPath('$subProjectA/pubspec.yaml');
-    var subProjectB_pubspec = convertPath('$subProjectB/pubspec.yaml');
-    var subProjectA_file = convertPath('$subProjectA/bin/sub_a.dart');
-    var subProjectB_file = convertPath('$subProjectB/bin/sub_b.dart');
-    // create files
-    newFile(projectA_file, content: '// a');
-    newFile(projectB_file, content: '// b');
-    newFile(subProjectA_pubspec, content: 'pubspec');
-    newFile(subProjectB_pubspec, content: 'pubspec');
-    newFile(subProjectA_file, content: '// sub-a');
-    newFile(subProjectB_file, content: '// sub-b');
-    // set roots
-    manager.setRoots(<String>[projectA, projectB], <String>[]);
-    callbacks
-        .assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
-    callbacks.assertContextFiles(projectA, [projectA_file]);
-    callbacks.assertContextFiles(projectB, [projectB_file]);
-    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
-    callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
-    // remove "projectB"
-    manager.setRoots(<String>[projectA], <String>[]);
-    callbacks.assertContextPaths([projectA, subProjectA]);
-    callbacks.assertContextFiles(projectA, [projectA_file]);
-    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
-  }
-
-  void test_setRoots_rootPathContainsDotFile() {
-    // If the path to the context root itself contains a folder whose name
-    // begins with '.', then that is not sufficient to cause any files in the
-    // context to be ignored.
-    var project = convertPath('/.pub/project');
-    var fileA = convertPath('$project/foo.dart');
-    newFile(fileA, content: '');
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-  }
-
-  Future<void> test_watch_addDummyLink() {
-    manager.setRoots(<String>[projPath], <String>[]);
-    // empty folder initially
-    expect(callbacks.currentFilePaths, isEmpty);
-    // add link
-    var filePath = join(projPath, 'foo.dart');
-    resourceProvider.newDummyLink(filePath);
-    // the link was ignored
-    return pumpEventQueue().then((_) {
-      expect(callbacks.currentFilePaths, isEmpty);
-    });
-  }
-
-  Future<void> test_watch_addFile() {
-    manager.setRoots(<String>[projPath], <String>[]);
-    // empty folder initially
-    expect(callbacks.currentFilePaths, hasLength(0));
-    // add file
-    var filePath = join(projPath, 'foo.dart');
-    newFile(filePath, content: 'contents');
-    // the file was added
-    return pumpEventQueue().then((_) {
-      var filePaths = callbacks.currentFilePaths;
-      expect(filePaths, hasLength(1));
-      expect(filePaths, contains(filePath));
-    });
-  }
-
-  Future<void> test_watch_addFile_excluded() {
-    // prepare paths
-    var project = convertPath('/project');
-    var folderA = convertPath('$project/aaa');
-    var folderB = convertPath('$project/bbb');
-    var fileA = convertPath('$folderA/a.dart');
-    var fileB = convertPath('$folderB/b.dart');
-    // create files
-    newFile(fileA, content: 'library a;');
-    // set roots
-    manager.setRoots(<String>[project], <String>[folderB]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-    // add a file, ignored as excluded
-    newFile(fileB, content: 'library b;');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([project]);
-      callbacks.assertContextFiles(project, [fileA]);
-    });
-  }
-
-  Future<void> test_watch_addFile_inDocFolder_inner() {
-    // prepare paths
-    var project = convertPath('/project');
-    var fileA = convertPath('$project/a.dart');
-    var fileB = convertPath('$project/lib/doc/b.dart');
-    // create files
-    newFile(fileA, content: '');
-    // set roots
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-    // add a "lib/doc" file, it is not ignored
-    newFile(fileB, content: '');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([project]);
-      callbacks.assertContextFiles(project, [fileA, fileB]);
-    });
-  }
-
-  Future<void> test_watch_addFile_inDocFolder_topLevel() {
-    // prepare paths
-    var project = convertPath('/project');
-    var fileA = convertPath('$project/a.dart');
-    var fileB = convertPath('$project/doc/b.dart');
-    // create files
-    newFile(fileA, content: '');
-    // set roots
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-    // add a "doc" file, it is ignored
-    newFile(fileB, content: '');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([project]);
-      callbacks.assertContextFiles(project, [fileA]);
-    });
-  }
-
-  Future<void> test_watch_addFile_pathContainsDotFile() async {
-    // If a file is added and the path to it (relative to the context root)
-    // contains a folder whose name begins with '.', then the file is ignored.
-    var project = convertPath('/project');
-    var fileA = convertPath('$project/foo.dart');
-    var fileB = convertPath('$project/.pub/bar.dart');
-    newFile(fileA, content: '');
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-    newFile(fileB, content: '');
-    await pumpEventQueue();
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-  }
-
-  Future<void> test_watch_addFile_rootPathContainsDotFile() async {
-    // If a file is added and the path to the context contains a folder whose
-    // name begins with '.', then the file is not ignored.
-    var project = convertPath('/.pub/project');
-    var fileA = convertPath('$project/foo.dart');
-    var fileB = convertPath('$project/bar/baz.dart');
-    newFile(fileA, content: '');
-    manager.setRoots(<String>[project], <String>[]);
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA]);
-    newFile(fileB, content: '');
-    await pumpEventQueue();
-    callbacks.assertContextPaths([project]);
-    callbacks.assertContextFiles(project, [fileA, fileB]);
-  }
-
-  Future<void> test_watch_addFileInSubfolder() {
-    manager.setRoots(<String>[projPath], <String>[]);
-    // empty folder initially
-    expect(callbacks.currentFilePaths, hasLength(0));
-    // add file in subfolder
-    var filePath = join(projPath, 'foo', 'bar.dart');
-    newFile(filePath, content: 'contents');
-    // the file was added
-    return pumpEventQueue().then((_) {
-      var filePaths = callbacks.currentFilePaths;
-      expect(filePaths, hasLength(1));
-      expect(filePaths, contains(filePath));
-    });
-  }
-
-  Future<void> test_watch_addPackagespec_toRoot() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var rootPackagespec = convertPath('$root/.packages');
-    // create files
-    newFile(rootFile, content: 'library root;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    // add packagespec - still just one root
-    newFile(rootPackagespec, content: '');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root]);
-      callbacks.assertContextFiles(root, [rootFile]);
-      // TODO(pquitslund): verify that a new source factory is created --
-      // likely this will need to happen in a corresponding ServerContextManagerTest.
-    });
-  }
-
-  Future<void> test_watch_addPackagespec_toSubFolder() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub/aaa');
-    var subPubspec = convertPath('$subProject/.packages');
-    var subFile = convertPath('$subProject/bin/a.dart');
-    // create files
-    newFile(rootFile, content: 'library root;');
-    newFile(subFile, content: 'library a;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile, subFile]);
-    // add .packages
-    newFile(subPubspec, content: '');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root, subProject]);
-      callbacks.assertContextFiles(root, [rootFile]);
-      callbacks.assertContextFiles(subProject, [subFile]);
-    });
-  }
-
-  Future<void> test_watch_addPackagespec_toSubFolder_ofSubFolder() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub');
-    var subPubspec = convertPath('$subProject/.packages');
-    var subFile = convertPath('$subProject/bin/sub.dart');
-    var subSubPubspec = convertPath('$subProject/subsub/.packages');
-    // create files
-    newFile(rootFile, content: 'library root;');
-    newFile(subPubspec, content: '');
-    newFile(subFile, content: 'library sub;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, subProject]);
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(subProject, [subFile]);
-    // add pubspec - ignore, because is already in a packagespec-based context
-    newFile(subSubPubspec, content: '');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root, subProject]);
-      callbacks.assertContextFiles(root, [rootFile]);
-      callbacks.assertContextFiles(subProject, [subFile]);
-    });
-  }
-
-  Future<void> test_watch_addPackagespec_toSubFolder_withPubspec() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub/aaa');
-    var subPackagespec = convertPath('$subProject/.packages');
-    var subPubspec = convertPath('$subProject/pubspec.yaml');
-    var subFile = convertPath('$subProject/bin/a.dart');
-    // create files
-    newFile(subPubspec, content: 'pubspec');
-    newFile(rootFile, content: 'library root;');
-    newFile(subFile, content: 'library a;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, subProject]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(subProject, [subFile]);
-
-    // add .packages
-    newFile(subPackagespec, content: '');
-    return pumpEventQueue().then((_) {
-      // Should NOT create another context.
-      callbacks.assertContextPaths([root, subProject]);
-      callbacks.assertContextFiles(root, [rootFile]);
-      callbacks.assertContextFiles(subProject, [subFile]);
-    });
-  }
-
-  Future<void> test_watch_addPubspec_toRoot() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var rootPubspec = convertPath('$root/pubspec.yaml');
-    // create files
-    newFile(rootFile, content: 'library root;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    // add pubspec - still just one root
-    newFile(rootPubspec, content: 'pubspec');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root]);
-      callbacks.assertContextFiles(root, [rootFile]);
-    });
-  }
-
-  Future<void> test_watch_addPubspec_toSubFolder() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub/aaa');
-    var subPubspec = convertPath('$subProject/pubspec.yaml');
-    var subFile = convertPath('$subProject/bin/a.dart');
-    // create files
-    newFile(rootFile, content: 'library root;');
-    newFile(subFile, content: 'library a;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile, subFile]);
-    // add pubspec
-    newFile(subPubspec, content: 'pubspec');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root, subProject]);
-      callbacks.assertContextFiles(root, [rootFile]);
-      callbacks.assertContextFiles(subProject, [subFile]);
-    });
-  }
-
-  Future<void> test_watch_addPubspec_toSubFolder_ofSubFolder() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub');
-    var subPubspec = convertPath('$subProject/pubspec.yaml');
-    var subFile = convertPath('$subProject/bin/sub.dart');
-    var subSubPubspec = convertPath('$subProject/subsub/pubspec.yaml');
-    // create files
-    newFile(rootFile, content: 'library root;');
-    newFile(subPubspec, content: 'pubspec');
-    newFile(subFile, content: 'library sub;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, subProject]);
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(subProject, [subFile]);
-    // add pubspec - ignore, because is already in a pubspec-based context
-    newFile(subSubPubspec, content: 'pubspec');
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root, subProject]);
-      callbacks.assertContextFiles(root, [rootFile]);
-      callbacks.assertContextFiles(subProject, [subFile]);
-    });
-  }
-
-  Future<void> test_watch_deleteFile() {
-    var filePath = join(projPath, 'foo.dart');
-    // add root with a file
-    var file = newFile(filePath, content: 'contents');
-    var projFolder = file.parent2;
-    manager.setRoots(<String>[projPath], <String>[]);
-    // the file was added
-    var filePaths = callbacks.currentFilePaths;
-    expect(filePaths, hasLength(1));
-    expect(filePaths, contains(filePath));
-    expect(file.exists, isTrue);
-    expect(projFolder.exists, isTrue);
-    // delete the file
-    deleteFile(filePath);
-    return pumpEventQueue().then((_) {
-      expect(file.exists, isFalse);
-      expect(projFolder.exists, isTrue);
-      expect(callbacks.currentFilePaths, hasLength(0));
-    });
-  }
-
-  Future<void> test_watch_deleteFolder() {
-    var filePath = join(projPath, 'foo.dart');
-    // add root with a file
-    var file = newFile(filePath, content: 'contents');
-    var projFolder = file.parent2;
-    manager.setRoots(<String>[projPath], <String>[]);
-    // the file was added
-    var filePaths = callbacks.currentFilePaths;
-    expect(filePaths, hasLength(1));
-    expect(filePaths, contains(filePath));
-    expect(file.exists, isTrue);
-    expect(projFolder.exists, isTrue);
-    // delete the folder
-    deleteFolder(projPath);
-    return pumpEventQueue().then((_) {
-      expect(file.exists, isFalse);
-      expect(projFolder.exists, isFalse);
-      expect(callbacks.currentFilePaths, hasLength(0));
-    });
-  }
-
-  Future<void> test_watch_deletePackagespec_fromRoot() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootPubspec = convertPath('$root/.packages');
-    var rootFile = convertPath('$root/root.dart');
-    // create files
-    newFile(rootPubspec, content: '');
-    newFile(rootFile, content: 'library root;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root]);
-    callbacks.assertContextFiles(root, [rootFile]);
-    // delete the pubspec
-    deleteFile(rootPubspec);
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root]);
-      callbacks.assertContextFiles(root, [rootFile]);
-    });
-  }
-
-  Future<void> test_watch_deletePackagespec_fromSubFolder() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub/aaa');
-    var subPubspec = convertPath('$subProject/.packages');
-    var subFile = convertPath('$subProject/bin/a.dart');
-    // create files
-    newFile(subPubspec, content: '');
-    newFile(rootFile, content: 'library root;');
-    newFile(subFile, content: 'library a;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, subProject]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(subProject, [subFile]);
-    // delete the pubspec
-    deleteFile(subPubspec);
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root]);
-      callbacks.assertContextFiles(root, [rootFile, subFile]);
-    });
-  }
-
-  Future<void> test_watch_deletePackagespec_fromSubFolder_withPubspec() {
-    // prepare paths:
-    //
-    // root
-    //   root.dart
-    //   sub
-    //     aaa
-    //       .packages
-    //       pubspec.yaml
-    //       bin
-    //         a.dart
-    //
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub/aaa');
-    var subPackagespec = convertPath('$subProject/.packages');
-    var subPubspec = convertPath('$subProject/pubspec.yaml');
-    var subFile = convertPath('$subProject/bin/a.dart');
-    // create files
-    newFile(subPackagespec, content: '');
-    newFile(subPubspec, content: 'pubspec');
-    newFile(rootFile, content: 'library root;');
-    newFile(subFile, content: 'library a;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, subProject]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(subProject, [subFile]);
-    // delete the packagespec
-    deleteFile(subPackagespec);
-    return pumpEventQueue().then((_) {
-      // Should NOT merge
-      callbacks.assertContextPaths([root, subProject]);
-      callbacks.assertContextFiles(subProject, [subFile]);
-    });
-  }
-
-  Future<void> test_watch_deletePubspec_fromRoot() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootPubspec = convertPath('$root/pubspec.yaml');
-    var rootFile = convertPath('$root/root.dart');
-    // create files
-    newFile(rootPubspec, content: 'pubspec');
-    newFile(rootFile, content: 'library root;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root]);
-    callbacks.assertContextFiles(root, [rootFile]);
-    // delete the pubspec
-    deleteFile(rootPubspec);
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root]);
-      callbacks.assertContextFiles(root, [rootFile]);
-    });
-  }
-
-  Future<void> test_watch_deletePubspec_fromSubFolder() {
-    // prepare paths
-    var root = convertPath('/root');
-    var rootFile = convertPath('$root/root.dart');
-    var subProject = convertPath('$root/sub/aaa');
-    var subPubspec = convertPath('$subProject/pubspec.yaml');
-    var subFile = convertPath('$subProject/bin/a.dart');
-    // create files
-    newFile(subPubspec, content: 'pubspec');
-    newFile(rootFile, content: 'library root;');
-    newFile(subFile, content: 'library a;');
-    // set roots
-    manager.setRoots(<String>[root], <String>[]);
-    callbacks.assertContextPaths([root, subProject]);
-    // verify files
-    callbacks.assertContextFiles(root, [rootFile]);
-    callbacks.assertContextFiles(subProject, [subFile]);
-    // delete the pubspec
-    deleteFile(subPubspec);
-    return pumpEventQueue().then((_) {
-      callbacks.assertContextPaths([root]);
-      callbacks.assertContextFiles(root, [rootFile, subFile]);
-    });
-  }
-
-  Future<void> test_watch_modifyFile() {
-    var filePath = join(projPath, 'foo.dart');
-    // add root with a file
-    newFile(filePath, content: 'contents');
-    manager.setRoots(<String>[projPath], <String>[]);
-    // the file was added
-    var filePaths = callbacks.currentFilePaths;
-    expect(filePaths, hasLength(1));
-    expect(filePaths, contains(filePath));
-    // TODO(brianwilkerson) Test when the file was modified
-    // update the file
-    callbacks.now++;
-    modifyFile(filePath, 'new contents');
-    return pumpEventQueue().then((_) {
-      // TODO(brianwilkerson) Test when the file was modified
-    });
-  }
-
-  Future<void> test_watch_modifyPackageConfigJson() {
-    var packageConfigPath = '$projPath/.dart_tool/package_config.json';
-    var filePath = convertPath('$projPath/bin/main.dart');
-
-    newFile(packageConfigPath, content: '');
-    newFile(filePath, content: 'library main;');
-
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    var filePaths = callbacks.currentFilePaths;
-    expect(filePaths, hasLength(1));
-    expect(filePaths, contains(filePath));
-    expect(_currentPackageMap, isEmpty);
-
-    // update .dart_tool/package_config.json
-    callbacks.now++;
-    modifyFile(
-      packageConfigPath,
-      (PackageConfigFileBuilder()..add(name: 'my', rootPath: '../'))
-          .toContent(toUriStr: toUriStr),
-    );
-
-    return pumpEventQueue().then((_) {
-      // verify new package info
-      expect(_currentPackageMap.keys, unorderedEquals(['my']));
-    });
-  }
-
-  Future<void> test_watch_modifyPackagespec() {
-    var packagesPath = convertPath('$projPath/.packages');
-    var filePath = convertPath('$projPath/bin/main.dart');
-
-    newFile(packagesPath, content: '');
-    newFile(filePath, content: 'library main;');
-
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    var filePaths = callbacks.currentFilePaths;
-    expect(filePaths, hasLength(1));
-    expect(filePaths, contains(filePath));
-    expect(_currentPackageMap, isEmpty);
-
-    // update .packages
-    callbacks.now++;
-    modifyFile(packagesPath, 'main:./lib/');
-    return pumpEventQueue().then((_) {
-      // verify new package info
-      expect(_currentPackageMap.keys, unorderedEquals(['main']));
-    });
-  }
-}
-
-abstract class ContextManagerTest with ResourceProviderMixin {
-  /// The name of the 'bin' directory.
-  static const String BIN_NAME = 'bin';
-
-  /// The name of the 'example' directory.
-  static const String EXAMPLE_NAME = 'example';
-
-  /// The name of the 'lib' directory.
-  static const String LIB_NAME = 'lib';
-
-  /// The name of the 'src' directory.
-  static const String SRC_NAME = 'src';
-
-  /// The name of the 'test' directory.
-  static const String TEST_NAME = 'test';
-
-  ContextManagerImpl manager;
-
-  TestContextManagerCallbacks callbacks;
-
-  String projPath;
-
-  AnalysisError missing_return =
-      AnalysisError(_MockSource('test.dart'), 0, 1, HintCode.MISSING_RETURN, [
-    ['x']
-  ]);
-
-  AnalysisError invalid_assignment_error = AnalysisError(
-      _MockSource('test.dart'), 0, 1, CompileTimeErrorCode.INVALID_ASSIGNMENT, [
-    ['x'],
-    ['y']
-  ]);
-
-  AnalysisError unused_local_variable = AnalysisError(
-      _MockSource('test.dart'), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
-    ['x']
-  ]);
-
-  List<Glob> get analysisFilesGlobs {
-    var patterns = <String>[
-      '**/*.${AnalysisEngine.SUFFIX_DART}',
-      '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}'
-    ];
-    return patterns
-        .map((pattern) => Glob(path.posix.separator, pattern))
-        .toList();
-  }
-
-  AnalysisOptions get analysisOptions => callbacks.analysisOptions;
-
-  List<ErrorProcessor> get errorProcessors => analysisOptions.errorProcessors;
-
-  List<Linter> get lints => analysisOptions.lintRules;
-
-  SourceFactory get sourceFactory => callbacks.sourceFactory;
-
-  Map<String, List<Folder>> get _currentPackageMap => _packageMap(projPath);
-
-  /// TODO(brianwilkerson) This doesn't add the strong mode processor when using
-  /// the new analysis driver.
-  ErrorProcessor getProcessor(AnalysisError error) => errorProcessors
-      .firstWhere((ErrorProcessor p) => p.appliesTo(error), orElse: () => null);
-
-  void processRequiredPlugins() {
-    registerLintRules();
-  }
-
-  void setUp() {
-    processRequiredPlugins();
-    projPath = convertPath('/my/proj');
-    newFolder(projPath);
-    // Create an SDK in the mock file system.
-    MockSdk(resourceProvider: resourceProvider);
-    var sdkManager = DartSdkManager(convertPath(sdkRoot));
-    manager = ContextManagerImpl(
-      resourceProvider,
-      sdkManager,
-      analysisFilesGlobs,
-      InstrumentationService.NULL_SERVICE,
-    );
-    var logger = PerformanceLog(NullStringSink());
-    var scheduler = AnalysisDriverScheduler(logger);
-    callbacks = TestContextManagerCallbacks(
-        resourceProvider, sdkManager, logger, scheduler);
-    manager.callbacks = callbacks;
-  }
-
-  Map<String, List<Folder>> _packageMap(String contextPath) {
-    var folder = getFolder(contextPath);
-    var info = manager.getContextInfoFor(folder);
-    return info.analysisDriver.sourceFactory?.packageMap;
-  }
-}
-
-@reflectiveTest
-class ContextManagerWithOptionsTest extends ContextManagerTest {
-  String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
-
-  void deleteOptionsFile() {
-    deleteFile('$projPath/$optionsFileName');
-  }
-
-  Future<void> test_analysis_options_file_delete() async {
-    // Setup analysis options
-    newFile('$projPath/$optionsFileName', content: r'''
-embedded_libs:
-  "dart:foobar": "../sdk_ext/entry.dart"
-analyzer:
-  errors:
-    unused_local_variable: false
-linter:
-  rules:
-    - camel_case_types
-''');
-
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-
-    // Verify options were set.
-    expect(errorProcessors, hasLength(1));
-    expect(lints, hasLength(1));
-
-    // Remove options.
-    deleteOptionsFile();
-    await pumpEventQueue();
-
-    // Verify defaults restored.
-    expect(errorProcessors, isEmpty);
-    expect(lints, isEmpty);
-  }
-
-  @failingTest
-  Future<void> test_analysis_options_file_delete_with_embedder() async {
-    // This fails because the ContextBuilder doesn't pick up the strongMode
-    // flag from the embedder.yaml file.
-    // Setup _embedder.yaml.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/_embedder.yaml', content: r'''
-analyzer:
-  language:
-    enablePreviewDart2: true
-  errors:
-    missing_return: false
-linter:
-  rules:
-    - avoid_as
-''');
-
-    // Setup .packages file
-    newFile('$projPath/.packages', content: r'''
-test_pack:lib/''');
-
-    // Setup analysis options
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  errors:
-    unused_local_variable: false
-linter:
-  rules:
-    - camel_case_types
-''');
-
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-
-    // Verify options were set.
-    expect(errorProcessors, hasLength(2));
-    expect(lints, hasLength(2));
-
-    // Remove options.
-    deleteOptionsFile();
-    await pumpEventQueue();
-
-    // Verify defaults restored.
-    expect(lints, hasLength(1));
-    expect(lints.first, const TypeMatcher<AvoidAs>());
-    expect(errorProcessors, hasLength(1));
-    expect(getProcessor(missing_return).severity, isNull);
-  }
-
-  Future<void> test_analysis_options_include() async {
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    var sdkExtPath = '$projPath/sdk_ext';
-    newFile('$sdkExtPath/entry.dart');
-    var sdkExtSrcPath = '$projPath/sdk_ext/src';
-    newFile('$sdkExtSrcPath/part.dart');
-    // Setup analysis options file which includes another options file.
-    newFile('$projPath/$optionsFileName', content: r'''
-include: other_options.yaml
-''');
-    newFile('$projPath/other_options.yaml', content: r'''
-analyzer:
-  errors:
-    unused_local_variable: false
-linter:
-  rules:
-    - camel_case_types
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-    // Verify options were set.
-    expect(errorProcessors, hasLength(1));
-    expect(lints, hasLength(1));
-    expect(lints[0].name, 'camel_case_types');
-  }
-
-  Future<void> test_analysis_options_include_package() async {
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    var sdkExtPath = '$projPath/sdk_ext';
-    newFile('$sdkExtPath/entry.dart');
-    var sdkExtSrcPath = '$projPath/sdk_ext/src';
-    newFile('$sdkExtSrcPath/part.dart');
-    // Setup package
-    var booLibPosixPath = '/my/pkg/boo/lib';
-    newFile('$booLibPosixPath/other_options.yaml', content: r'''
-analyzer:
-  errors:
-    unused_local_variable: false
-linter:
-  rules:
-    - camel_case_types
-''');
-    // Setup analysis options file which includes another options file.
-    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
-        content: 'boo:${toUriStr(booLibPosixPath)}\n');
-    newFile('$projPath/$optionsFileName', content: r'''
-include: package:boo/other_options.yaml
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-    // Verify options were set.
-    expect(errorProcessors, hasLength(1));
-    expect(lints, hasLength(1));
-    expect(lints[0].name, 'camel_case_types');
-  }
-
-  @failingTest
-  Future<void> test_analysis_options_parse_failure() async {
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    var sdkExtPath = '$projPath/sdk_ext';
-    newFile('$sdkExtPath/entry.dart');
-    var sdkExtSrcPath = '$projPath/sdk_ext/src';
-    newFile('$sdkExtSrcPath/part.dart');
-    // Setup analysis options file with ignore list.
-    var optionsFilePath = newFile('$projPath/$optionsFileName', content: r'''
-;
-''').path;
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // Check that an error was produced.
-    TestNotificationManager notificationManager = callbacks.notificationManager;
-    var errors = notificationManager.recordedErrors;
-    expect(errors, hasLength(1));
-    expect(errors[errors.keys.first][optionsFilePath], hasLength(1));
-  }
-
-  Future<void> test_deleteRoot_hasAnalysisOptions() async {
-    newFile('$projPath/$optionsFileName');
-
-    // Add the root.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-
-    // Remove the root, with the analysis options file.
-    // No exceptions.
-    deleteFolder(projPath);
-    await pumpEventQueue();
-  }
-
-  @failingTest
-  Future<void> test_embedder_options() async {
-    // This fails because the ContextBuilder doesn't pick up the strongMode
-    // flag from the embedder.yaml file.
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    var sdkExtPath = '$projPath/sdk_ext';
-    newFile('$projPath/test', content: 'test.dart');
-    newFile('$sdkExtPath/entry.dart');
-    // Setup _embedder.yaml.
-    newFile('$libPath/_embedder.yaml', content: r'''
-embedded_libs:
-  "dart:foobar": "../sdk_ext/entry.dart"
-analyzer:
-  strong-mode: true
-  errors:
-    missing_return: false
-linter:
-  rules:
-    - avoid_as
-''');
-    // Setup .packages file
-    newFile('$projPath/.packages', content: r'''
-test_pack:lib/''');
-
-    // Setup analysis options
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  exclude:
-    - 'test/**'
-  errors:
-    unused_local_variable: false
-linter:
-  rules:
-    - camel_case_types
-''');
-
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-
-    // Confirm that one context was created.
-    var count = manager.numberOfContextsInAnalysisRoot(newFolder(projPath));
-    expect(count, equals(1));
-
-    // Verify options.
-    // * from `_embedder.yaml`:
-    // TODO(brianwilkerson) Figure out what to use in place of 'strongMode'.
-//    expect(analysisOptions.strongMode, isTrue);
-
-    // * verify tests are excluded
-    expect(
-        callbacks.currentContextFilePaths[projPath].keys,
-        unorderedEquals(
-            ['/my/proj/sdk_ext/entry.dart', '/my/proj/$optionsFileName']));
-
-    // Verify filter setup.
-    expect(errorProcessors, hasLength(2));
-
-    // * (embedder.)
-    expect(getProcessor(missing_return).severity, isNull);
-
-    // * (options.)
-    expect(getProcessor(unused_local_variable).severity, isNull);
-
-    // Verify lints.
-    var lintNames = lints.map((lint) => lint.name);
-
-    expect(
-        lintNames,
-        unorderedEquals([
-          'avoid_as' /* embedder */,
-          'camel_case_types' /* options */
-        ]));
-
-    // Sanity check embedder libs.
-    var source = sourceFactory.forUri('dart:foobar');
-    expect(source, isNotNull);
-    expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
-  }
-
-  Future<void> test_error_filter_analysis_option() async {
-    // Create files.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  errors:
-    unused_local_variable: ignore
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // Verify filter setup.
-    expect(errorProcessors, hasLength(1));
-    expect(getProcessor(unused_local_variable).severity, isNull);
-  }
-
-  Future<void> test_error_filter_analysis_option_multiple_filters() async {
-    // Create files.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  errors:
-    invalid_assignment: ignore
-    unused_local_variable: error
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // Verify filter setup.
-    expect(errorProcessors, hasLength(2));
-
-    expect(getProcessor(invalid_assignment_error).severity, isNull);
-    expect(getProcessor(unused_local_variable).severity, ErrorSeverity.ERROR);
-  }
-
-  Future<void> test_error_filter_analysis_option_synonyms() async {
-    // Create files.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  errors:
-    unused_local_variable: ignore
-    ambiguous_import: false
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // Verify filter setup.
-    expect(errorProcessors, isNotNull);
-    expect(errorProcessors, hasLength(2));
-  }
-
-  Future<void> test_error_filter_analysis_option_unpsecified() async {
-    // Create files.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-#  errors:
-#    unused_local_variable: ignore
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // Verify filter setup.
-    expect(errorProcessors, isEmpty);
-  }
-
-  Future<void> test_non_analyzable_files_not_considered() async {
-    // Set up project and get a reference to the driver.
-    manager.setRoots(<String>[projPath], <String>[]);
-    var projectFolder = newFolder(projPath);
-    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, hasLength(1));
-
-    // Add the driver to the manager so that it will receive the events.
-    manager.driverMap[projectFolder] = drivers[0];
-
-    // Ensure adding a file that shouldn't be analyzed is not picked up.
-    newFile('$projPath/test.txt');
-    await pumpEventQueue();
-    expect(drivers[0].hasFilesToAnalyze, false);
-
-    // Ensure modifying a file that shouldn't be analyzed is not picked up.
-    modifyFile('$projPath/test.txt', 'new content');
-    await pumpEventQueue();
-    expect(drivers[0].hasFilesToAnalyze, false);
-  }
-
-  @failingTest
-  Future<void> test_optionsFile_update_strongMode() async {
-    // It appears that this fails because we are not correctly updating the
-    // analysis options in the driver when the file is modified.
-    //return super.test_optionsFile_update_strongMode();
-    // After a few other changes, the test now times out on my machine, so I'm
-    // disabling it in order to prevent it from being flaky.
-    _fail('Test times out');
-    var file = newFile('$projPath/bin/test.dart', content: r'''
-main() {
-  var paths = <int>[];
-  var names = <String>[];
-  paths.addAll(names.map((s) => s.length));
-}
-''');
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  strong-mode: false
-''');
-    // Create the context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    await pumpEventQueue();
-
-    var result = await callbacks.currentDriver.getResult(file.path);
-
-    // Not strong mode - both in the context and the SDK context.
-//    AnalysisContext sdkContext = sourceFactory.dartSdk.context;
-    // TODO(brianwilkerson) Figure out whether there is an option other than
-    // 'strongMode' that will apply to the SDK context.
-//    expect(analysisOptions.strongMode, isFalse);
-//    expect(sdkContext.analysisOptions.strongMode, isFalse);
-    expect(result.errors, isEmpty);
-
-    // Update the options file - turn on 'strong-mode'.
-    modifyFile('$projPath/$optionsFileName', r'''
-analyzer:
-  strong-mode: true
-''');
-    await pumpEventQueue();
-
-    // Strong mode - both in the context and the SDK context.
-    result = await callbacks.currentDriver.getResult(file.path);
-
-    // Not strong mode - both in the context and the SDK context.
-//    sdkContext = sourceFactory.dartSdk.context;
-    // TODO(brianwilkerson) Figure out whether there is an option other than
-    // 'strongMode' that will apply to the SDK context.
-//    expect(analysisOptions.strongMode, isTrue);
-//    expect(sdkContext.analysisOptions.strongMode, isTrue);
-    // The code is strong-mode clean.
-    // Verify that TypeSystem was reset.
-    expect(result.errors, isEmpty);
-  }
-
-  @failingTest
-  Future<void> test_path_filter_analysis_option() async {
-    // This fails because we're not analyzing the analysis options file.
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    newFile('$libPath/nope.dart');
-    var sdkExtPath = '$projPath/sdk_ext';
-    newFile('$sdkExtPath/entry.dart');
-    var sdkExtSrcPath = '$projPath/sdk_ext/src';
-    newFile('$sdkExtSrcPath/part.dart');
-    // Setup analysis options file with ignore list.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  exclude:
-    - lib/nope.dart
-    - 'sdk_ext/**'
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // Verify that analysis options was parsed and the ignore patterns applied.
-    var projectFolder = newFolder(projPath);
-    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, hasLength(1));
-    var driver = drivers[0];
-    expect(
-        driver.addedFiles,
-        unorderedEquals(
-            ['/my/proj/lib/main.dart', '/my/proj/$optionsFileName']));
-  }
-
-  Future<void> test_path_filter_child_contexts_option() async {
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    newFile('$libPath/pubspec.yaml', content: r'''
-name: foobar
-''');
-    var otherLibPath = '$projPath/other_lib';
-    newFile('$otherLibPath/entry.dart');
-    newFile('$otherLibPath/pubspec.yaml', content: r'''
-name: other_lib
-''');
-    // Setup analysis options file with ignore list that ignores the 'other_lib'
-    // directory by name.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  exclude:
-    - 'other_lib'
-''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-    // Verify that the context in other_lib wasn't created and that the
-    // context in lib was created.
-    var projectFolder = newFolder(projPath);
-    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, hasLength(2));
-    expect(drivers[0].name, equals(convertPath('/my/proj')));
-    expect(drivers[1].name, equals(convertPath('/my/proj/lib')));
-  }
-
-  Future<void>
-      test_path_filter_recursive_wildcard_child_contexts_option() async {
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    newFile('$libPath/pubspec.yaml', content: r'''
-  name: foobar
-  ''');
-    var otherLibPath = '$projPath/other_lib';
-    newFile('$otherLibPath/entry.dart');
-    newFile('$otherLibPath/pubspec.yaml', content: r'''
-  name: other_lib
-  ''');
-    // Setup analysis options file with ignore list that ignores 'other_lib'
-    // and all descendants.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  exclude:
-    - 'other_lib/**'
-  ''');
-    // Setup context.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    // Verify that the context in other_lib wasn't created and that the
-    // context in lib was created.
-    var projectFolder = newFolder(projPath);
-    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, hasLength(2));
-    expect(drivers[0].name, equals(convertPath('/my/proj')));
-    expect(drivers[1].name, equals(convertPath('/my/proj/lib')));
-  }
-
-  Future<void> test_path_filter_wildcard_child_contexts_option() async {
-    // Create files.
-    var libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
-    newFile('$libPath/main.dart');
-    newFile('$libPath/pubspec.yaml', content: r'''
-name: foobar
-''');
-    var otherLibPath = '$projPath/other_lib';
-    newFile('$otherLibPath/entry.dart');
-    newFile('$otherLibPath/pubspec.yaml', content: r'''
-name: other_lib
-''');
-    // Setup analysis options file with ignore list that ignores 'other_lib'
-    // and all immediate children.
-    newFile('$projPath/$optionsFileName', content: r'''
-analyzer:
-  exclude:
-    - 'other_lib/*'
-''');
-    // Setup context / driver.
-    manager.setRoots(<String>[projPath], <String>[]);
-
-    var projectFolder = newFolder(projPath);
-    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
-    expect(drivers, hasLength(2));
-    expect(drivers[0].name, equals(convertPath('/my/proj')));
-    expect(drivers[1].name, equals(convertPath('/my/proj/lib')));
-  }
-
-  void test_setRoots_nested_excludedByOuter() {
-    var project = convertPath('/project');
-    var projectPubspec = convertPath('$project/pubspec.yaml');
-    var example = convertPath('$project/example');
-    var examplePubspec = convertPath('$example/pubspec.yaml');
-    // create files
-    newFile(projectPubspec, content: 'name: project');
-    newFile(examplePubspec, content: 'name: example');
-    newFile('$project/$optionsFileName', content: r'''
-analyzer:
-  exclude:
-    - 'example'
-''');
-    manager.setRoots(<String>[project, example], <String>[]);
-    // verify
-    {
-      var rootInfo = manager.rootInfo;
-      expect(rootInfo.children, hasLength(1));
-      {
-        var projectInfo = rootInfo.children[0];
-        expect(projectInfo.folder.path, project);
-        expect(projectInfo.children, hasLength(1));
-        {
-          var exampleInfo = projectInfo.children[0];
-          expect(exampleInfo.folder.path, example);
-          expect(exampleInfo.children, isEmpty);
-        }
-      }
-    }
-    expect(callbacks.currentContextRoots, hasLength(2));
-    expect(callbacks.currentContextRoots, unorderedEquals([project, example]));
-  }
-
-  void test_setRoots_nested_excludedByOuter_deep() {
-    var a = convertPath('/a');
-    var c = convertPath('$a/b/c');
-    var aPubspec = convertPath('$a/pubspec.yaml');
-    var cPubspec = convertPath('$c/pubspec.yaml');
-    // create files
-    newFile(aPubspec, content: 'name: aaa');
-    newFile(cPubspec, content: 'name: ccc');
-    newFile('$a/$optionsFileName', content: r'''
-analyzer:
-  exclude:
-    - 'b**'
-''');
-    manager.setRoots(<String>[a, c], <String>[]);
-    // verify
-    {
-      var rootInfo = manager.rootInfo;
-      expect(rootInfo.children, hasLength(1));
-      {
-        var aInfo = rootInfo.children[0];
-        expect(aInfo.folder.path, a);
-        expect(aInfo.children, hasLength(1));
-        {
-          var cInfo = aInfo.children[0];
-          expect(cInfo.folder.path, c);
-          expect(cInfo.children, isEmpty);
-        }
-      }
-    }
-    expect(callbacks.currentContextRoots, hasLength(2));
-    expect(callbacks.currentContextRoots, unorderedEquals([a, c]));
-  }
-
-  Future<void> test_watchEvents() async {
-    var libPath = newFolder('$projPath/${ContextManagerTest.LIB_NAME}').path;
-    manager.setRoots(<String>[projPath], <String>[]);
-    newFile('$libPath/main.dart');
-    await Future.delayed(Duration(milliseconds: 1));
-    expect(callbacks.watchEvents, hasLength(1));
-  }
-}
-
-class TestContextManagerCallbacks extends ContextManagerCallbacks {
-  /// Source of timestamps stored in [currentContextFilePaths].
-  int now = 0;
-
-  /// The analysis driver that was created.
-  AnalysisDriver currentDriver;
-
-  /// A table mapping paths to the analysis driver associated with that path.
-  Map<String, AnalysisDriver> driverMap = <String, AnalysisDriver>{};
-
-  /// Map from context to the timestamp when the context was created.
-  Map<String, int> currentContextTimestamps = <String, int>{};
-
-  /// Map from context to (map from file path to timestamp of last event).
-  final Map<String, Map<String, int>> currentContextFilePaths =
-      <String, Map<String, int>>{};
-
-  /// A map from the paths of contexts to a set of the sources that should be
-  /// explicitly analyzed in those contexts.
-  final Map<String, Set<Source>> currentContextSources =
-      <String, Set<Source>>{};
-
-  /// Resource provider used for this test.
-  final ResourceProvider resourceProvider;
-
-  /// The manager managing the SDKs.
-  final DartSdkManager sdkManager;
-
-  /// The logger used by the scheduler and the driver.
-  final PerformanceLog logger;
-
-  /// The scheduler used by the driver.
-  final AnalysisDriverScheduler scheduler;
-
-  /// The list of `flushedFiles` in the last [removeContext] invocation.
-  List<String> lastFlushedFiles;
-
-  /// The watch events that have been broadcast.
-  List<WatchEvent> watchEvents = <WatchEvent>[];
-
-  @override
-  AbstractNotificationManager notificationManager = TestNotificationManager();
-
-  TestContextManagerCallbacks(
-      this.resourceProvider, this.sdkManager, this.logger, this.scheduler);
-
-  /// Return the current set of analysis options.
-  AnalysisOptions get analysisOptions => currentDriver?.analysisOptions;
-
-  /// Return the paths to the context roots that currently exist.
-  Iterable<String> get currentContextRoots {
-    return currentContextTimestamps.keys;
-  }
-
-  /// Return the paths to the files being analyzed in the current context root.
-  Iterable<String> get currentFilePaths {
-    if (currentDriver == null) {
-      return <String>[];
-    }
-    return currentDriver.addedFiles;
-  }
-
-  /// Return the current source factory.
-  SourceFactory get sourceFactory => currentDriver?.sourceFactory;
-
-  @override
-  AnalysisDriver addAnalysisDriver(Folder folder, ContextRoot contextRoot) {
-    var path = folder.path;
-    expect(currentContextRoots, isNot(contains(path)));
-    expect(contextRoot, isNotNull);
-    expect(contextRoot.root, path);
-    currentContextTimestamps[path] = now;
-
-    var builder = createContextBuilder(folder);
-    builder.analysisDriverScheduler = scheduler;
-    builder.byteStore = MemoryByteStore();
-    builder.performanceLog = logger;
-    builder.fileContentOverlay = FileContentOverlay();
-    var workspace = ContextBuilder.createWorkspace(
-      resourceProvider: resourceProvider,
-      options: builder.builderOptions,
-      rootPath: path,
-    );
-    currentDriver = builder.buildDriver(contextRoot, workspace);
-
-    driverMap[path] = currentDriver;
-    currentDriver.exceptions.listen((ExceptionResult result) {
-      AnalysisEngine.instance.instrumentationService.logException(
-          CaughtException.withMessage('Analysis failed: ${result.filePath}',
-              result.exception.exception, result.exception.stackTrace));
-    });
-    return currentDriver;
-  }
-
-  @override
-  void afterContextRefresh() {}
-
-  @override
-  void afterWatchEvent(WatchEvent event) {}
-
-  @override
-  void analysisOptionsUpdated(AnalysisDriver driver) {}
-
-  @override
-  void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
-    var driver = driverMap[contextFolder.path];
-    if (driver != null) {
-      changeSet.addedFiles.forEach((source) {
-        driver.addFile(source);
-      });
-      changeSet.changedFiles.forEach((source) {
-        driver.changeFile(source);
-      });
-      changeSet.removedFiles.forEach((source) {
-        driver.removeFile(source);
-      });
-    }
-  }
-
-  @override
-  void applyFileRemoved(AnalysisDriver driver, String file) {
-    driver.removeFile(file);
-  }
-
-  void assertContextFiles(String contextPath, List<String> expectedFiles) {
-    expect(getCurrentFilePaths(contextPath), unorderedEquals(expectedFiles));
-  }
-
-  void assertContextPaths(List<String> expected) {
-    expect(currentContextRoots, unorderedEquals(expected));
-  }
-
-  @override
-  void broadcastWatchEvent(WatchEvent event) {
-    watchEvents.add(event);
-  }
-
-  @override
-  ContextBuilder createContextBuilder(Folder folder) {
-    var builderOptions = ContextBuilderOptions();
-    var builder = ContextBuilder(resourceProvider, sdkManager, null,
-        options: builderOptions);
-    return builder;
-  }
-
-  /// Return the paths to the files being analyzed in the current context root.
-  Iterable<Source> currentFileSources(String contextPath) {
-    if (currentDriver == null) {
-      return <Source>[];
-    }
-    var driver = driverMap[contextPath];
-    var sourceFactory = driver.sourceFactory;
-    return driver.addedFiles.map((String path) {
-      var file = resourceProvider.getFile(path);
-      var source = file.createSource();
-      var uri = sourceFactory.restoreUri(source);
-      return file.createSource(uri);
-    });
-  }
-
-  /// Return the paths to the files being analyzed in the current context root.
-  Iterable<String> getCurrentFilePaths(String contextPath) {
-    if (currentDriver == null) {
-      return <String>[];
-    }
-    return driverMap[contextPath].addedFiles;
-  }
-
-  @override
-  void removeContext(Folder folder, List<String> flushedFiles) {
-    var path = folder.path;
-    expect(currentContextRoots, contains(path));
-    currentContextTimestamps.remove(path);
-    currentContextFilePaths.remove(path);
-    currentContextSources.remove(path);
-    lastFlushedFiles = flushedFiles;
-  }
-}
-
-class _MockSource implements Source {
-  @override
-  final String fullName;
-
-  _MockSource(this.fullName);
-
-  @override
-  dynamic noSuchMethod(Invocation invocation) {
-    throw StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-}
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 06c2e37..94445ff 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -14,9 +14,11 @@
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
+import 'package:analyzer/src/test_utilities/package_config_file_builder.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
+import 'package:meta/meta.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -303,31 +305,157 @@
 
 @reflectiveTest
 class AnalysisDomainTest extends AbstractAnalysisTest {
-  Map<String, List<AnalysisError>> filesErrors = {};
+  final Map<String, List<AnalysisError>> filesErrors = {};
+
+  /// The files for which `analysis.flushResults` was received.
+  final List<String> flushResults = [];
+
+  String get testFilePath => '$testPackageLibPath/test.dart';
+
+  String get testPackageLibPath => '$testPackageRootPath/lib';
+
+  String get testPackageRootPath => '$workspaceRootPath/test';
+
+  String get workspaceRootPath => '/home';
 
   void assertHasErrors(String path) {
-    expect(filesErrors[path], isNotEmpty);
+    path = convertPath(path);
+    expect(filesErrors[path], isNotEmpty, reason: path);
   }
 
   void assertNoErrors(String path) {
-    expect(filesErrors[path], isEmpty);
+    path = convertPath(path);
+    expect(filesErrors[path], isEmpty, reason: path);
   }
 
   void assertNoErrorsNotification(String path) {
-    expect(filesErrors[path], isNull);
+    path = convertPath(path);
+    expect(filesErrors[path], isNull, reason: path);
+  }
+
+  void forgetReceivedErrors() {
+    filesErrors.clear();
   }
 
   @override
   void processNotification(Notification notification) {
+    if (notification.event == ANALYSIS_NOTIFICATION_FLUSH_RESULTS) {
+      var decoded = AnalysisFlushResultsParams.fromNotification(notification);
+      flushResults.addAll(decoded.files);
+    }
     if (notification.event == ANALYSIS_NOTIFICATION_ERRORS) {
       var decoded = AnalysisErrorsParams.fromNotification(notification);
       filesErrors[decoded.file] = decoded.errors;
     }
   }
 
-  Future<void> test_fileSystem_addFile_excluded() async {
-    var a_path = convertPath('$projectPath/lib/a.dart');
-    var b_path = convertPath('$projectPath/lib/b.dart');
+  Future<void> test_fileSystem_addFile_analysisOptions() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    _createFilesWithErrors([a_path, b_path]);
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // Both a.dart and b.dart are analyzed.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path, b_path],
+      notAnalyzed: [],
+    );
+
+    // Write the options file that excludes b.dart
+    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
+analyzer:
+  exclude:
+    - lib/b.dart
+''');
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // Errors for all files were flushed, and only a.dart is reported again.
+    _assertFlushedResults([a_path, b_path]);
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [b_path],
+    );
+  }
+
+  Future<void> test_fileSystem_addFile_analysisOptions_analysis() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var options_path = '$testPackageRootPath/analysis_options.yaml';
+
+    newFile(a_path, content: 'error');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // a.dart was analyzed
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [options_path],
+    );
+
+    // Add a non-Dart file that we know how to analyze.
+    newFile(options_path, content: '''
+analyzer:
+  error:
+''');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // Both files were analyzed.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path, options_path],
+      notAnalyzed: [],
+    );
+  }
+
+  Future<void> test_fileSystem_addFile_androidManifestXml() async {
+    var path = '$testPackageRootPath/AndroidManifest.xml';
+
+    newFile('$testPackageLibPath/a.dart', content: '');
+
+    newFile('$testPackageRootPath/analysis_options.yaml', content: '''
+analyzer:
+  optional-checks:
+    chrome-os-manifest-checks: true
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+
+    newFile(path, content: '<manifest/>');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // No touch-screen.
+    assertHasErrors(path);
+  }
+
+  Future<void> test_fileSystem_addFile_dart() async {
+    var a_path = '$testPackageLibPath/a.dart';
+
+    // We have to create the folder, otherwise there is nothing to watch.
+    newFolder(testPackageLibPath);
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We don't have a.dart yet.
+    assertNoErrorsNotification(a_path);
+
+    _createFilesWithErrors([a_path]);
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We created a.dart, so it should be analyzed.
+    assertHasErrors(a_path);
+  }
+
+  Future<void> test_fileSystem_addFile_dart_excluded() async {
+    var a_path = '$projectPath/lib/a.dart';
+    var b_path = '$projectPath/lib/b.dart';
 
     newFile('$projectPath/analysis_options.yaml', content: r'''
 analyzer:
@@ -360,11 +488,267 @@
     assertNoErrors(b_path);
   }
 
-  Future<void> test_fileSystem_changeFile_excluded() async {
-    var a_path = convertPath('$projectPath/lib/a.dart');
-    var b_path = convertPath('$projectPath/lib/b.dart');
+  Future<void> test_fileSystem_addFile_dotPackagesFile() async {
+    var aaaLibPath = '/packages/aaa/lib';
+    var a_path = '$aaaLibPath/a.dart';
 
-    newFile('$projectPath/analysis_options.yaml', content: r'''
+    newFile(a_path, content: '''
+class A {}
+''');
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We cannot resolve `package:aaa/a.dart`
+    assertHasErrors(testFilePath);
+
+    // Write `.packages`, recreate analysis contexts.
+    newFile('$testPackageRootPath/.packages', content: '''
+aaa:${toUriStr(aaaLibPath)}
+''');
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_fileSystem_addFile_fixDataYaml() async {
+    var path = '$testPackageLibPath/fix_data.yaml';
+
+    newFile('$testPackageLibPath/a.dart', content: '');
+
+    // Make sure that it is a package.
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder(),
+    );
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+
+    // No `fix_data.yaml` to analyze yet.
+    assertNoErrorsNotification(path);
+
+    // Create it, will be analyzed.
+    newFile(path, content: '0: 1');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // And it has errors.
+    assertHasErrors(path);
+
+    // We don't recreate analysis contexts.
+    _assertFlushedResults([]);
+  }
+
+  Future<void> test_fileSystem_addFile_packageConfigJsonFile() async {
+    var aaaRootPath = '/packages/aaa';
+    var a_path = '$aaaRootPath/lib/a.dart';
+
+    newFile(a_path, content: '''
+class A {}
+''');
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We cannot resolve `package:aaa/a.dart`
+    assertHasErrors(testFilePath);
+
+    // Write `package_config.json`, recreate analysis contexts.
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
+    );
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_fileSystem_addFile_pubspec_analysis() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var pubspec_path = '$testPackageRootPath/pubspec.yaml';
+
+    newFile(a_path, content: 'error');
+
+    // Write an empty file to force a new analysis context.
+    // We look for `pubspec.yaml` files only in analysis context roots.
+    newFile('$testPackageRootPath/analysis_options.yaml', content: '');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // a.dart was analyzed
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [pubspec_path],
+    );
+
+    // Add a non-Dart file that we know how to analyze.
+    newFile(pubspec_path, content: '''
+name: sample
+dependencies: true
+''');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // Both files were analyzed.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path, pubspec_path],
+      notAnalyzed: [],
+    );
+  }
+
+  Future<void> test_fileSystem_addFile_unrelated() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var unrelated_path = '$testPackageRootPath/unrelated.txt';
+
+    newFile(a_path, content: 'error');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // a.dart was analyzed
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [unrelated_path],
+    );
+
+    // Add an unrelated file, no analysis.
+    newFile(unrelated_path, content: 'anything');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // No analysis.
+    _assertFlushedResults([]);
+    _assertAnalyzedFiles(hasErrors: [], notAnalyzed: [a_path]);
+  }
+
+  Future<void> test_fileSystem_changeFile_analysisOptions() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+    var c_path = '$testPackageLibPath/c.dart';
+
+    _createFilesWithErrors([a_path, b_path, c_path]);
+
+    // Exclude b.dart from analysis.
+    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
+analyzer:
+  exclude:
+    - lib/b.dart
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // Only a.dart is analyzed, because b.dart is excluded.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path, c_path],
+      notAnalyzed: [b_path],
+    );
+
+    // Exclude c.dart from analysis.
+    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
+analyzer:
+  exclude:
+    - lib/c.dart
+''');
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // Errors for all files were flushed, a.dart and b.dart analyzed.
+    _assertFlushedResults([a_path, c_path]);
+    _assertAnalyzedFiles(
+      hasErrors: [a_path, b_path],
+      notAnalyzed: [c_path],
+    );
+  }
+
+  Future<void> test_fileSystem_changeFile_androidManifestXml() async {
+    var path = '$testPackageRootPath/AndroidManifest.xml';
+
+    newFile('$testPackageLibPath/a.dart', content: '');
+
+    // Has an error - no touch screen.
+    newFile(path, content: '<manifest/>');
+
+    newFile('$testPackageRootPath/analysis_options.yaml', content: '''
+analyzer:
+  optional-checks:
+    chrome-os-manifest-checks: true
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+
+    // Forget and check that we did.
+    forgetReceivedErrors();
+    assertNoErrorsNotification(path);
+
+    // Update the file, so analyze it.
+    newFile(path, content: '<manifest/>');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // An error was reports.
+    assertHasErrors(path);
+  }
+
+  Future<void> test_fileSystem_changeFile_dart() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    newFile(a_path, content: r'''
+class A2 {}
+''');
+
+    newFile(b_path, content: r'''
+import 'a.dart';
+void f(A a) {}
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    assertNoErrors(a_path);
+    assertHasErrors(b_path);
+    forgetReceivedErrors();
+
+    // Update a.dart so that b.dart has no error.
+    newFile(a_path, content: 'class A {}');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // The update of a.dart fixed the error in b.dart
+    assertNoErrors(a_path);
+    assertNoErrors(b_path);
+  }
+
+  Future<void> test_fileSystem_changeFile_dart_excluded() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
 analyzer:
   exclude:
     - "**/a.dart"
@@ -379,7 +763,7 @@
 void f(A a) {}
 ''');
 
-    createProject();
+    setRoots(included: [workspaceRootPath], excluded: []);
     await pumpEventQueue();
     await server.onAnalysisComplete;
 
@@ -399,11 +783,180 @@
     assertNoErrors(b_path);
   }
 
-  Future<void> test_fileSystem_deleteFile_excluded() async {
-    var a_path = convertPath('$projectPath/lib/a.dart');
-    var b_path = convertPath('$projectPath/lib/b.dart');
+  Future<void> test_fileSystem_changeFile_dotPackagesFile() async {
+    var aaaLibPath = '/packages/aaa/lib';
+    var a_path = '$aaaLibPath/a.dart';
 
-    newFile('$projectPath/analysis_options.yaml', content: r'''
+    newFile(a_path, content: '''
+class A {}
+''');
+
+    // Write `.packages` empty, without `package:aaa`.
+    newFile('$testPackageRootPath/.packages', content: '');
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We cannot resolve `package:aaa/a.dart`
+    assertHasErrors(testFilePath);
+
+    // Write `.packages`, recreate analysis contexts.
+    newFile('$testPackageRootPath/.packages', content: '''
+aaa:${toUriStr(aaaLibPath)}
+''');
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_fileSystem_changeFile_fixDataYaml() async {
+    var path = '$testPackageLibPath/fix_data.yaml';
+
+    newFile('$testPackageLibPath/a.dart', content: '');
+
+    // Make sure that it is a package.
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder(),
+    );
+
+    // This file has an error.
+    newFile(path, content: '0: 1');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+
+    // The file was analyzed.
+    assertHasErrors(path);
+
+    // Replace with the context that does not have errors.
+    newFile(path, content: r'''
+version: 1
+transforms: []
+''');
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // And it has errors.
+    assertNoErrors(path);
+
+    // We don't recreate analysis contexts.
+    _assertFlushedResults([]);
+  }
+
+  Future<void> test_fileSystem_changeFile_packageConfigJsonFile() async {
+    var aaaRootPath = '/packages/aaa';
+    var a_path = '$aaaRootPath/lib/a.dart';
+
+    newFile(a_path, content: '''
+class A {}
+''');
+
+    // Write the empty file, without `package:aaa`.
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder(),
+    );
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We cannot resolve `package:aaa/a.dart`
+    assertHasErrors(testFilePath);
+
+    // Write `package_config.json`, recreate analysis contexts.
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
+    );
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_fileSystem_deleteFile_analysisOptions() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    _createFilesWithErrors([a_path, b_path]);
+
+    // Exclude b.dart from analysis.
+    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
+analyzer:
+  exclude:
+    - lib/b.dart
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // Only a.dart is analyzed, because b.dart is excluded.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [b_path],
+    );
+
+    // Delete the options file.
+    deleteFile('$testPackageRootPath/analysis_options.yaml');
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // Errors for a.dart were flushed, a.dart and b.dart analyzed.
+    _assertFlushedResults([a_path]);
+    _assertAnalyzedFiles(
+      hasErrors: [a_path, b_path],
+      notAnalyzed: [],
+    );
+  }
+
+  Future<void> test_fileSystem_deleteFile_dart() async {
+    var a_path = '$testPackageLibPath/a.dart';
+
+    _createFilesWithErrors([a_path]);
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // a.dart was analyzed
+    assertHasErrors(a_path);
+    forgetReceivedErrors();
+
+    deleteFile(a_path);
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We deleted a.dart, its errors should be flushed.
+    _assertFlushedResults([a_path]);
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_fileSystem_deleteFile_dart_excluded() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    newFile('$testPackageRootPath/analysis_options.yaml', content: r'''
 analyzer:
   exclude:
     - "**/a.dart"
@@ -418,7 +971,7 @@
 void f(A a) {}
 ''');
 
-    createProject();
+    setRoots(included: [workspaceRootPath], excluded: []);
     await pumpEventQueue();
     await server.onAnalysisComplete;
 
@@ -436,27 +989,337 @@
     assertHasErrors(b_path);
   }
 
-  Future<void> test_setRoots_packages() {
-    // prepare package
-    var pkgFile = newFile('/packages/pkgA/libA.dart', content: '''
-library lib_a;
+  Future<void> test_fileSystem_deleteFile_dotPackagesFile() async {
+    var aaaLibPath = '/packages/aaa/lib';
+    var a_path = '$aaaLibPath/a.dart';
+
+    newFile(a_path, content: '''
 class A {}
-''').path;
-    newFile('/project/.packages',
-        content: 'pkgA:${toUriStr('/packages/pkgA')}');
-    addTestFile('''
-import 'package:pkgA/libA.dart';
-void f(A a) {
-}
 ''');
+
+    newFile('$testPackageRootPath/.packages', content: '''
+aaa:${toUriStr(aaaLibPath)}
+''');
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // Write `.packages`, recreate analysis contexts.
+    deleteFile('$testPackageRootPath/.packages');
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We cannot resolve `package:aaa/a.dart`
+    assertHasErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_fileSystem_deleteFile_packageConfigJsonFile() async {
+    var aaaRootPath = '/packages/aaa';
+    var a_path = '$aaaRootPath/lib/a.dart';
+
+    newFile(a_path, content: '''
+class A {}
+''');
+
+    // Write the empty file, without `package:aaa`.
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
+    );
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // Delete `package_config.json`, recreate analysis contexts.
+    deleteFile(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+    );
+
+    await pumpEventQueue();
+    await server.onAnalysisComplete;
+
+    // We cannot resolve 'package:aaa/a.dart', so errors.
+    assertHasErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_setRoots_dotPackagesFile() async {
+    var aaaLibPath = '/packages/aaa/lib';
+    var a_path = '$aaaLibPath/a.dart';
+
+    newFile(a_path, content: '''
+class A {}
+''');
+
+    newFile('$testPackageRootPath/.packages', content: '''
+aaa:${toUriStr(aaaLibPath)}
+''');
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
     // create project and wait for analysis
-    createProject();
-    return waitForTasksFinished().then((_) {
-      // if 'package:pkgA/libA.dart' was resolved, then there are no errors
-      expect(filesErrors[testFile], isEmpty);
-      // errors are not reported for packages
-      expect(filesErrors[pkgFile], isNull);
-    });
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  Future<void> test_setRoots_includedFile() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    _createFilesWithErrors([a_path, b_path]);
+
+    setRoots(included: [a_path], excluded: []);
+
+    // Only a.dart is included, so b.dart is not analyzed.
+    await server.onAnalysisComplete;
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [b_path],
+    );
+  }
+
+  Future<void> test_setRoots_includedFile_setRoots() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    _createFilesWithErrors([a_path, b_path]);
+
+    // Include only single file.
+    setRoots(included: [a_path], excluded: []);
+    await server.onAnalysisComplete;
+
+    // So, only a.dart is analyzed, and b.dart is not.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [b_path],
+    );
+
+    // Include the folder that contains both a.dart and b.dart
+    setRoots(included: [testPackageRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // So, both a.dart and b.dart are analyzed.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path, b_path],
+      notAnalyzed: [],
+    );
+  }
+
+  Future<void> test_setRoots_includedFileFolder() async {
+    var includedFile = '$testPackageLibPath/a.dart';
+    var includedFolder = '$testPackageLibPath/foo';
+    var includedFolderFile1 = '$includedFolder/1.dart';
+    var includedFolderFile2 = '$includedFolder/2.dart';
+    var notIncludedFile = '$testPackageLibPath/b.dart';
+
+    _createFilesWithErrors([
+      includedFile,
+      includedFolderFile1,
+      includedFolderFile2,
+      notIncludedFile,
+    ]);
+
+    setRoots(included: [includedFile, includedFolder], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We can combine a file, and a folder as included paths.
+    // And the file that is not in there is not analyzed.
+    _assertAnalyzedFiles(hasErrors: [
+      includedFile,
+      includedFolderFile1,
+      includedFolderFile2,
+    ], notAnalyzed: [
+      notIncludedFile,
+    ]);
+  }
+
+  Future<void> test_setRoots_includedFolder_analysisOptions_exclude() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var b_path = '$testPackageLibPath/b.dart';
+
+    newOptionsFile(testPackageRootPath, content: '''
+analyzer:
+  exclude:
+    - "**/b.dart"
+''');
+
+    _createFilesWithErrors([a_path, b_path]);
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+
+    // b.dart is excluded using the options file.
+    await server.onAnalysisComplete;
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [b_path],
+    );
+  }
+
+  @FailingTest(reason: 'Not implemented in ContextLocator')
+  Future<void> test_setRoots_includedFolder_excludedFile() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var excluded_path = '$testPackageRootPath/excluded/b.dart';
+
+    _createFilesWithErrors([a_path, excluded_path]);
+
+    setRoots(
+      included: [workspaceRootPath],
+      excluded: [excluded_path],
+    );
+    await server.onAnalysisComplete;
+
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [excluded_path],
+    );
+  }
+
+  Future<void> test_setRoots_includedFolder_excludedFolder() async {
+    var a_path = '$testPackageLibPath/a.dart';
+    var excluded_path = '$testPackageRootPath/excluded/b.dart';
+
+    _createFilesWithErrors([a_path, excluded_path]);
+
+    setRoots(
+      included: [workspaceRootPath],
+      excluded: ['$testPackageRootPath/excluded'],
+    );
+    await server.onAnalysisComplete;
+
+    // a.dart is analyzed, but b.dart is in the excluded folder.
+    _assertAnalyzedFiles(
+      hasErrors: [a_path],
+      notAnalyzed: [excluded_path],
+    );
+  }
+
+  Future<void> test_setRoots_notDartFile_androidManifestXml() async {
+    var path = '$testPackageRootPath/AndroidManifest.xml';
+
+    newFile('$testPackageLibPath/a.dart', content: '');
+
+    newFile('$testPackageRootPath/analysis_options.yaml', content: '''
+analyzer:
+  optional-checks:
+    chrome-os-manifest-checks: true
+''');
+
+    newFile(path, content: '<manifest/>');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+
+    // No touch-screen.
+    assertHasErrors(path);
+  }
+
+  Future<void> test_setRoots_notDartFile_fixDataYaml() async {
+    var path = '$testPackageLibPath/fix_data.yaml';
+
+    // Make sure that it is a package.
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder(),
+    );
+
+    // So, `lib/fix_data.yaml` will be analyzed.
+    newFile(path, content: '0: 1');
+
+    setRoots(included: [workspaceRootPath], excluded: []);
+
+    assertHasErrors(path);
+  }
+
+  Future<void> test_setRoots_packageConfigJsonFile() async {
+    var aaaRootPath = '/packages/aaa';
+    var a_path = '$aaaRootPath/lib/a.dart';
+
+    newFile(a_path, content: '''
+class A {}
+''');
+
+    writePackageConfig(
+      '$testPackageRootPath/.dart_tool/package_config.json',
+      PackageConfigFileBuilder()..add(name: 'aaa', rootPath: aaaRootPath),
+    );
+
+    newFile(testFilePath, content: '''
+import 'package:aaa/a.dart';
+void f(A a) {}
+''');
+
+    // create project and wait for analysis
+    setRoots(included: [workspaceRootPath], excluded: []);
+    await server.onAnalysisComplete;
+
+    // We have `A` in 'package:aaa/a.dart', so no errors.
+    assertNoErrors(testFilePath);
+
+    // errors are not reported for packages
+    assertNoErrorsNotification(a_path);
+  }
+
+  void writePackageConfig(String path, PackageConfigFileBuilder config) {
+    newFile(path, content: config.toContent(toUriStr: toUriStr));
+  }
+
+  void _assertAnalyzedFiles({
+    @required List<String> hasErrors,
+    @required List<String> notAnalyzed,
+  }) {
+    for (var path in hasErrors) {
+      assertHasErrors(path);
+    }
+
+    for (var path in notAnalyzed) {
+      assertNoErrorsNotification(path);
+    }
+
+    filesErrors.clear();
+  }
+
+  void _assertFlushedResults(List<String> paths) {
+    var convertedPaths = paths.map(convertPath).toList();
+    expect(flushResults, convertedPaths);
+    flushResults.clear();
+  }
+
+  /// Create files with a content that has a compile time error.
+  /// So, when analyzed, these files will satisfy [assertHasErrors].
+  void _createFilesWithErrors(List<String> paths) {
+    for (var path in paths) {
+      newFile(path, content: 'error');
+    }
   }
 }
 
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index ec7ad30..7173df2 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -266,7 +266,7 @@
     assertValidId(result2.id);
 
     // Wait for all processing to be complete
-    await analysisHandler.server.analysisDriverScheduler.waitForIdle();
+    await analysisHandler.server.onAnalysisComplete;
     await pumpEventQueue();
 
     // Assert that first request has been aborted
@@ -304,7 +304,7 @@
     assertValidId(completionId);
 
     // Wait for all processing to be complete
-    await analysisHandler.server.analysisDriverScheduler.waitForIdle();
+    await analysisHandler.server.onAnalysisComplete;
     await pumpEventQueue();
 
     // Assert that request has been aborted
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 72b7b5b..b7b387c 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -220,9 +220,7 @@
   }
 
   void test_mapUri_file_dartUriKind() {
-    var path = server.findSdk().mapDartUri('dart:async').fullName;
-    // hack - pretend that the SDK file exists in the project FS
-    newFile(path, content: '// hack');
+    var path = _mapUri(uri: 'dart:async').file;
     // map file
     var result = _mapUri(file: path);
     expect(result.file, isNull);
diff --git a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
index 6d9e3fc..fe4524b 100644
--- a/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/get_suggestions_available_test.dart
@@ -79,7 +79,10 @@
     // Force the server to rebuild all contexts, as happens when the file watcher
     // fails on Windows.
     // https://github.com/dart-lang/sdk/issues/44650
-    server.contextManager.refresh(null);
+    server.contextManager.refresh();
+
+    // Give it time to process the newly scheduled files.
+    await pumpEventQueue(times: 5000);
 
     // Ensure the set is still returned after the rebuild.
     results = await _getSuggestions(testFile, 0);
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index 64fb2ea..eca22e0 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -11,7 +11,6 @@
 import 'channel/test_all.dart' as channel;
 import 'client/test_all.dart' as client;
 import 'completion_test.dart' as completion;
-import 'context_manager_test.dart' as context_manager;
 import 'domain_analysis_test.dart' as domain_analysis;
 import 'domain_completion_test.dart' as domain_completion;
 import 'domain_diagnostic_test.dart' as domain_experimental;
@@ -39,7 +38,6 @@
     channel.main();
     client.main();
     completion.main();
-    context_manager.main();
     domain_analysis.main();
     domain_completion.main();
     domain_edit_dartfix.main();
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 1ece128..f64e776 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -6,6 +6,8 @@
 * Added `Folder.isRoot`.
 * Added `FolderExtension` with `withAncestors`.
 * Added `ContextRoot.workspace`, deprecated `AnalysisContext.workspace`.
+* Deprecated `ElementVisitor.visitFunctionTypeAliasElement()`.
+  Override `ElementVisitor.visitTypeAliasElement()` instead.
 
 ## 1.0.0
 * Stable null safety release.
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 336473b..91e2155 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -995,6 +995,7 @@
 
   R? visitFunctionElement(FunctionElement element);
 
+  @Deprecated('Override visitTypeAliasElement() instead')
   R? visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
 
   R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element);
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
index 27f3283..7da9bd6 100644
--- a/pkg/analyzer/lib/dart/element/visitor.dart
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -118,6 +118,7 @@
   R? visitFunctionElement(FunctionElement element) =>
       visitLocalElement(element);
 
+  @Deprecated('Override visitTypeAliasElement() instead')
   @override
   R? visitFunctionTypeAliasElement(FunctionTypeAliasElement element) =>
       visitElement(element);
@@ -249,6 +250,7 @@
     return null;
   }
 
+  @Deprecated('Override visitTypeAliasElement() instead')
   @override
   R? visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
     element.visitChildren(this);
@@ -369,6 +371,7 @@
   @override
   R? visitFunctionElement(FunctionElement element) => null;
 
+  @Deprecated('Override visitTypeAliasElement() instead')
   @override
   R? visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
 
@@ -450,6 +453,7 @@
   @override
   R? visitFunctionElement(FunctionElement element) => _throw(element);
 
+  @Deprecated('Override visitTypeAliasElement() instead')
   @override
   R? visitFunctionTypeAliasElement(FunctionTypeAliasElement element) =>
       _throw(element);
diff --git a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
index cdd784b..30d1728 100644
--- a/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/analysis_context_collection.dart
@@ -10,6 +10,8 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/context_builder.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:cli_util/cli_util.dart';
 
 /// An implementation of [AnalysisContextCollection].
@@ -25,12 +27,15 @@
   AnalysisContextCollectionImpl({
     ByteStore? byteStore,
     Map<String, String>? declaredVariables,
+    bool drainStreams = true,
     bool enableIndex = false,
     required List<String> includedPaths,
     List<String>? excludedPaths,
+    PerformanceLog? performanceLog,
     ResourceProvider? resourceProvider,
     bool retainDataForTesting = false,
     String? sdkPath,
+    AnalysisDriverScheduler? scheduler,
   }) : resourceProvider =
             resourceProvider ?? PhysicalResourceProvider.INSTANCE {
     sdkPath ??= getSdkPath();
@@ -53,9 +58,12 @@
         byteStore: byteStore,
         contextRoot: root,
         declaredVariables: DeclaredVariables.fromMap(declaredVariables ?? {}),
+        drainStreams: drainStreams,
         enableIndex: enableIndex,
+        performanceLog: performanceLog,
         retainDataForTesting: retainDataForTesting,
         sdkPath: sdkPath,
+        scheduler: scheduler,
       );
       contexts.add(context);
     }
diff --git a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
index 1af6e4f..e98ab16 100644
--- a/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/context_builder.dart
@@ -41,11 +41,12 @@
       {ByteStore? byteStore,
       required ContextRoot contextRoot,
       DeclaredVariables? declaredVariables,
+      bool drainStreams = true,
       bool enableIndex = false,
       List<String>? librarySummaryPaths,
-      @deprecated PerformanceLog? performanceLog,
+      PerformanceLog? performanceLog,
       bool retainDataForTesting = false,
-      @deprecated AnalysisDriverScheduler? scheduler,
+      AnalysisDriverScheduler? scheduler,
       String? sdkPath,
       String? sdkSummaryPath}) {
     // TODO(scheglov) Remove this, and make `sdkPath` required.
@@ -95,8 +96,10 @@
 
     // AnalysisDriver reports results into streams.
     // We need to drain these streams to avoid memory leak.
-    driver.results.drain();
-    driver.exceptions.drain();
+    if (drainStreams) {
+      driver.results.drain();
+      driver.exceptions.drain();
+    }
 
     DriverBasedAnalysisContext context =
         DriverBasedAnalysisContext(resourceProvider, contextRoot, driver);
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index f8ef12c..c8b5796 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4331,7 +4331,9 @@
 
   @override
   T? accept<T>(ElementVisitor<T> visitor) {
-    return visitor.visitFunctionTypeAliasElement(this);
+    // ignore: deprecated_member_use_from_same_package
+    visitor.visitFunctionTypeAliasElement(this);
+    return visitor.visitTypeAliasElement(this);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
index f218476..387ca4a 100644
--- a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -581,14 +581,15 @@
     // However in summary code it doesn't look like the AST node with span is
     // available.
     String prefix;
+    var genericClass = this.genericClass;
     if (genericClass != null &&
-        (genericClass!.name == "List" || genericClass!.name == "Map") &&
-        genericClass!.library.isDartCore == true) {
+        (genericClass.name == "List" || genericClass.name == "Map") &&
+        genericClass.library.isDartCore == true) {
       // This will become:
       //     "List element"
       //     "Map key"
       //     "Map value"
-      prefix = "${genericClass!.name} $parameterName";
+      prefix = "${genericClass.name} $parameterName";
     } else {
       prefix = "Parameter '$parameterName'";
     }
diff --git a/pkg/analyzer/lib/src/dartdoc/dartdoc_directive_info.dart b/pkg/analyzer/lib/src/dartdoc/dartdoc_directive_info.dart
index 2bcb023..85f2e08 100644
--- a/pkg/analyzer/lib/src/dartdoc/dartdoc_directive_info.dart
+++ b/pkg/analyzer/lib/src/dartdoc/dartdoc_directive_info.dart
@@ -44,7 +44,9 @@
 
   /// Process the given Dartdoc [comment], extracting the template directive if
   /// there is one.
-  void extractTemplate(String comment) {
+  void extractTemplate(String? comment) {
+    if (comment == null) return;
+
     for (Match match in templateRegExp.allMatches(comment)) {
       String name = match.group(1)!.trim();
       String body = match.group(2)!.trim();
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index c5ca546..06acfc4 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -196,9 +196,10 @@
     _addLibrariesWithPaths(sdkLibraries, _sdkLibraryPathList);
 
     var dependencyLibraries = <Library>[];
-    for (var pathPrefix in _pathPrefixToDependencyPathList.keys) {
+    for (var entry in _pathPrefixToDependencyPathList.entries) {
+      var pathPrefix = entry.key;
       if (path.startsWith(pathPrefix)) {
-        var pathList = _pathPrefixToDependencyPathList[pathPrefix]!;
+        var pathList = entry.value;
         _addLibrariesWithPaths(dependencyLibraries, pathList);
         break;
       }
@@ -1493,13 +1494,13 @@
                 relevanceTags: ['ElementKind.FIELD'],
                 returnType: _getTypeAnnotationString(classMember.returnType),
               );
-            } else if (classMember.isSetter) {
+            } else if (classMember.isSetter && parameters != null) {
               addDeclaration(
                 isDeprecated: isDeprecated,
                 isStatic: isStatic,
                 kind: DeclarationKind.SETTER,
                 name: classMember.name,
-                parameters: parameters!.toSource(),
+                parameters: parameters.toSource(),
                 parameterNames: _getFormalParameterNames(parameters),
                 parameterTypes: _getFormalParameterTypes(parameters),
                 parent: parent,
@@ -1507,8 +1508,8 @@
                 requiredParameterCount:
                     _getFormalParameterRequiredCount(parameters),
               );
-            } else {
-              var defaultArguments = _computeDefaultArguments(parameters!);
+            } else if (parameters != null) {
+              var defaultArguments = _computeDefaultArguments(parameters);
               addDeclaration(
                 defaultArgumentListString: defaultArguments?.text,
                 defaultArgumentListTextRanges: defaultArguments?.ranges,
@@ -1605,11 +1606,12 @@
           );
         }
       } else if (node is ExtensionDeclaration) {
-        if (node.name != null) {
+        var name = node.name;
+        if (name != null) {
           addDeclaration(
             isDeprecated: isDeprecated,
             kind: DeclarationKind.EXTENSION,
-            name: node.name!,
+            name: name,
             relevanceTags: ['ElementKind.EXTENSION'],
           );
         }
@@ -1626,20 +1628,20 @@
             relevanceTags: ['ElementKind.FUNCTION'],
             returnType: _getTypeAnnotationString(node.returnType),
           );
-        } else if (node.isSetter) {
+        } else if (node.isSetter && parameters != null) {
           addDeclaration(
             isDeprecated: isDeprecated,
             kind: DeclarationKind.SETTER,
             name: node.name,
-            parameters: parameters!.toSource(),
+            parameters: parameters.toSource(),
             parameterNames: _getFormalParameterNames(parameters),
             parameterTypes: _getFormalParameterTypes(parameters),
             relevanceTags: ['ElementKind.FUNCTION'],
             requiredParameterCount:
                 _getFormalParameterRequiredCount(parameters),
           );
-        } else {
-          var defaultArguments = _computeDefaultArguments(parameters!);
+        } else if (parameters != null) {
+          var defaultArguments = _computeDefaultArguments(parameters);
           addDeclaration(
             defaultArgumentListString: defaultArguments?.text,
             defaultArgumentListTextRanges: defaultArguments?.ranges,
@@ -1731,35 +1733,27 @@
     DartdocDirectiveInfo info = DartdocDirectiveInfo();
     for (Directive directive in unit.directives) {
       var comment = directive.documentationComment;
-      if (comment != null) {
-        info.extractTemplate(getCommentNodeRawText(comment)!);
-      }
+      info.extractTemplate(getCommentNodeRawText(comment));
     }
     for (CompilationUnitMember declaration in unit.declarations) {
       var comment = declaration.documentationComment;
-      if (comment != null) {
-        info.extractTemplate(getCommentNodeRawText(comment)!);
-      }
+      info.extractTemplate(getCommentNodeRawText(comment));
       if (declaration is ClassOrMixinDeclaration) {
         for (ClassMember member in declaration.members) {
           var comment = member.documentationComment;
-          if (comment != null) {
-            info.extractTemplate(getCommentNodeRawText(comment)!);
-          }
+          info.extractTemplate(getCommentNodeRawText(comment));
         }
       } else if (declaration is EnumDeclaration) {
         for (EnumConstantDeclaration constant in declaration.constants) {
           var comment = constant.documentationComment;
-          if (comment != null) {
-            info.extractTemplate(getCommentNodeRawText(comment)!);
-          }
+          info.extractTemplate(getCommentNodeRawText(comment));
         }
       }
     }
     Map<String, String> templateMap = info.templateMap;
-    for (String name in templateMap.keys) {
-      templateNames.add(name);
-      templateValues.add(templateMap[name]!);
+    for (var entry in templateMap.entries) {
+      templateNames.add(entry.key);
+      templateValues.add(entry.value);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
index 3c6f084..18d7617 100644
--- a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
@@ -1050,17 +1050,18 @@
   void _token(Token? token) {
     if (token == null) return;
 
-    if (_last != null) {
-      if (_last!.next != token) {
+    var last = _last;
+    if (last != null) {
+      if (last.next != token) {
         throw StateError(
-          '|$_last| must be followed by |${_last!.next}|, got |$token|',
+          '|$last| must be followed by |${last.next}|, got |$token|',
         );
       }
     }
 
     // Print preceding comments as a separate sequence of tokens.
     if (token.precedingComments != null) {
-      var lastToken = _last;
+      var lastToken = last;
       _last = null;
       for (Token? c = token.precedingComments; c != null; c = c.next) {
         _token(c);
diff --git a/pkg/analyzer/test/src/dart/analysis/dependency/base.dart b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
index 4d09fb6..3eec88f 100644
--- a/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
+++ b/pkg/analyzer/test/src/dart/analysis/dependency/base.dart
@@ -9,10 +9,7 @@
 
 import '../../resolution/context_collection_resolution.dart';
 
-class BaseDependencyTest extends PubPackageResolutionTest
-    with WithoutNullSafetyMixin {
-  // TODO(https://github.com/dart-lang/sdk/issues/44666): Use null safety in
-  //  test cases.
+class BaseDependencyTest extends PubPackageResolutionTest {
   late final String a;
   late final String b;
   late final String c;
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index a11c045..f3bb485 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -36,17 +36,15 @@
 /// Integration tests for resolution.
 @reflectiveTest
 class AnalysisDriverResolutionTest extends PubPackageResolutionTest
-    with WithoutNullSafetyMixin, ElementsTypesMixin {
-  // TODO(https://github.com/dart-lang/sdk/issues/44666): Use null safety in
-  //  test cases.
+    with ElementsTypesMixin {
   void assertDeclaredVariableType(SimpleIdentifier node, String expected) {
     var element = node.staticElement as VariableElement;
     assertType(element.type, expected);
   }
 
-  void assertDeclaredVariableTypeDynamic(SimpleIdentifier node) {
+  void assertDeclaredVariableTypeObject(SimpleIdentifier node) {
     var element = node.staticElement as VariableElement;
-    expect(element.type, isDynamicType);
+    expect(element.type, typeProvider.objectType);
   }
 
   /// Test that [argumentList] has exactly two type items `int` and `double`.
@@ -669,11 +667,11 @@
     expect(atD.name.staticElement, elementD);
     expect(atD.element, constructorD);
 
-    expect(constC.staticType, interfaceTypeStar(elementC));
+    expect(constC.staticType, interfaceTypeNone(elementC));
 
     var constructorName = constC.constructorName;
     expect(constructorName.staticElement, constructorC);
-    expect(constructorName.type.type, interfaceTypeStar(elementC));
+    expect(constructorName.type.type, interfaceTypeNone(elementC));
   }
 
   test_annotation_unprefixed_topLevelVariable() async {
@@ -978,7 +976,7 @@
       var forTarget = forInvocation.target as SimpleIdentifier;
       expect(forTarget.staticElement, itemsElement);
 
-      var closureTypeStr = 'Null Function(int)';
+      var closureTypeStr = 'void Function(int)';
       var closure =
           forInvocation.argumentList.arguments[0] as FunctionExpression;
 
@@ -988,7 +986,7 @@
       ParameterElement itemElement = closureElement.parameters[0];
       itemElement1 = itemElement;
 
-      expect(closureElement.returnType, typeProvider.nullType);
+      expect(closureElement.returnType, typeProvider.voidType);
       assertType(closureElement.type, closureTypeStr);
       expect(closure.staticType, same(closureElement.type));
 
@@ -1019,7 +1017,7 @@
       var forTarget = forInvocation.target as SimpleIdentifier;
       expect(forTarget.staticElement, itemsElement);
 
-      var closureTypeStr = 'Null Function(int)';
+      var closureTypeStr = 'void Function(int)';
       var closure =
           forInvocation.argumentList.arguments[0] as FunctionExpression;
 
@@ -1029,7 +1027,7 @@
       ParameterElement itemElement = closureElement.parameters[0];
       expect(itemElement, isNot(same(itemElement1)));
 
-      expect(closureElement.returnType, typeProvider.nullType);
+      expect(closureElement.returnType, typeProvider.voidType);
       assertType(closureElement.type, closureTypeStr);
       expect(closure.staticType, same(closureElement.type));
 
@@ -1330,7 +1328,7 @@
       expect(constructorName.staticElement, same(aUnnamed));
 
       TypeName typeName = constructorName.type;
-      expect(typeName.type, interfaceTypeStar(aElement));
+      expect(typeName.type, interfaceTypeNone(aElement));
 
       var identifier = typeName.name as SimpleIdentifier;
       expect(identifier.staticElement, same(aElement));
@@ -1350,7 +1348,7 @@
       expect(constructorName.staticElement, same(aNamed));
 
       var typeName = constructorName.type;
-      expect(typeName.type, interfaceTypeStar(aElement));
+      expect(typeName.type, interfaceTypeNone(aElement));
 
       var identifier = typeName.name as SimpleIdentifier;
       expect(identifier.staticElement, same(aElement));
@@ -1380,10 +1378,10 @@
 
     var bNode = result.unit!.declarations[1] as ClassDeclaration;
     TypeParameterType uType =
-        typeParameterTypeStar(bNode.declaredElement!.typeParameters[0]);
+        typeParameterTypeNone(bNode.declaredElement!.typeParameters[0]);
     InterfaceType auType = aElement.instantiate(
       typeArguments: [uType],
-      nullabilitySuffix: NullabilitySuffix.star,
+      nullabilitySuffix: NullabilitySuffix.none,
     );
 
     {
@@ -1767,7 +1765,7 @@
     VariableDeclaration fNode = fDeclaration.fields.variables[0];
     var fElement = fNode.declaredElement as FieldElement;
     expect(
-        fElement.type, typeProvider.listType(typeParameterTypeStar(tElement)));
+        fElement.type, typeProvider.listType(typeParameterTypeNone(tElement)));
   }
 
   test_field_generic() async {
@@ -2091,7 +2089,7 @@
       var aDeclaration = unit.declarations[1] as TopLevelVariableDeclaration;
       VariableDeclaration aNode = aDeclaration.variables.variables[0];
       var value = aNode.initializer as InstanceCreationExpression;
-      expect(value.staticType, interfaceTypeStar(cElement));
+      expect(value.staticType, interfaceTypeNone(cElement));
 
       var constructorName = value.constructorName;
       expect(constructorName.name, isNull);
@@ -2109,7 +2107,7 @@
       var bDeclaration = unit.declarations[2] as TopLevelVariableDeclaration;
       VariableDeclaration bNode = bDeclaration.variables.variables[0];
       var value = bNode.initializer as InstanceCreationExpression;
-      expect(value.staticType, interfaceTypeStar(cElement));
+      expect(value.staticType, interfaceTypeNone(cElement));
 
       var constructorName = value.constructorName;
       expect(constructorName.staticElement, namedConstructor);
@@ -2144,7 +2142,7 @@
 
     var creation = vNode.initializer as InstanceCreationExpression;
     List<Expression> arguments = creation.argumentList.arguments;
-    expect(creation.staticType, interfaceTypeStar(xElement));
+    expect(creation.staticType, interfaceTypeNone(xElement));
 
     var constructorName = creation.constructorName;
     expect(constructorName.name, isNull);
@@ -2185,7 +2183,7 @@
       var aDeclaration = unit.declarations[1] as TopLevelVariableDeclaration;
       VariableDeclaration aNode = aDeclaration.variables.variables[0];
       var value = aNode.initializer as InstanceCreationExpression;
-      expect(value.staticType, interfaceTypeStar(cElement));
+      expect(value.staticType, interfaceTypeNone(cElement));
 
       var constructorName = value.constructorName;
       expect(constructorName.name, isNull);
@@ -2206,7 +2204,7 @@
       var bDeclaration = unit.declarations[2] as TopLevelVariableDeclaration;
       VariableDeclaration bNode = bDeclaration.variables.variables[0];
       var value = bNode.initializer as InstanceCreationExpression;
-      expect(value.staticType, interfaceTypeStar(cElement));
+      expect(value.staticType, interfaceTypeNone(cElement));
 
       var constructorName = value.constructorName;
       expect(constructorName.staticElement, namedConstructor);
@@ -2254,7 +2252,7 @@
     {
       var cTypeInt = cElement.instantiate(
         typeArguments: [typeProvider.intType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       var statement = statements[0] as ExpressionStatement;
@@ -2283,7 +2281,7 @@
     {
       var cTypeDouble = cElement.instantiate(
         typeArguments: [typeProvider.doubleType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       var statement = statements[1] as ExpressionStatement;
@@ -2313,7 +2311,7 @@
     {
       var cTypeBool = cElement.instantiate(
         typeArguments: [typeProvider.boolType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       var statement = statements[2] as ExpressionStatement;
@@ -2369,7 +2367,7 @@
     {
       var cTypeInt = cElement.instantiate(
         typeArguments: [typeProvider.intType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       var statement = statements[0] as ExpressionStatement;
@@ -2391,7 +2389,7 @@
     {
       var cTypeBool = cElement.instantiate(
         typeArguments: [typeProvider.boolType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       var statement = statements[1] as ExpressionStatement;
@@ -2415,7 +2413,7 @@
     {
       var cTypeDouble = cElement.instantiate(
         typeArguments: [typeProvider.doubleType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       var statement = statements[2] as ExpressionStatement;
@@ -2438,7 +2436,7 @@
     {
       var cTypeBool = cElement.instantiate(
         typeArguments: [typeProvider.boolType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       var statement = statements[3] as ExpressionStatement;
@@ -2555,7 +2553,7 @@
     await resolveTestFile();
     expect(result.errors, isNotEmpty);
 
-    assertDeclaredVariableTypeDynamic(findNode.simple('x,'));
+    assertDeclaredVariableTypeObject(findNode.simple('x,'));
     assertDeclaredVariableType(findNode.simple('y,'), 'StackTrace');
   }
 
@@ -2578,7 +2576,7 @@
     await resolveTestFile();
     expect(result.errors, isNotEmpty);
 
-    assertDeclaredVariableTypeDynamic(findNode.simple('e,'));
+    assertDeclaredVariableTypeObject(findNode.simple('e,'));
     assertDeclaredVariableType(findNode.simple('s})'), 'StackTrace');
   }
 
@@ -2591,7 +2589,7 @@
     await resolveTestFile();
     expect(result.errors, isNotEmpty);
 
-    assertDeclaredVariableTypeDynamic(findNode.simple('e,'));
+    assertDeclaredVariableTypeObject(findNode.simple('e,'));
     assertDeclaredVariableType(findNode.simple('s])'), 'StackTrace');
   }
 
@@ -2686,7 +2684,7 @@
 
     var invocation = findNode.functionExpressionInvocation('id(');
     assertElement(invocation.function, findElement.topGet('id'));
-    assertInvokeType(invocation, 'bool Function(Object, Object)');
+    assertInvokeType(invocation, 'bool Function(Object?, Object?)');
     assertType(invocation, 'bool');
 
     var aRef = invocation.argumentList.arguments[0];
@@ -4369,26 +4367,24 @@
 
   test_local_parameter() async {
     await assertNoErrorsInCode(r'''
-void main(int p) {
+void main(List<String> p) {
   p;
 }
 ''');
 
-    InterfaceType intType = typeProvider.intType;
-
     var main = result.unit!.declarations[0] as FunctionDeclaration;
     List<Statement> statements = _getMainStatements(result);
 
     // (int p)
     VariableElement pElement = main.declaredElement!.parameters[0];
-    expect(pElement.type, intType);
+    expect(pElement.type, listNone(typeProvider.stringType));
 
     // p;
     {
       var statement = statements[0] as ExpressionStatement;
       var identifier = statement.expression as SimpleIdentifier;
       expect(identifier.staticElement, pElement);
-      expect(identifier.staticType, intType);
+      expect(identifier.staticType, listNone(typeProvider.stringType));
     }
   }
 
@@ -5210,7 +5206,7 @@
 
   test_methodInvocation_explicitCall_functionTarget() async {
     addTestFile(r'''
-main(double computation(int p)) {
+f(double computation(int p)) {
   computation.call(1);
 }
 ''');
@@ -5933,7 +5929,7 @@
 
   test_outline_type_genericFunction() async {
     addTestFile(r'''
-int Function(double) g() => null;
+int Function(double) g() => (double g) => 0;
 ''');
     await resolveTestFile();
     expect(result.errors, isEmpty);
@@ -5950,8 +5946,8 @@
 
   test_outline_type_topLevelVar_named() async {
     addTestFile(r'''
-int a;
-List<double> b;
+int a = 0;
+List<double> b = [];
 ''');
     await resolveTestFile();
     expect(result.errors, isEmpty);
@@ -6176,7 +6172,7 @@
 
     SimpleIdentifier prefix = prefixed.prefix;
     expect(prefix.staticElement, same(vElement));
-    expect(prefix.staticType, interfaceTypeStar(cElement));
+    expect(prefix.staticType, interfaceTypeNone(cElement));
 
     SimpleIdentifier identifier = prefixed.identifier;
     expect(identifier.staticElement, same(fElement.getter));
@@ -6216,7 +6212,7 @@
 
   test_prefixedIdentifier_explicitCall() async {
     addTestFile(r'''
-main(double computation(int p)) {
+f(double computation(int p)) {
   computation.call;
 }
 ''');
@@ -6519,7 +6515,7 @@
         newC.constructorName.staticElement,
         cClassElement.unnamedConstructor,
       );
-      expect(newC.staticType, interfaceTypeStar(cClassElement));
+      expect(newC.staticType, interfaceTypeNone(cClassElement));
 
       expect(access.propertyName.staticElement, same(fElement.getter));
       expect(access.propertyName.staticType, typeProvider.intType);
@@ -6556,7 +6552,7 @@
         newC.constructorName.staticElement,
         cClassElement.unnamedConstructor,
       );
-      expect(newC.staticType, interfaceTypeStar(cClassElement));
+      expect(newC.staticType, interfaceTypeNone(cClassElement));
 
       expect(access.propertyName.staticElement, same(fElement.getter));
       expect(access.propertyName.staticType, typeProvider.intType);
@@ -6720,7 +6716,7 @@
 
       var target = invocation.target as SuperExpression;
       expect(
-          target.staticType, interfaceTypeStar(bNode.declaredElement!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       expect(invocation.methodName.staticElement, same(methodElement));
     }
@@ -6742,7 +6738,7 @@
 
       var target = propertyAccess.target as SuperExpression;
       expect(
-          target.staticType, interfaceTypeStar(bNode.declaredElement!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       expect(propertyAccess.propertyName.staticElement, same(getterElement));
       expect(propertyAccess.propertyName.staticType, typeProvider.intType);
@@ -6772,7 +6768,7 @@
 
       var target = propertyAccess.target as SuperExpression;
       expect(
-          target.staticType, interfaceTypeStar(bNode.declaredElement!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       if (hasAssignmentLeftResolution) {
         expect(propertyAccess.propertyName.staticElement, same(setterElement));
@@ -6790,7 +6786,7 @@
 
       var target = binary.leftOperand as ThisExpression;
       expect(
-          target.staticType, interfaceTypeStar(bNode.declaredElement!)); // raw
+          target.staticType, interfaceTypeNone(bNode.declaredElement!)); // raw
 
       expect(binary.staticElement, same(operatorElement));
       expect(binary.staticType, typeProvider.intType);
@@ -6832,7 +6828,7 @@
     List<Statement> testStatements = testBody.block.statements;
 
     var elementA = findElement.class_('A');
-    var thisTypeA = interfaceTypeStar(elementA);
+    var thisTypeA = interfaceTypeNone(elementA);
 
     // method(1);
     {
@@ -6998,7 +6994,7 @@
     {
       var expectedType = aElement.instantiate(
         typeArguments: [typeProvider.boolType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       TypeName superClass = dNode.extendsClause!.superclass;
@@ -7012,7 +7008,7 @@
     {
       var expectedType = bElement.instantiate(
         typeArguments: [typeProvider.intType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       TypeName mixinType = dNode.withClause!.mixinTypes[0];
@@ -7026,7 +7022,7 @@
     {
       var expectedType = cElement.instantiate(
         typeArguments: [typeProvider.doubleType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       TypeName implementedType = dNode.implementsClause!.interfaces[0];
@@ -7067,7 +7063,7 @@
     {
       var expectedType = aElement.instantiate(
         typeArguments: [typeProvider.boolType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       TypeName superClass = dNode.superclass;
@@ -7081,7 +7077,7 @@
     {
       var expectedType = bElement.instantiate(
         typeArguments: [typeProvider.intType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       TypeName mixinType = dNode.withClause.mixinTypes[0];
@@ -7095,7 +7091,7 @@
     {
       var expectedType = cElement.instantiate(
         typeArguments: [typeProvider.doubleType],
-        nullabilitySuffix: NullabilitySuffix.star,
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       TypeName interfaceType = dNode.implementsClause!.interfaces[0];
@@ -7407,7 +7403,7 @@
 
       VariableDeclaration bNode = bDeclaration.fields.variables[0];
       expect(bNode.declaredElement, same(bElement));
-      expect(bElement.type, typeParameterTypeStar(tElement));
+      expect(bElement.type, typeParameterTypeNone(tElement));
       expect(bNode.name.staticElement, same(bElement));
       expect(bNode.name.staticType, isNull);
     }
@@ -7647,7 +7643,7 @@
         name: 'b',
         offset: 27,
         kind: ParameterKind.REQUIRED,
-        type: typeParameterTypeStar(aliasElement.typeParameters[0]));
+        type: typeParameterTypeNone(aliasElement.typeParameters[0]));
   }
 
   test_top_typeParameter() async {
@@ -7673,7 +7669,7 @@
       expect(tNode.declaredElement, same(cElement.typeParameters[0]));
 
       var bound = tNode.bound as TypeName;
-      expect(bound.type, interfaceTypeStar(aElement));
+      expect(bound.type, interfaceTypeNone(aElement));
 
       var boundIdentifier = bound.name as SimpleIdentifier;
       expect(boundIdentifier.staticElement, same(aElement));
@@ -7683,8 +7679,8 @@
     {
       var listElement = typeProvider.listElement;
       var listOfA = listElement.instantiate(
-        typeArguments: [interfaceTypeStar(aElement)],
-        nullabilitySuffix: NullabilitySuffix.star,
+        typeArguments: [interfaceTypeNone(aElement)],
+        nullabilitySuffix: NullabilitySuffix.none,
       );
 
       TypeParameter uNode = cNode.typeParameters!.typeParameters[1];
@@ -7698,7 +7694,7 @@
       expect(listIdentifier.staticType, isNull);
 
       var aTypeName = bound.typeArguments!.arguments[0] as TypeName;
-      expect(aTypeName.type, interfaceTypeStar(aElement));
+      expect(aTypeName.type, interfaceTypeNone(aElement));
 
       var aIdentifier = aTypeName.name as SimpleIdentifier;
       expect(aIdentifier.staticElement, same(aElement));
@@ -7745,7 +7741,7 @@
       var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
       var exceptionElement =
           exceptionNode.staticElement as LocalVariableElement;
-      expect(exceptionElement.type, DynamicTypeImpl.instance);
+      expect(exceptionElement.type, typeProvider.objectType);
 
       var stackNode = catchClause.stackTraceParameter as SimpleIdentifier;
       var stackElement = stackNode.staticElement as LocalVariableElement;
@@ -7757,7 +7753,7 @@
       var exceptionIdentifier =
           exceptionStatement.expression as SimpleIdentifier;
       expect(exceptionIdentifier.staticElement, same(exceptionElement));
-      expect(exceptionIdentifier.staticType, DynamicTypeImpl.instance);
+      expect(exceptionIdentifier.staticType, typeProvider.objectType);
 
       var stackStatement = catchStatements[1] as ExpressionStatement;
       var stackIdentifier = stackStatement.expression as SimpleIdentifier;
@@ -7805,7 +7801,7 @@
       var exceptionNode = catchClause.exceptionParameter as SimpleIdentifier;
       var exceptionElement =
           exceptionNode.staticElement as LocalVariableElement;
-      expect(exceptionElement.type, DynamicTypeImpl.instance);
+      expect(exceptionElement.type, typeProvider.objectType);
     }
 
     // on int catch (e)
@@ -8206,7 +8202,7 @@
     var statement = statements[0] as ExpressionStatement;
 
     var creation = statement.expression as InstanceCreationExpression;
-    expect(creation.staticType, interfaceTypeStar(randomElement));
+    expect(creation.staticType, interfaceTypeNone(randomElement));
 
     ConstructorName constructorName = creation.constructorName;
 
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index a04b1a4..97d2b78 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,7 +1,12 @@
 # Changelog
+## 6.1.1
+- Callsite `StackTrace`s are now attached to `RPCError`s and `SentinelException`s.
+
+## 6.1.0+1
+- Documentation update.
 
 ## 6.1.0
-- *bug fix* Fixed issue where the root object was omitted from
+- *breaking bug fix*: Fixed issue where the root object was omitted from
   `HeapSnapshot.classes` and the sentinel `HeapSnapshotObject` was omitted from
   `HeapSnapshot.objects`
 - Added `identityHashCode` property to `HeapSnapshotObject`, which can be used to compare
@@ -10,6 +15,9 @@
   access children of a given object.
 - Added `klass` getter to `HeapSnapshotObject`.
 - Fixed issue where `null` could be returned instead of `InstanceRef` of type `Null`.
+- Added `getAllocationTraces` and `setTraceClassAllocation` RPCs.
+- Updated `CpuSample` to include `identityHashCode` and `classId` properties.
+- Updated `Class` to include `traceAllocations` property.
 
 ## 6.0.1
 - Stable null-safe release.
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index e5c1673..4413911 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -505,6 +505,20 @@
   Future<AllocationProfile> getAllocationProfile(String isolateId,
       {bool? reset, bool? gc});
 
+  /// The `getAllocationTraces` RPC allows for the retrieval of allocation
+  /// traces for objects of a specific set of types (see
+  /// [setTraceClassAllocation]). Only samples collected in the time range
+  /// `[timeOriginMicros, timeOriginMicros + timeExtentMicros]` will be
+  /// reported.
+  ///
+  /// If `classId` is provided, only traces for allocations with the matching
+  /// `classId` will be reported.
+  ///
+  /// If the profiler is disabled, an RPC error response will be returned.
+  ///
+  /// If isolateId refers to an isolate which has exited, then the Collected
+  /// Sentinel is returned.
+  ///
   /// See [CpuSamples].
   Future<CpuSamples> getAllocationTraces(
     String isolateId, {
@@ -1061,6 +1075,16 @@
   /// returned.
   Future<Success> setName(String isolateId, String name);
 
+  /// The `setTraceClassAllocation` RPC allows for enabling or disabling
+  /// allocation tracing for a specific type of object. Allocation traces can be
+  /// retrieved with the `getAllocationTraces` RPC.
+  ///
+  /// If `enable` is true, allocations of objects of the class represented by
+  /// `classId` will be traced.
+  ///
+  /// If `isolateId` refers to an isolate which has exited, then the `Collected`
+  /// [Sentinel] is returned.
+  ///
   /// See [Success].
   ///
   /// This method will throw a [SentinelException] in the case a [Sentinel] is
@@ -1574,12 +1598,25 @@
   }
 }
 
+class _OutstandingRequest<T> {
+  _OutstandingRequest(this.method);
+  static int _idCounter = 0;
+  final String id = '${_idCounter++}';
+  final String method;
+  final StackTrace _stackTrace = StackTrace.current;
+  final Completer<T> _completer = Completer<T>();
+
+  Future<T> get future => _completer.future;
+
+  void complete(T value) => _completer.complete(value);
+  void completeError(Object error) =>
+      _completer.completeError(error, _stackTrace);
+}
+
 class VmService implements VmServiceInterface {
   late final StreamSubscription _streamSub;
   late final Function _writeMessage;
-  int _id = 0;
-  Map<String, Completer> _completers = {};
-  Map<String, String> _methodCalls = {};
+  final Map<String, _OutstandingRequest> _outstandingRequests = {};
   Map<String, ServiceCallback> _services = {};
   late final Log _log;
 
@@ -2019,12 +2056,14 @@
 
   Future<void> dispose() async {
     await _streamSub.cancel();
-    _completers.forEach((id, c) {
-      final method = _methodCalls[id];
-      return c.completeError(RPCError(
-          method, RPCError.kServerError, 'Service connection disposed'));
+    _outstandingRequests.forEach((id, request) {
+      request._completer.completeError(RPCError(
+        request.method,
+        RPCError.kServerError,
+        'Service connection disposed',
+      ));
     });
-    _completers.clear();
+    _outstandingRequests.clear();
     if (_disposeHandler != null) {
       await _disposeHandler!();
     }
@@ -2035,21 +2074,19 @@
 
   Future get onDone => _onDoneCompleter.future;
 
-  Future<T> _call<T>(String method, [Map args = const {}]) {
-    String id = '${++_id}';
-    Completer<T> completer = Completer<T>();
-    _completers[id] = completer;
-    _methodCalls[id] = method;
+  Future<T> _call<T>(String method, [Map args = const {}]) async {
+    final request = _OutstandingRequest(method);
+    _outstandingRequests[request.id] = request;
     Map m = {
       'jsonrpc': '2.0',
-      'id': id,
+      'id': request.id,
       'method': method,
       'params': args,
     };
     String message = jsonEncode(m);
     _onSend.add(message);
     _writeMessage(message);
-    return completer.future;
+    return await request.future as T;
   }
 
   /// Register a service for invocation.
@@ -2119,22 +2156,21 @@
   }
 
   void _processResponse(Map<String, dynamic> json) {
-    Completer? completer = _completers.remove(json['id']);
-    String methodName = _methodCalls.remove(json['id'])!;
-    List<String> returnTypes = _methodReturnTypes[methodName] ?? [];
-    if (completer == null) {
+    final request = _outstandingRequests.remove(json['id']);
+    if (request == null) {
       _log.severe('unmatched request response: ${jsonEncode(json)}');
     } else if (json['error'] != null) {
-      completer.completeError(RPCError.parse(methodName, json['error']));
+      request.completeError(RPCError.parse(request.method, json['error']));
     } else {
       Map<String, dynamic> result = json['result'] as Map<String, dynamic>;
       String type = result['type'];
       if (type == 'Sentinel') {
-        completer.completeError(SentinelException.parse(methodName, result));
+        request.completeError(SentinelException.parse(request.method, result));
       } else if (_typeFactories[type] == null) {
-        completer.complete(Response.parse(result));
+        request.complete(Response.parse(result));
       } else {
-        completer.complete(createServiceObject(result, returnTypes));
+        List<String> returnTypes = _methodReturnTypes[request.method] ?? [];
+        request.complete(createServiceObject(result, returnTypes));
       }
     }
   }
@@ -6645,8 +6681,7 @@
 /// line number followed by `(tokenPos, columnNumber)` pairs:
 ///
 /// ```
-/// [
-/// ```lineNumber, (tokenPos, columnNumber)*]
+/// [lineNumber, (tokenPos, columnNumber)*]
 /// ```
 ///
 /// The `tokenPos` is an arbitrary integer value that is used to represent a
@@ -6656,10 +6691,7 @@
 /// For example, a `tokenPosTable` with the value...
 ///
 /// ```
-/// [
-/// ```[
-/// ```1, 100, 5, 101, 8],[
-/// ```2, 102, 7]]
+/// [[1, 100, 5, 101, 8],[2, 102, 7]]
 /// ```
 ///
 /// ...encodes the mapping:
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index f934b81..b3e0010 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -3,7 +3,7 @@
   A library to communicate with a service implementing the Dart VM
   service protocol.
 
-version: 6.1.0
+version: 6.1.1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service
 
diff --git a/pkg/vm_service/test/rpc_error_test.dart b/pkg/vm_service/test/rpc_error_test.dart
new file mode 100644
index 0000000..e6b5df5
--- /dev/null
+++ b/pkg/vm_service/test/rpc_error_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2021, 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:vm_service/vm_service.dart';
+import 'package:test/test.dart';
+
+import 'common/test_helper.dart';
+
+var tests = <VMTest>[
+  (VmService vm) async {
+    // Invoke a non-existant RPC.
+    try {
+      final res = await vm.callMethod('foo');
+      fail('Expected RPCError, got $res');
+    } on RPCError catch (e, st) {
+      // Ensure stack trace contains actual invocation path.
+      final stack = st.toString().split('\n');
+      expect(stack.where((e) => e.contains('VmService.callMethod')).length, 1);
+      // Call to vm.callMethod('foo') and the invocation of the test closure.
+      expect(
+          stack.where((e) => e.contains('test/rpc_error_test.dart')).length, 2);
+    } catch (e) {
+      fail('Expected RPCError, got $e');
+    }
+  },
+];
+
+main([args = const <String>[]]) async => await runVMTests(
+      args,
+      tests,
+      'rpc_error_test.dart',
+    );
diff --git a/pkg/vm_service/test/throws_sentinel_test.dart b/pkg/vm_service/test/throws_sentinel_test.dart
index 3b377c5..fd95bbe 100644
--- a/pkg/vm_service/test/throws_sentinel_test.dart
+++ b/pkg/vm_service/test/throws_sentinel_test.dart
@@ -12,8 +12,15 @@
     try {
       final res = await vm.getIsolate('isolates/12321');
       fail('Expected SentinelException, got $res');
-    } on SentinelException {
-      // Expected.
+    } on SentinelException catch (e, st) {
+      // Ensure stack trace contains actual invocation path.
+      final stack = st.toString().split('\n');
+      expect(stack.where((e) => e.contains('VmService.getIsolate')).length, 1);
+      // Call to vm.getIsolate('isolates/12321') and the invocation of the test closure.
+      expect(
+        stack.where((e) => e.contains('test/throws_sentinel_test.dart')).length,
+        2,
+      );
     } catch (e) {
       fail('Expected SentinelException, got $e');
     }
diff --git a/pkg/vm_service/tool/dart/generate_dart.dart b/pkg/vm_service/tool/dart/generate_dart.dart
index f512f5a..774f271 100644
--- a/pkg/vm_service/tool/dart/generate_dart.dart
+++ b/pkg/vm_service/tool/dart/generate_dart.dart
@@ -100,12 +100,11 @@
 
   Future<void> dispose() async {
     await _streamSub.cancel();
-    _completers.forEach((id, c) {
-      final method = _methodCalls[id];
-      return c.completeError(RPCError(
-          method, RPCError.kServerError, 'Service connection disposed'));
+    _outstandingRequests.forEach((id, request) {
+      request._completer.completeError(RPCError(
+          request.method, RPCError.kServerError, 'Service connection disposed',));
     });
-    _completers.clear();
+    _outstandingRequests.clear();
     if (_disposeHandler != null) {
       await _disposeHandler!();
     }
@@ -116,16 +115,14 @@
 
   Future get onDone => _onDoneCompleter.future;
 
-  Future<T> _call<T>(String method, [Map args = const {}]) {
-    String id = '${++_id}';
-    Completer<T> completer = Completer<T>();
-    _completers[id] = completer;
-    _methodCalls[id] = method;
-    Map m = {'jsonrpc': '2.0', 'id': id, 'method': method, 'params': args,};
+  Future<T> _call<T>(String method, [Map args = const {}]) async {
+    final request = _OutstandingRequest(method);
+    _outstandingRequests[request.id] = request;
+    Map m = {'jsonrpc': '2.0', 'id': request.id, 'method': method, 'params': args,};
     String message = jsonEncode(m);
     _onSend.add(message);
     _writeMessage(message);
-    return completer.future;
+    return await request.future as T;
   }
 
   /// Register a service for invocation.
@@ -196,22 +193,21 @@
   }
 
   void _processResponse(Map<String, dynamic> json) {
-    Completer? completer = _completers.remove(json['id']);
-    String methodName = _methodCalls.remove(json['id'])!;
-    List<String> returnTypes = _methodReturnTypes[methodName] ?? [];
-    if (completer == null) {
+    final request = _outstandingRequests.remove(json['id']);
+    if (request == null) {
       _log.severe('unmatched request response: ${jsonEncode(json)}');
     } else if (json['error'] != null) {
-      completer.completeError(RPCError.parse(methodName, json['error']));
+      request.completeError(RPCError.parse(request.method, json['error']));
     } else {
       Map<String, dynamic> result = json['result'] as Map<String, dynamic>;
       String type = result['type'];
       if (type == 'Sentinel') {
-        completer.completeError(SentinelException.parse(methodName, result));
+        request.completeError(SentinelException.parse(request.method, result));
       } else if (_typeFactories[type] == null) {
-        completer.complete(Response.parse(result));
+        request.complete(Response.parse(result));
       } else {
-        completer.complete(createServiceObject(result, returnTypes));
+        List<String> returnTypes = _methodReturnTypes[request.method] ?? [];
+        request.complete(createServiceObject(result, returnTypes));
       }
     }
   }
@@ -816,13 +812,29 @@
     gen.write('}');
     gen.writeln();
 
+    gen.write('''
+class _OutstandingRequest<T> {
+  _OutstandingRequest(this.method);
+  static int _idCounter = 0;
+  final String id = '\${_idCounter++}';
+  final String method;
+  final StackTrace _stackTrace = StackTrace.current;
+  final Completer<T> _completer = Completer<T>();
+
+  Future<T> get future => _completer.future;
+
+  void complete(T value) => _completer.complete(value);
+  void completeError(Object error) =>
+      _completer.completeError(error, _stackTrace);
+}
+''');
+
     // The client side service implementation.
     gen.writeStatement('class VmService implements VmServiceInterface {');
     gen.writeStatement('late final StreamSubscription _streamSub;');
     gen.writeStatement('late final Function _writeMessage;');
-    gen.writeStatement('int _id = 0;');
-    gen.writeStatement('Map<String, Completer> _completers = {};');
-    gen.writeStatement('Map<String, String> _methodCalls = {};');
+    gen.writeStatement(
+        'final Map<String, _OutstandingRequest> _outstandingRequests = {};');
     gen.writeStatement('Map<String, ServiceCallback> _services = {};');
     gen.writeStatement('late final Log _log;');
     gen.write('''
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 0dfaa61..938b2d9 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -1009,18 +1009,15 @@
     // RoundedAllocationSize(
     //     (array_length * kwordSize) + target::Array::header_size()).
     __ mov(R3, Operand(R2));  // Array length.
-    // Check that length is a positive Smi.
+    // Check that length is a Smi.
     __ tst(R3, Operand(kSmiTagMask));
     __ b(&slow_case, NE);
 
-    __ cmp(R3, Operand(0));
-    __ b(&slow_case, LT);
-
-    // Check for maximum allowed length.
+    // Check length >= 0 && length <= kMaxNewSpaceElements
     const intptr_t max_len =
         target::ToRawSmi(target::Array::kMaxNewSpaceElements);
     __ CompareImmediate(R3, max_len);
-    __ b(&slow_case, GT);
+    __ b(&slow_case, HI);
 
     const intptr_t cid = kArrayCid;
     NOT_IN_PRODUCT(__ LoadAllocationStatsAddress(R4, cid));
@@ -3450,13 +3447,11 @@
   /* R2: requested array length argument. */
   __ tst(R2, Operand(kSmiTagMask));
   __ b(&call_runtime, NE);
-  __ CompareImmediate(R2, 0);
-  __ b(&call_runtime, LT);
   __ SmiUntag(R2);
-  /* Check for maximum allowed length. */
+  /* Check for length >= 0 && length <= max_len. */
   /* R2: untagged array length. */
   __ CompareImmediate(R2, max_len);
-  __ b(&call_runtime, GT);
+  __ b(&call_runtime, HI);
   __ mov(R2, Operand(R2, LSL, scale_shift));
   const intptr_t fixed_size_plus_alignment_padding =
       target::TypedData::InstanceSize() +
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 01b54d7..35c6bcf 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -1128,18 +1128,14 @@
     // and is computed as:
     // RoundedAllocationSize(
     //     (array_length * kwordSize) + target::Array::header_size()).
-    // Assert that length is a Smi.
-    __ tsti(R2, Immediate(kSmiTagMask));
-    __ b(&slow_case, NE);
+    // Check that length is a Smi.
+    __ BranchIfNotSmi(R2, &slow_case);
 
-    __ cmp(R2, Operand(0));
-    __ b(&slow_case, LT);
-
-    // Check for maximum allowed length.
+    // Check length >= 0 && length <= kMaxNewSpaceElements
     const intptr_t max_len =
         target::ToRawSmi(target::Array::kMaxNewSpaceElements);
     __ CompareImmediate(R2, max_len);
-    __ b(&slow_case, GT);
+    __ b(&slow_case, HI);
 
     const intptr_t cid = kArrayCid;
     NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, R4, &slow_case));
@@ -3594,13 +3590,11 @@
   /* Check that length is a positive Smi. */
   /* R2: requested array length argument. */
   __ BranchIfNotSmi(R2, &call_runtime);
-  __ CompareRegisters(R2, ZR);
-  __ b(&call_runtime, LT);
   __ SmiUntag(R2);
-  /* Check for maximum allowed length. */
+  /* Check for length >= 0 && length <= max_len. */
   /* R2: untagged array length. */
   __ CompareImmediate(R2, max_len);
-  __ b(&call_runtime, GT);
+  __ b(&call_runtime, HI);
   __ LslImmediate(R2, R2, scale_shift);
   const intptr_t fixed_size_plus_alignment_padding =
       target::TypedData::InstanceSize() +
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 229be66..7dcc08e 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -804,25 +804,21 @@
 // Uses EAX, EBX, ECX, EDI  as temporary registers.
 // The newly allocated object is returned in EAX.
 void StubCodeCompiler::GenerateAllocateArrayStub(Assembler* assembler) {
-  Label slow_case;
-  // Compute the size to be allocated, it is based on the array length
-  // and is computed as:
-  // RoundedAllocationSize(
-  //     (array_length * kwordSize) + target::Array::header_size()).
-  // Assert that length is a Smi.
-  __ testl(EDX, Immediate(kSmiTagMask));
-
   if (!FLAG_use_slow_path) {
+    Label slow_case;
+    // Compute the size to be allocated, it is based on the array length
+    // and is computed as:
+    // RoundedAllocationSize(
+    //     (array_length * kwordSize) + target::Array::header_size()).
+    // Assert that length is a Smi.
+    __ testl(EDX, Immediate(kSmiTagMask));
     __ j(NOT_ZERO, &slow_case);
 
-    __ cmpl(EDX, Immediate(0));
-    __ j(LESS, &slow_case);
-
     // Check for maximum allowed length.
     const Immediate& max_len =
         Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
     __ cmpl(EDX, max_len);
-    __ j(GREATER, &slow_case);
+    __ j(ABOVE, &slow_case);
 
     NOT_IN_PRODUCT(__ MaybeTraceAllocation(kArrayCid, EAX, &slow_case,
                                            Assembler::kFarJump));
@@ -2948,13 +2944,11 @@
   /* EDI: requested array length argument. */
   __ testl(EDI, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &call_runtime);
-  __ cmpl(EDI, Immediate(0));
-  __ j(LESS, &call_runtime);
   __ SmiUntag(EDI);
-  /* Check for maximum allowed length. */
+  /* Check for length >= 0 && length <= max_len. */
   /* EDI: untagged array length. */
   __ cmpl(EDI, Immediate(max_len));
-  __ j(GREATER, &call_runtime);
+  __ j(ABOVE, &call_runtime);
   /* Special case for scaling by 16. */
   if (scale_factor == TIMES_16) {
     /* double length of array. */
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index e852d5a..9141a0c 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -1060,17 +1060,15 @@
     // RoundedAllocationSize(
     //     (array_length * target::kwordSize) + target::Array::header_size()).
     __ movq(RDI, R10);  // Array Length.
-    // Check that length is a positive Smi.
+    // Check that length is Smi.
     __ testq(RDI, Immediate(kSmiTagMask));
     __ j(NOT_ZERO, &slow_case);
 
-    __ cmpq(RDI, Immediate(0));
-    __ j(LESS, &slow_case);
-    // Check for maximum allowed length.
+    // Check length >= 0 && length <= kMaxNewSpaceElements
     const Immediate& max_len =
         Immediate(target::ToRawSmi(target::Array::kMaxNewSpaceElements));
     __ cmpq(RDI, max_len);
-    __ j(GREATER, &slow_case);
+    __ j(ABOVE, &slow_case);
 
     // Check for allocation tracing.
     NOT_IN_PRODUCT(
@@ -3538,13 +3536,11 @@
   /* RDI: requested array length argument. */
   __ testq(RDI, Immediate(kSmiTagMask));
   __ j(NOT_ZERO, &call_runtime);
-  __ cmpq(RDI, Immediate(0));
-  __ j(LESS, &call_runtime);
   __ SmiUntag(RDI);
-  /* Check for maximum allowed length. */
+  /* Check for length >= 0 && length <= max_len. */
   /* RDI: untagged array length. */
   __ cmpq(RDI, Immediate(max_len));
-  __ j(GREATER, &call_runtime);
+  __ j(ABOVE, &call_runtime);
   /* Special case for scaling by 16. */
   if (scale_factor == TIMES_16) {
     /* double length of array. */
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 9df4745..e6df0a6 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -732,6 +732,10 @@
 
 ### getAllocationTraces
 
+```
+CpuSamples getAllocationTraces(string isolateId, int timeOriginMicros [optional], int timeExtentMicros [optional], string classId [optional])
+```
+
 The _getAllocationTraces_ RPC allows for the retrieval of allocation traces for objects of a
 specific set of types (see [setTraceClassAllocation](#setTraceClassAllocation)). Only samples
 collected in the time range `[timeOriginMicros, timeOriginMicros + timeExtentMicros]` will be
@@ -744,10 +748,6 @@
 
 If isolateId refers to an isolate which has exited, then the Collected Sentinel is returned.
 
-```
-CpuSamples getAllocationTraces(string isolateId, int timeOriginMicros [optional], int timeExtentMicros [optional], string classId [optional])
-```
-
 See [CpuSamples](#cpusamples).
 
 ### getClassList
@@ -1385,16 +1385,16 @@
 
 ### setTraceClassAllocation
 
+```
+Success|Sentinel setTraceClassAllocation(string isolateId, string classId, bool enable)
+```
+
 The _setTraceClassAllocation_ RPC allows for enabling or disabling allocation tracing for a specific type of object. Allocation traces can be retrieved with the _getAllocationTraces_ RPC.
 
 If `enable` is true, allocations of objects of the class represented by `classId` will be traced.
 
 If `isolateId` refers to an isolate which has exited, then the _Collected_ [Sentinel](#sentinel) is returned.
 
-```
-Success|Sentinel setTraceClassAllocation(string isolateId, string classId, bool enable)
-```
-
 See [Success](#success).
 
 ### setVMName
@@ -3996,8 +3996,6 @@
 3.40 | Added `IsolateFlag` object and `isolateFlags` property to `Isolate`.
 3.41 | Added `PortList` object, `ReceivePort` `InstanceKind`, and `getPorts` RPC.
 3.42 | Added `limit` optional parameter to `getStack` RPC.
-3.43 | Updated heap snapshot format to include identity hash codes. Added `getAllocationTraces`
-and `setTraceClassAllocation` RPCs, updated `CpuSample` to include `identityHashCode` and
-`classId` properties, updated `Class` to include `traceAllocations` property.
+3.43 | Updated heap snapshot format to include identity hash codes. Added `getAllocationTraces` and `setTraceClassAllocation` RPCs, updated `CpuSample` to include `identityHashCode` and `classId` properties, updated `Class` to include `traceAllocations` property.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/tools/VERSION b/tools/VERSION
index c32fee5..c251049 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 13
 PATCH 0
-PRERELEASE 56
+PRERELEASE 57
 PRERELEASE_PATCH 0
\ No newline at end of file
