// 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 'dart:async';

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/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/dart/analysis/restricted_analysis_context.dart';
import 'package:analyzer/src/dart/analysis/session.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/summary/summary_file_builder.dart';
import 'package:analyzer/src/test_utilities/mock_sdk.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';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AbstractContextManagerTest);
    defineReflectiveTests(ContextManagerWithNewOptionsTest);
    defineReflectiveTests(ContextManagerWithOldOptionsTest);
  });
}

/// 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() {
    String subProjPath = join(projPath, 'subproj');
    Folder subProjFolder = resourceProvider.newFolder(subProjPath);
    resourceProvider.newFile(join(subProjPath, 'pubspec.yaml'), 'contents');
    String subProjFilePath = join(subProjPath, 'file.dart');
    resourceProvider.newFile(subProjFilePath, 'contents');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // Make sure that there really are contexts for both the main project and
    // the subproject.
    Folder projectFolder = resourceProvider.getFolder(projPath);
    ContextInfo projContextInfo = manager.getContextInfoFor(projectFolder);
    expect(projContextInfo, isNotNull);
    expect(projContextInfo.folder, projectFolder);
    ContextInfo subProjContextInfo = manager.getContextInfoFor(subProjFolder);
    expect(subProjContextInfo, isNotNull);
    expect(subProjContextInfo.folder, subProjFolder);
    expect(projContextInfo.analysisDriver,
        isNot(equals(subProjContextInfo.analysisDriver)));
    // Check that getDriversInAnalysisRoot() works.
    List<AnalysisDriver> drivers =
        manager.getDriversInAnalysisRoot(projectFolder);
    expect(drivers, isNotNull);
    expect(drivers, hasLength(2));
    expect(drivers, contains(projContextInfo.analysisDriver));
    expect(drivers, contains(subProjContextInfo.analysisDriver));
  }

  @failingTest
  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.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/nope.dart');
    String embedderPath = '$projPath/embedder';
    newFile('$embedderPath/entry.dart');
    String 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"
  ''');

    Folder projectFolder = resourceProvider.newFolder(projPath);

    // NOTE that this is Not in our package path yet.

    // Setup context.
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    await pumpEventQueue();
    // Confirm that one driver / context was created.
    List<AnalysisDriver> 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);
  }

  test_embedder_packagespec() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/nope.dart');
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$sdkExtPath/entry.dart');
    String 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'''
test_pack:lib/''');
    // Setup context.

    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    await pumpEventQueue();
    // Confirm that one context was created.
    int count = manager
        .numberOfContextsInAnalysisRoot(resourceProvider.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
    String project = convertPath('/project');
    String excludedFolder = convertPath('$project/excluded');
    // set roots
    resourceProvider.newFolder(project);
    resourceProvider.newFolder(excludedFolder);
    manager.setRoots(
        <String>[project], <String>[excludedFolder], <String, String>{});
    // verify
    expect(manager.isInAnalysisRoot(convertPath('$excludedFolder/test.dart')),
        isFalse);
  }

  void test_isInAnalysisRoot_inNestedContext() {
    String subProjPath = join(projPath, 'subproj');
    Folder subProjFolder = resourceProvider.newFolder(subProjPath);
    resourceProvider.newFile(join(subProjPath, 'pubspec.yaml'), 'contents');
    String subProjFilePath = join(subProjPath, 'file.dart');
    resourceProvider.newFile(subProjFilePath, 'contents');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // Make sure that there really is a context for the subproject.
    ContextInfo 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>[], <String, String>{});
    expect(manager.isInAnalysisRoot('$projPath/test.dart'), isTrue);
  }

  void test_isInAnalysisRoot_notInRoot() {
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    expect(manager.isInAnalysisRoot('/test.dart'), isFalse);
  }

  test_packagesFolder_areAnalyzed() {
    // create a context with a pubspec.yaml file
    String pubspecPath = join(projPath, 'pubspec.yaml');
    resourceProvider.newFile(pubspecPath, 'pubspec');
    // create a file in the "packages" folder
    String filePath1 = join(projPath, 'packages', 'file1.dart');
    File file1 = resourceProvider.newFile(filePath1, 'contents');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    expect(callbacks.currentFilePaths, unorderedEquals([file1.path]));
    String filePath2 = join(projPath, 'packages', 'file2.dart');
    File file2 = resourceProvider.newFile(filePath2, 'contents');
    return pumpEventQueue().then((_) {
      expect(callbacks.currentFilePaths,
          unorderedEquals([file1.path, file2.path]));
    });
  }

  test_path_filter() async {
    // Setup context.
    Folder root = resourceProvider.newFolder(projPath);
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    expect(callbacks.currentFilePaths, isEmpty);
    // Set ignore patterns for context.
    ContextInfo rootInfo = manager.getContextInfoFor(root);
    manager.setIgnorePatternsForContext(
        rootInfo, ['sdk_ext/**', 'lib/ignoreme.dart']);
    // Start creating files.
    newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/ignoreme.dart');
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$sdkExtPath/entry.dart');
    String sdkExtSrcPath = '$projPath/sdk_ext/src';
    newFile('$sdkExtSrcPath/part.dart');
    // Pump event loop so new files are discovered and added to context.
    await pumpEventQueue();
    // Verify that ignored files were ignored.
    Iterable<String> filePaths = callbacks.currentFilePaths;
    expect(filePaths, hasLength(1));
    expect(filePaths, contains(convertPath('/my/proj/lib/main.dart')));
  }

  test_refresh_folder_with_packagespec() {
    // create a context with a .packages file
    String packagespecFile = join(projPath, '.packages');
    resourceProvider.newFile(packagespecFile, '');
    manager.setRoots(<String>[projPath], <String>[], <String, 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.
  test_refresh_folder_with_packagespec_subfolders() {
    // Create a folder with no .packages file, containing two subfolders with
    // .packages files.
    String subdir1Path = join(projPath, 'subdir1');
    String subdir2Path = join(projPath, 'subdir2');
    String packagespec1Path = join(subdir1Path, '.packages');
    String packagespec2Path = join(subdir2Path, '.packages');
    resourceProvider.newFile(packagespec1Path, '');
    resourceProvider.newFile(packagespec2Path, '');
    manager.setRoots(<String>[projPath], <String>[], <String, 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);
      });
    });
  }

  test_refresh_folder_with_pubspec() {
    // create a context with a pubspec.yaml file
    String pubspecPath = join(projPath, 'pubspec.yaml');
    resourceProvider.newFile(pubspecPath, 'pubspec');
    manager.setRoots(<String>[projPath], <String>[], <String, 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);
      });
    });
  }

  test_refresh_folder_with_pubspec_subfolders() {
    // Create a folder with no pubspec.yaml, containing two subfolders with
    // pubspec.yaml files.
    String subdir1Path = join(projPath, 'subdir1');
    String subdir2Path = join(projPath, 'subdir2');
    String pubspec1Path = join(subdir1Path, 'pubspec.yaml');
    String pubspec2Path = join(subdir2Path, 'pubspec.yaml');
    resourceProvider.newFile(pubspec1Path, 'pubspec');
    resourceProvider.newFile(pubspec2Path, 'pubspec');
    manager.setRoots(<String>[projPath], <String>[], <String, 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);
      });
    });
  }

  test_refresh_oneContext() {
    // create two contexts with pubspec.yaml files
    String pubspecPath = join(projPath, 'pubspec.yaml');
    resourceProvider.newFile(pubspecPath, 'pubspec1');

    String proj2Path = convertPath('/my/proj2');
    resourceProvider.newFolder(proj2Path);
    String pubspec2Path = join(proj2Path, 'pubspec.yaml');
    resourceProvider.newFile(pubspec2Path, 'pubspec2');

    List<String> roots = <String>[projPath, proj2Path];
    manager.setRoots(roots, <String>[], <String, String>{});
    return pumpEventQueue().then((_) {
      expect(callbacks.currentContextRoots, unorderedEquals(roots));
      int then = callbacks.now;
      callbacks.now++;
      manager.refresh([resourceProvider.getResource(proj2Path)]);
      return pumpEventQueue().then((_) {
        expect(callbacks.currentContextRoots, unorderedEquals(roots));
        expect(callbacks.currentContextTimestamps[projPath], then);
        expect(callbacks.currentContextTimestamps[proj2Path], callbacks.now);
      });
    });
  }

  test_sdk_ext_packagespec() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/nope.dart');
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$sdkExtPath/entry.dart');
    String sdkExtSrcPath = '$projPath/sdk_ext/src';
    newFile('$sdkExtSrcPath/part.dart');
    // Setup sdk extension mapping.
    newFile('$libPath/_sdkext', content: r'''
{
  "dart:foobar": "../sdk_ext/entry.dart"
}
''');
    // Setup .packages file
    newFile('$projPath/.packages', content: r'''
test_pack:lib/''');
    // Setup context.
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // Confirm that one context was created.
    int count = manager
        .numberOfContextsInAnalysisRoot(resourceProvider.newFolder(projPath));
    expect(count, equals(1));
    var source = sourceFactory.forUri('dart:foobar');
    expect(source.fullName, equals(convertPath('/my/proj/sdk_ext/entry.dart')));
  }

  void test_setRoots_addFolderWithDartFile() {
    String filePath = resourceProvider.pathContext.join(projPath, 'foo.dart');
    resourceProvider.newFile(filePath, 'contents');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // verify
    Iterable<String> filePaths = callbacks.currentFilePaths;
    expect(filePaths, hasLength(1));
    expect(filePaths, contains(filePath));
    List<AnalysisDriver> drivers =
        manager.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath));
    expect(drivers, hasLength(1));
    expect(drivers[0], isNotNull);
    Source result = sourceFactory.forUri('dart:async');
    expect(result, isNotNull);
  }

  void test_setRoots_addFolderWithDartFileInSubfolder() {
    String filePath = join(projPath, 'foo', 'bar.dart');
    resourceProvider.newFile(filePath, 'contents');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // verify
    Iterable<String> filePaths = callbacks.currentFilePaths;
    expect(filePaths, hasLength(1));
    expect(filePaths, contains(filePath));
  }

  void test_setRoots_addFolderWithDummyLink() {
    String filePath = join(projPath, 'foo.dart');
    resourceProvider.newDummyLink(filePath);
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // verify
    expect(callbacks.currentFilePaths, isEmpty);
  }

  void test_setRoots_addFolderWithNestedPackageSpec() {
    String examplePath =
        convertPath('$projPath/${ContextManagerTest.EXAMPLE_NAME}');
    String 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>[], <String, String>{});

    expect(callbacks.currentContextRoots, hasLength(2));

    expect(callbacks.currentContextRoots, contains(projPath));
    Iterable<Source> projSources = callbacks.currentFileSources(projPath);
    expect(projSources, hasLength(1));
    expect(projSources.first.uri.toString(),
        (new Uri.file(join(libPath, 'main.dart')).toString()));

    expect(callbacks.currentContextRoots, contains(examplePath));
    Iterable<Source> exampleSources = callbacks.currentFileSources(examplePath);
    expect(exampleSources, hasLength(1));
    expect(exampleSources.first.uri.toString(),
        (new Uri.file(join(examplePath, 'example.dart')).toString()));
  }

  void test_setRoots_addFolderWithNestedPubspec() {
    String examplePath =
        convertPath('$projPath/${ContextManagerTest.EXAMPLE_NAME}');
    String 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>[], <String, String>{});

    expect(callbacks.currentContextRoots, hasLength(2));

    expect(callbacks.currentContextRoots, contains(projPath));
    Iterable<Source> projSources = callbacks.currentFileSources(projPath);
    expect(projSources, hasLength(1));
    expect(projSources.first.uri.toString(), 'package:proj/main.dart');

    expect(callbacks.currentContextRoots, contains(examplePath));
    Iterable<Source> exampleSources = callbacks.currentFileSources(examplePath);
    expect(exampleSources, hasLength(1));
    expect(exampleSources.first.uri.toString(),
        (new Uri.file('$examplePath/example.dart').toString()));
  }

  void test_setRoots_addFolderWithoutPubspec() {
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // verify
    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
    expect(callbacks.currentFilePaths, hasLength(0));
  }

  void test_setRoots_addFolderWithPackagespec() {
    String packagespecPath = join(projPath, '.packages');
    var testLib = convertPath('/home/somebody/.pub/cache/unittest-0.9.9/lib');
    var testLibUri = resourceProvider.pathContext.toUri(testLib);
    resourceProvider.newFile(packagespecPath, 'unittest:$testLibUri');
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    File mainFile = newFile('$libPath/main.dart');
    Source source = mainFile.createSource();

    manager.setRoots(<String>[projPath], <String>[], <String, String>{});

    // verify
    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
    expect(callbacks.currentFilePaths, hasLength(1));

    // smoketest resolution
    Source resolvedSource =
        sourceFactory.resolveUri(source, 'package:unittest/unittest.dart');
    expect(resolvedSource, isNotNull);
    expect(resolvedSource.fullName, convertPath('$testLib/unittest.dart'));
  }

  void test_setRoots_addFolderWithPackagespecAndPackageRoot() {
    // The package root should take priority.
    String packagespecPath = join(projPath, '.packages');
    var testLib = convertPath('/home/somebody/.pub/cache/unittest-0.9.9/lib');
    var testLibUri = resourceProvider.pathContext.toUri(testLib);
    resourceProvider.newFile(packagespecPath, 'unittest:$testLibUri');
    String packageRootPath = '/package/root/';
    manager.setRoots(<String>[projPath], <String>[],
        <String, String>{projPath: packageRootPath});
    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
    _checkPackageRoot(projPath, packageRootPath);
  }

  void test_setRoots_addFolderWithPubspec() {
    String pubspecPath = join(projPath, 'pubspec.yaml');
    resourceProvider.newFile(pubspecPath, 'pubspec');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // verify
    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
    expect(callbacks.currentFilePaths, hasLength(0));
  }

  void test_setRoots_addFolderWithPubspec_andPackagespec() {
    String pubspecPath = join(projPath, 'pubspec.yaml');
    String packagespecPath = join(projPath, '.packages');
    resourceProvider.newFile(pubspecPath, 'pubspec');
    resourceProvider.newFile(packagespecPath, '');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // verify
    callbacks.assertContextPaths([projPath]);
  }

  void test_setRoots_addFolderWithPubspecAndLib() {
    String binPath = '$projPath/${ContextManagerTest.BIN_NAME}';
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    String srcPath = '$libPath/${ContextManagerTest.SRC_NAME}';
    String testPath = '$projPath/${ContextManagerTest.TEST_NAME}';

    newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
        content: 'proj:lib/');
    String appPath = newFile('$binPath/app.dart').path;
    newFile('$libPath/main.dart');
    newFile('$srcPath/internal.dart');
    String testFilePath = newFile('$testPath/main_test.dart').path;

    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    Iterable<Source> sources = callbacks.currentFileSources(projPath);

    expect(callbacks.currentContextRoots, unorderedEquals([projPath]));
    expect(sources, hasLength(4));
    List<String> uris =
        sources.map((Source source) => source.uri.toString()).toList();
    expect(uris, contains((new Uri.file(appPath)).toString()));
    expect(uris, contains('package:proj/main.dart'));
    expect(uris, contains('package:proj/src/internal.dart'));
    expect(uris, contains((new Uri.file(testFilePath)).toString()));
  }

  void test_setRoots_addFolderWithPubspecAndPackagespecFolders() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProjectA = convertPath('$root/sub/aaa');
    String subProjectB = convertPath('$root/sub/sub2/bbb');
    String subProjectA_file = convertPath('$subProjectA/bin/a.dart');
    String 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>[], <String, 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
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String projectA = convertPath('$root/sub/aaa');
    String projectALib = convertPath('$root/sub/aaa/lib');
    String subProjectA_file = convertPath('$projectA/bin/a.dart');
    String projectB = convertPath('$root/sub/sub2/bbb');
    String projectBLib = convertPath('$root/sub/sub2/bbb/lib');
    String 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/');
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subProjectA_file, 'library a;');
    resourceProvider.newFile(subProjectB_file, 'library b;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, 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': [resourceProvider.getFolder(projectALib)]
        }));
    expect(
        _packageMap(projectB),
        equals({
          'bar': [resourceProvider.getFolder(projectBLib)]
        }));
  }

  void test_setRoots_addPackageRoot() {
    String packagePathFoo = convertPath('/package1/foo');
    String packageRootPath = convertPath('/package2/foo');
    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
        content: 'foo:file:///package1/foo');
    Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
    List<String> includedPaths = <String>[projPath];
    List<String> excludedPaths = <String>[];
    manager.setRoots(includedPaths, excludedPaths, <String, String>{});
    expect(
        _currentPackageMap,
        equals({
          'foo': [packageFolder]
        }));
    manager.setRoots(includedPaths, excludedPaths,
        <String, String>{projPath: packageRootPath});
    _checkPackageRoot(projPath, equals(packageRootPath));
  }

  void test_setRoots_changePackageRoot() {
    String packageRootPath1 = '/package1';
    String packageRootPath2 = '/package2';
    List<String> includedPaths = <String>[projPath];
    List<String> excludedPaths = <String>[];
    manager.setRoots(includedPaths, excludedPaths,
        <String, String>{projPath: packageRootPath1});
    _checkPackageRoot(projPath, equals(packageRootPath1));
    manager.setRoots(includedPaths, excludedPaths,
        <String, String>{projPath: packageRootPath2});
    _checkPackageRoot(projPath, equals(packageRootPath2));
  }

  void test_setRoots_exclude_newRoot_withExcludedFile() {
    // prepare paths
    String project = convertPath('/project');
    String file1 = convertPath('$project/file1.dart');
    String file2 = convertPath('$project/file2.dart');
    // create files
    resourceProvider.newFile(file1, '// 1');
    resourceProvider.newFile(file2, '// 2');
    // set roots
    manager.setRoots(<String>[project], <String>[file1], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [file2]);
  }

  void test_setRoots_exclude_newRoot_withExcludedFolder() {
    // prepare paths
    String project = convertPath('/project');
    String folderA = convertPath('$project/aaa');
    String folderB = convertPath('$project/bbb');
    String fileA = convertPath('$folderA/a.dart');
    String fileB = convertPath('$folderB/b.dart');
    // create files
    resourceProvider.newFile(fileA, 'library a;');
    resourceProvider.newFile(fileB, 'library b;');
    // set roots
    manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
  }

  void test_setRoots_exclude_sameRoot_addExcludedFile() {
    // prepare paths
    String project = convertPath('/project');
    String file1 = convertPath('$project/file1.dart');
    String file2 = convertPath('$project/file2.dart');
    // create files
    resourceProvider.newFile(file1, '// 1');
    resourceProvider.newFile(file2, '// 2');
    // set roots
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [file1, file2]);
    // exclude "2"
    manager.setRoots(<String>[project], <String>[file2], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [file1]);
  }

  void test_setRoots_exclude_sameRoot_addExcludedFolder() {
    // prepare paths
    String project = convertPath('/project');
    String folderA = convertPath('$project/aaa');
    String folderB = convertPath('$project/bbb');
    String fileA = convertPath('$folderA/a.dart');
    String fileB = convertPath('$folderB/b.dart');
    // create files
    resourceProvider.newFile(fileA, 'library a;');
    resourceProvider.newFile(fileB, 'library b;');
    // initially both "aaa/a" and "bbb/b" are included
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA, fileB]);
    // exclude "bbb/"
    manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
  }

  void test_setRoots_exclude_sameRoot_removeExcludedFile() {
    // prepare paths
    String project = convertPath('/project');
    String file1 = convertPath('$project/file1.dart');
    String file2 = convertPath('$project/file2.dart');
    // create files
    resourceProvider.newFile(file1, '// 1');
    resourceProvider.newFile(file2, '// 2');
    // set roots
    manager.setRoots(<String>[project], <String>[file2], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [file1]);
    // stop excluding "2"
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [file1, file2]);
  }

  void test_setRoots_exclude_sameRoot_removeExcludedFile_inFolder() {
    // prepare paths
    String project = convertPath('/project');
    String file1 = convertPath('$project/bin/file1.dart');
    String file2 = convertPath('$project/bin/file2.dart');
    // create files
    resourceProvider.newFile(file1, '// 1');
    resourceProvider.newFile(file2, '// 2');
    // set roots
    manager.setRoots(<String>[project], <String>[file2], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [file1]);
    // stop excluding "2"
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [file1, file2]);
  }

  void test_setRoots_exclude_sameRoot_removeExcludedFolder() {
    // prepare paths
    String project = convertPath('/project');
    String folderA = convertPath('$project/aaa');
    String folderB = convertPath('$project/bbb');
    String fileA = convertPath('$folderA/a.dart');
    String fileB = convertPath('$folderB/b.dart');
    // create files
    resourceProvider.newFile(fileA, 'library a;');
    resourceProvider.newFile(fileB, 'library b;');
    // exclude "bbb/"
    manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
    // stop excluding "bbb/"
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA, fileB]);
  }

  void test_setRoots_ignoreDocFolder() {
    String project = convertPath('/project');
    String fileA = convertPath('$project/foo.dart');
    String fileB = convertPath('$project/lib/doc/bar.dart');
    String fileC = convertPath('$project/doc/bar.dart');
    resourceProvider.newFile(fileA, '');
    resourceProvider.newFile(fileB, '');
    resourceProvider.newFile(fileC, '');
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA, fileB]);
  }

  void test_setRoots_nested_includedByOuter_innerFirst() {
    String project = convertPath('/project');
    String projectPubspec = convertPath('$project/pubspec.yaml');
    String example = convertPath('$project/example');
    String examplePubspec = convertPath('$example/pubspec.yaml');
    // create files
    resourceProvider.newFile(projectPubspec, 'name: project');
    resourceProvider.newFile(examplePubspec, 'name: example');
    manager
        .setRoots(<String>[example, project], <String>[], <String, String>{});
    // verify
    {
      ContextInfo rootInfo = manager.rootInfo;
      expect(rootInfo.children, hasLength(1));
      {
        ContextInfo projectInfo = rootInfo.children[0];
        expect(projectInfo.folder.path, project);
        expect(projectInfo.children, hasLength(1));
        {
          ContextInfo 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() {
    String project = convertPath('/project');
    String projectPubspec = convertPath('$project/pubspec.yaml');
    String example = convertPath('$project/example');
    // create files
    resourceProvider.newFile(projectPubspec, 'name: project');
    resourceProvider.newFolder(example);
    manager
        .setRoots(<String>[project, example], <String>[], <String, String>{});
    // verify
    {
      ContextInfo rootInfo = manager.rootInfo;
      expect(rootInfo.children, hasLength(1));
      {
        ContextInfo projectInfo = rootInfo.children[0];
        expect(projectInfo.folder.path, project);
        expect(projectInfo.children, isEmpty);
      }
    }
    expect(callbacks.currentContextRoots, unorderedEquals([project]));
  }

  void test_setRoots_nested_includedByOuter_twoPubspecs() {
    String project = convertPath('/project');
    String projectPubspec = convertPath('$project/pubspec.yaml');
    String example = convertPath('$project/example');
    String examplePubspec = convertPath('$example/pubspec.yaml');
    // create files
    resourceProvider.newFile(projectPubspec, 'name: project');
    resourceProvider.newFile(examplePubspec, 'name: example');
    manager
        .setRoots(<String>[project, example], <String>[], <String, String>{});
    // verify
    {
      ContextInfo rootInfo = manager.rootInfo;
      expect(rootInfo.children, hasLength(1));
      {
        ContextInfo projectInfo = rootInfo.children[0];
        expect(projectInfo.folder.path, project);
        expect(projectInfo.children, hasLength(1));
        {
          ContextInfo exampleInfo = projectInfo.children[0];
          expect(exampleInfo.folder.path, example);
          expect(exampleInfo.children, isEmpty);
        }
      }
    }
    expect(callbacks.currentContextRoots, unorderedEquals([project, example]));
  }

  void test_setRoots_newFolderWithPackageRoot() {
    String packageRootPath = '/package';
    manager.setRoots(<String>[projPath], <String>[],
        <String, String>{projPath: packageRootPath});
    _checkPackageRoot(projPath, equals(packageRootPath));
  }

  void test_setRoots_newlyAddedFoldersGetProperPackageMap() {
    String packagePath = convertPath('/package/foo');
    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
        content: 'foo:file:///package/foo');
    Folder packageFolder = resourceProvider.newFolder(packagePath);
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    expect(
        _currentPackageMap,
        equals({
          'foo': [packageFolder]
        }));
  }

  void test_setRoots_noContext_excludedFolder() {
    // prepare paths
    String project = convertPath('/project');
    String excludedFolder = convertPath('$project/excluded');
    String excludedPubspec = convertPath('$excludedFolder/pubspec.yaml');
    // create files
    resourceProvider.newFile(excludedPubspec, 'name: ignore-me');
    // set "/project", and exclude "/project/excluded"
    manager.setRoots(
        <String>[project], <String>[excludedFolder], <String, String>{});
    callbacks.assertContextPaths([project]);
  }

  void test_setRoots_noContext_inDotFolder() {
    String pubspecPath = join(projPath, '.pub', 'pubspec.yaml');
    resourceProvider.newFile(pubspecPath, 'name: test');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // verify
    expect(callbacks.currentContextRoots, hasLength(1));
    expect(callbacks.currentContextRoots, contains(projPath));
    expect(callbacks.currentFilePaths, hasLength(0));
  }

  void test_setRoots_packageResolver() {
    String filePath = join(projPath, 'lib', 'foo.dart');
    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
        content: 'foo:lib/');
    resourceProvider.newFile(filePath, 'contents');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});

    var drivers =
        manager.getDriversInAnalysisRoot(resourceProvider.newFolder(projPath));
    expect(drivers, hasLength(1));
    expect(drivers[0], isNotNull);
    Source result = sourceFactory.forUri('package:foo/foo.dart');
    expect(result.fullName, filePath);
  }

  void test_setRoots_packagesFolder_hasContext() {
    String pubspecPath = join(projPath, 'packages', 'pubspec.yaml');
    resourceProvider.newFile(pubspecPath, 'name: test');
    manager.setRoots(<String>[projPath], <String>[], <String, 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.
    String project = convertPath('/project');
    String fileA = convertPath('$project/foo.dart');
    String fileB = convertPath('$project/.pub/bar.dart');
    resourceProvider.newFile(fileA, '');
    resourceProvider.newFile(fileB, '');
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
  }

  void test_setRoots_removeFolderWithoutPubspec() {
    // add one root - there is a context
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    expect(callbacks.currentContextRoots, hasLength(1));
    // set empty roots - no contexts
    manager.setRoots(<String>[], <String>[], <String, String>{});
    expect(callbacks.currentContextRoots, hasLength(0));
    expect(callbacks.currentFilePaths, hasLength(0));
  }

  void test_setRoots_removeFolderWithPackagespec() {
    // create a pubspec
    String pubspecPath = join(projPath, '.packages');
    resourceProvider.newFile(pubspecPath, '');
    // add one root - there is a context
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    expect(manager.changeSubscriptions, hasLength(1));
    expect(callbacks.currentContextRoots, hasLength(1));
    // set empty roots - no contexts
    manager.setRoots(<String>[], <String>[], <String, String>{});
    expect(manager.changeSubscriptions, hasLength(0));
    expect(callbacks.currentContextRoots, hasLength(0));
    expect(callbacks.currentFilePaths, hasLength(0));
  }

  void test_setRoots_removeFolderWithPackagespecFolder() {
    // prepare paths
    String projectA = convertPath('/projectA');
    String projectB = convertPath('/projectB');
    String subProjectA = convertPath('$projectA/sub');
    String subProjectB = convertPath('$projectB/sub');
    String projectA_file = convertPath('$projectA/a.dart');
    String projectB_file = convertPath('$projectB/a.dart');
    String subProjectA_pubspec = convertPath('$subProjectA/.packages');
    String subProjectB_pubspec = convertPath('$subProjectB/.packages');
    String subProjectA_file = convertPath('$subProjectA/bin/sub_a.dart');
    String subProjectB_file = convertPath('$subProjectB/bin/sub_b.dart');
    // create files
    resourceProvider.newFile(projectA_file, '// a');
    resourceProvider.newFile(projectB_file, '// b');
    resourceProvider.newFile(subProjectA_pubspec, '');
    resourceProvider.newFile(subProjectB_pubspec, '');
    resourceProvider.newFile(subProjectA_file, '// sub-a');
    resourceProvider.newFile(subProjectB_file, '// sub-b');
    // set roots
    manager
        .setRoots(<String>[projectA, projectB], <String>[], <String, 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>[], <String, String>{});
    callbacks.assertContextPaths([projectA, subProjectA]);
    callbacks.assertContextFiles(projectA, [projectA_file]);
    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
  }

  void test_setRoots_removeFolderWithPubspec() {
    // create a pubspec
    String pubspecPath = join(projPath, 'pubspec.yaml');
    resourceProvider.newFile(pubspecPath, 'pubspec');
    // add one root - there is a context
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    expect(callbacks.currentContextRoots, hasLength(1));
    // set empty roots - no contexts
    manager.setRoots(<String>[], <String>[], <String, String>{});
    expect(callbacks.currentContextRoots, hasLength(0));
    expect(callbacks.currentFilePaths, hasLength(0));
  }

  void test_setRoots_removeFolderWithPubspecFolder() {
    // prepare paths
    String projectA = convertPath('/projectA');
    String projectB = convertPath('/projectB');
    String subProjectA = convertPath('$projectA/sub');
    String subProjectB = convertPath('$projectB/sub');
    String projectA_file = convertPath('$projectA/a.dart');
    String projectB_file = convertPath('$projectB/a.dart');
    String subProjectA_pubspec = convertPath('$subProjectA/pubspec.yaml');
    String subProjectB_pubspec = convertPath('$subProjectB/pubspec.yaml');
    String subProjectA_file = convertPath('$subProjectA/bin/sub_a.dart');
    String subProjectB_file = convertPath('$subProjectB/bin/sub_b.dart');
    // create files
    resourceProvider.newFile(projectA_file, '// a');
    resourceProvider.newFile(projectB_file, '// b');
    resourceProvider.newFile(subProjectA_pubspec, 'pubspec');
    resourceProvider.newFile(subProjectB_pubspec, 'pubspec');
    resourceProvider.newFile(subProjectA_file, '// sub-a');
    resourceProvider.newFile(subProjectB_file, '// sub-b');
    // set roots
    manager
        .setRoots(<String>[projectA, projectB], <String>[], <String, 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>[], <String, String>{});
    callbacks.assertContextPaths([projectA, subProjectA]);
    callbacks.assertContextFiles(projectA, [projectA_file]);
    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
  }

  void test_setRoots_removePackageRoot() {
    String packagePathFoo = convertPath('/package1/foo');
    String packageRootPath = convertPath('/package2/foo');
    Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
        content: 'foo:file:///package1/foo');
    List<String> includedPaths = <String>[projPath];
    List<String> excludedPaths = <String>[];
    manager.setRoots(includedPaths, excludedPaths,
        <String, String>{projPath: packageRootPath});
    _checkPackageRoot(projPath, equals(packageRootPath));
    manager.setRoots(includedPaths, excludedPaths, <String, String>{});
    expect(
        _currentPackageMap,
        equals({
          'foo': [packageFolder]
        }));
  }

  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.
    String project = convertPath('/.pub/project');
    String fileA = convertPath('$project/foo.dart');
    resourceProvider.newFile(fileA, '');
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
  }

  test_watch_addDummyLink() {
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // empty folder initially
    expect(callbacks.currentFilePaths, isEmpty);
    // add link
    String filePath = join(projPath, 'foo.dart');
    resourceProvider.newDummyLink(filePath);
    // the link was ignored
    return pumpEventQueue().then((_) {
      expect(callbacks.currentFilePaths, isEmpty);
    });
  }

  test_watch_addFile() {
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // empty folder initially
    expect(callbacks.currentFilePaths, hasLength(0));
    // add file
    String filePath = join(projPath, 'foo.dart');
    resourceProvider.newFile(filePath, 'contents');
    // the file was added
    return pumpEventQueue().then((_) {
      Iterable<String> filePaths = callbacks.currentFilePaths;
      expect(filePaths, hasLength(1));
      expect(filePaths, contains(filePath));
    });
  }

  test_watch_addFile_excluded() {
    // prepare paths
    String project = convertPath('/project');
    String folderA = convertPath('$project/aaa');
    String folderB = convertPath('$project/bbb');
    String fileA = convertPath('$folderA/a.dart');
    String fileB = convertPath('$folderB/b.dart');
    // create files
    resourceProvider.newFile(fileA, 'library a;');
    // set roots
    manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
    // add a file, ignored as excluded
    resourceProvider.newFile(fileB, 'library b;');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([project]);
      callbacks.assertContextFiles(project, [fileA]);
    });
  }

  test_watch_addFile_inDocFolder_inner() {
    // prepare paths
    String project = convertPath('/project');
    String fileA = convertPath('$project/a.dart');
    String fileB = convertPath('$project/lib/doc/b.dart');
    // create files
    resourceProvider.newFile(fileA, '');
    // set roots
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
    // add a "lib/doc" file, it is not ignored
    resourceProvider.newFile(fileB, '');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([project]);
      callbacks.assertContextFiles(project, [fileA, fileB]);
    });
  }

  test_watch_addFile_inDocFolder_topLevel() {
    // prepare paths
    String project = convertPath('/project');
    String fileA = convertPath('$project/a.dart');
    String fileB = convertPath('$project/doc/b.dart');
    // create files
    resourceProvider.newFile(fileA, '');
    // set roots
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
    // add a "doc" file, it is ignored
    resourceProvider.newFile(fileB, '');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([project]);
      callbacks.assertContextFiles(project, [fileA]);
    });
  }

  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.
    String project = convertPath('/project');
    String fileA = convertPath('$project/foo.dart');
    String fileB = convertPath('$project/.pub/bar.dart');
    resourceProvider.newFile(fileA, '');
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
    resourceProvider.newFile(fileB, '');
    await pumpEventQueue();
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
  }

  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.
    String project = convertPath('/.pub/project');
    String fileA = convertPath('$project/foo.dart');
    String fileB = convertPath('$project/bar/baz.dart');
    resourceProvider.newFile(fileA, '');
    manager.setRoots(<String>[project], <String>[], <String, String>{});
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA]);
    resourceProvider.newFile(fileB, '');
    await pumpEventQueue();
    callbacks.assertContextPaths([project]);
    callbacks.assertContextFiles(project, [fileA, fileB]);
  }

  test_watch_addFileInSubfolder() {
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // empty folder initially
    expect(callbacks.currentFilePaths, hasLength(0));
    // add file in subfolder
    String filePath = join(projPath, 'foo', 'bar.dart');
    resourceProvider.newFile(filePath, 'contents');
    // the file was added
    return pumpEventQueue().then((_) {
      Iterable<String> filePaths = callbacks.currentFilePaths;
      expect(filePaths, hasLength(1));
      expect(filePaths, contains(filePath));
    });
  }

  test_watch_addPackagespec_toRoot() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String rootPackagespec = convertPath('$root/.packages');
    // create files
    resourceProvider.newFile(rootFile, 'library root;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile]);
    // add packagespec - still just one root
    resourceProvider.newFile(rootPackagespec, '');
    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.
    });
  }

  test_watch_addPackagespec_toSubFolder() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub/aaa');
    String subPubspec = convertPath('$subProject/.packages');
    String subFile = convertPath('$subProject/bin/a.dart');
    // create files
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subFile, 'library a;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile, subFile]);
    // add .packages
    resourceProvider.newFile(subPubspec, '');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root, subProject]);
      callbacks.assertContextFiles(root, [rootFile]);
      callbacks.assertContextFiles(subProject, [subFile]);
    });
  }

  test_watch_addPackagespec_toSubFolder_ofSubFolder() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub');
    String subPubspec = convertPath('$subProject/.packages');
    String subFile = convertPath('$subProject/bin/sub.dart');
    String subSubPubspec = convertPath('$subProject/subsub/.packages');
    // create files
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subPubspec, '');
    resourceProvider.newFile(subFile, 'library sub;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root, subProject]);
    callbacks.assertContextFiles(root, [rootFile]);
    callbacks.assertContextFiles(subProject, [subFile]);
    // add pubspec - ignore, because is already in a packagespec-based context
    resourceProvider.newFile(subSubPubspec, '');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root, subProject]);
      callbacks.assertContextFiles(root, [rootFile]);
      callbacks.assertContextFiles(subProject, [subFile]);
    });
  }

  test_watch_addPackagespec_toSubFolder_withPubspec() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub/aaa');
    String subPackagespec = convertPath('$subProject/.packages');
    String subPubspec = convertPath('$subProject/pubspec.yaml');
    String subFile = convertPath('$subProject/bin/a.dart');
    // create files
    resourceProvider.newFile(subPubspec, 'pubspec');
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subFile, 'library a;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root, subProject]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile]);
    callbacks.assertContextFiles(subProject, [subFile]);

    // add .packages
    resourceProvider.newFile(subPackagespec, '');
    return pumpEventQueue().then((_) {
      // Should NOT create another context.
      callbacks.assertContextPaths([root, subProject]);
      callbacks.assertContextFiles(root, [rootFile]);
      callbacks.assertContextFiles(subProject, [subFile]);
    });
  }

  test_watch_addPubspec_toRoot() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String rootPubspec = convertPath('$root/pubspec.yaml');
    // create files
    resourceProvider.newFile(rootFile, 'library root;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile]);
    // add pubspec - still just one root
    resourceProvider.newFile(rootPubspec, 'pubspec');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root]);
      callbacks.assertContextFiles(root, [rootFile]);
    });
  }

  test_watch_addPubspec_toSubFolder() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub/aaa');
    String subPubspec = convertPath('$subProject/pubspec.yaml');
    String subFile = convertPath('$subProject/bin/a.dart');
    // create files
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subFile, 'library a;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile, subFile]);
    // add pubspec
    resourceProvider.newFile(subPubspec, 'pubspec');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root, subProject]);
      callbacks.assertContextFiles(root, [rootFile]);
      callbacks.assertContextFiles(subProject, [subFile]);
    });
  }

  test_watch_addPubspec_toSubFolder_ofSubFolder() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub');
    String subPubspec = convertPath('$subProject/pubspec.yaml');
    String subFile = convertPath('$subProject/bin/sub.dart');
    String subSubPubspec = convertPath('$subProject/subsub/pubspec.yaml');
    // create files
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subPubspec, 'pubspec');
    resourceProvider.newFile(subFile, 'library sub;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root, subProject]);
    callbacks.assertContextFiles(root, [rootFile]);
    callbacks.assertContextFiles(subProject, [subFile]);
    // add pubspec - ignore, because is already in a pubspec-based context
    resourceProvider.newFile(subSubPubspec, 'pubspec');
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root, subProject]);
      callbacks.assertContextFiles(root, [rootFile]);
      callbacks.assertContextFiles(subProject, [subFile]);
    });
  }

  test_watch_deleteFile() {
    String filePath = join(projPath, 'foo.dart');
    // add root with a file
    File file = resourceProvider.newFile(filePath, 'contents');
    Folder projFolder = file.parent;
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // the file was added
    Iterable<String> filePaths = callbacks.currentFilePaths;
    expect(filePaths, hasLength(1));
    expect(filePaths, contains(filePath));
    expect(file.exists, isTrue);
    expect(projFolder.exists, isTrue);
    // delete the file
    resourceProvider.deleteFile(filePath);
    return pumpEventQueue().then((_) {
      expect(file.exists, isFalse);
      expect(projFolder.exists, isTrue);
      expect(callbacks.currentFilePaths, hasLength(0));
    });
  }

  test_watch_deleteFolder() {
    String filePath = join(projPath, 'foo.dart');
    // add root with a file
    File file = resourceProvider.newFile(filePath, 'contents');
    Folder projFolder = file.parent;
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // the file was added
    Iterable<String> filePaths = callbacks.currentFilePaths;
    expect(filePaths, hasLength(1));
    expect(filePaths, contains(filePath));
    expect(file.exists, isTrue);
    expect(projFolder.exists, isTrue);
    // delete the folder
    resourceProvider.deleteFolder(projPath);
    return pumpEventQueue().then((_) {
      expect(file.exists, isFalse);
      expect(projFolder.exists, isFalse);
      expect(callbacks.currentFilePaths, hasLength(0));
    });
  }

  test_watch_deletePackagespec_fromRoot() {
    // prepare paths
    String root = convertPath('/root');
    String rootPubspec = convertPath('$root/.packages');
    String rootFile = convertPath('$root/root.dart');
    // create files
    resourceProvider.newFile(rootPubspec, '');
    resourceProvider.newFile(rootFile, 'library root;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root]);
    callbacks.assertContextFiles(root, [rootFile]);
    // delete the pubspec
    resourceProvider.deleteFile(rootPubspec);
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root]);
      callbacks.assertContextFiles(root, [rootFile]);
    });
  }

  test_watch_deletePackagespec_fromSubFolder() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub/aaa');
    String subPubspec = convertPath('$subProject/.packages');
    String subFile = convertPath('$subProject/bin/a.dart');
    // create files
    resourceProvider.newFile(subPubspec, '');
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subFile, 'library a;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root, subProject]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile]);
    callbacks.assertContextFiles(subProject, [subFile]);
    // delete the pubspec
    resourceProvider.deleteFile(subPubspec);
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root]);
      callbacks.assertContextFiles(root, [rootFile, subFile]);
    });
  }

  test_watch_deletePackagespec_fromSubFolder_withPubspec() {
    // prepare paths:
    //
    // root
    //   root.dart
    //   sub
    //     aaa
    //       .packages
    //       pubspec.yaml
    //       bin
    //         a.dart
    //
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub/aaa');
    String subPackagespec = convertPath('$subProject/.packages');
    String subPubspec = convertPath('$subProject/pubspec.yaml');
    String subFile = convertPath('$subProject/bin/a.dart');
    // create files
    resourceProvider.newFile(subPackagespec, '');
    resourceProvider.newFile(subPubspec, 'pubspec');
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subFile, 'library a;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root, subProject]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile]);
    callbacks.assertContextFiles(subProject, [subFile]);
    // delete the packagespec
    resourceProvider.deleteFile(subPackagespec);
    return pumpEventQueue().then((_) {
      // Should NOT merge
      callbacks.assertContextPaths([root, subProject]);
      callbacks.assertContextFiles(subProject, [subFile]);
    });
  }

  test_watch_deletePubspec_fromRoot() {
    // prepare paths
    String root = convertPath('/root');
    String rootPubspec = convertPath('$root/pubspec.yaml');
    String rootFile = convertPath('$root/root.dart');
    // create files
    resourceProvider.newFile(rootPubspec, 'pubspec');
    resourceProvider.newFile(rootFile, 'library root;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root]);
    callbacks.assertContextFiles(root, [rootFile]);
    // delete the pubspec
    resourceProvider.deleteFile(rootPubspec);
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root]);
      callbacks.assertContextFiles(root, [rootFile]);
    });
  }

  test_watch_deletePubspec_fromSubFolder() {
    // prepare paths
    String root = convertPath('/root');
    String rootFile = convertPath('$root/root.dart');
    String subProject = convertPath('$root/sub/aaa');
    String subPubspec = convertPath('$subProject/pubspec.yaml');
    String subFile = convertPath('$subProject/bin/a.dart');
    // create files
    resourceProvider.newFile(subPubspec, 'pubspec');
    resourceProvider.newFile(rootFile, 'library root;');
    resourceProvider.newFile(subFile, 'library a;');
    // set roots
    manager.setRoots(<String>[root], <String>[], <String, String>{});
    callbacks.assertContextPaths([root, subProject]);
    // verify files
    callbacks.assertContextFiles(root, [rootFile]);
    callbacks.assertContextFiles(subProject, [subFile]);
    // delete the pubspec
    resourceProvider.deleteFile(subPubspec);
    return pumpEventQueue().then((_) {
      callbacks.assertContextPaths([root]);
      callbacks.assertContextFiles(root, [rootFile, subFile]);
    });
  }

  test_watch_modifyFile() {
    String filePath = join(projPath, 'foo.dart');
    // add root with a file
    resourceProvider.newFile(filePath, 'contents');
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    // the file was added
    Iterable<String> filePaths = callbacks.currentFilePaths;
    expect(filePaths, hasLength(1));
    expect(filePaths, contains(filePath));
    // TODO(brianwilkerson) Test when the file was modified
    // update the file
    callbacks.now++;
    resourceProvider.modifyFile(filePath, 'new contents');
    return pumpEventQueue().then((_) {
      // TODO(brianwilkerson) Test when the file was modified
    });
  }

  test_watch_modifyPackagespec() {
    String packagesPath = convertPath('$projPath/.packages');
    String filePath = convertPath('$projPath/bin/main.dart');

    resourceProvider.newFile(packagesPath, '');
    resourceProvider.newFile(filePath, 'library main;');

    manager.setRoots(<String>[projPath], <String>[], <String, String>{});

    Iterable<String> filePaths = callbacks.currentFilePaths;
    expect(filePaths, hasLength(1));
    expect(filePaths, contains(filePath));
    expect(_currentPackageMap, isEmpty);

    // update .packages
    callbacks.now++;
    resourceProvider.modifyFile(packagesPath, 'main:./lib/');
    return pumpEventQueue().then((_) {
      // verify new package info
      expect(_currentPackageMap.keys, unorderedEquals(['main']));
    });
  }

  /**
   * Verify that package URI's for source files in [path] will be resolved
   * using a package root matching [expectation].
   */
  void _checkPackageRoot(String path, expectation) {
    // TODO(brianwilkerson) Figure out how to test this. Possibly by comparing
    // the contents of the package map (although that approach doesn't work at
    // the moment).
//    FolderDisposition disposition = callbacks.currentContextDispositions[path];
//    expect(disposition.packageRoot, expectation);
    // TODO(paulberry): we should also verify that the package map itself is
    // correct.  See dartbug.com/23909.
  }
}

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;

  UriResolver packageResolver = null;

  String projPath = null;

  AnalysisError missing_return =
      new AnalysisError(null, 0, 1, HintCode.MISSING_RETURN, [
    ['x']
  ]);

  AnalysisError invalid_assignment_error =
      new AnalysisError(null, 0, 1, StaticTypeWarningCode.INVALID_ASSIGNMENT, [
    ['x'],
    ['y']
  ]);

  AnalysisError unused_local_variable =
      new AnalysisError(null, 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
    ['x']
  ]);

  List<Glob> get analysisFilesGlobs {
    List<String> patterns = <String>[
      '**/*.${AnalysisEngine.SUFFIX_DART}',
      '**/*.${AnalysisEngine.SUFFIX_HTML}',
      '**/*.${AnalysisEngine.SUFFIX_HTM}',
      '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
      '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}'
    ];
    return patterns
        .map((pattern) => new 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();
  }

  UriResolver providePackageResolver(Folder folder) => packageResolver;

  void setUp() {
    processRequiredPlugins();
    projPath = convertPath('/my/proj');
    resourceProvider.newFolder(projPath);
    // Create an SDK in the mock file system.
    new MockSdk(generateSummaryFiles: true, resourceProvider: resourceProvider);
    DartSdkManager sdkManager = new DartSdkManager(convertPath('/sdk'), true);
    manager = new ContextManagerImpl(
        resourceProvider,
        sdkManager,
        providePackageResolver,
        analysisFilesGlobs,
        InstrumentationService.NULL_SERVICE,
        new AnalysisOptionsImpl());
    PerformanceLog logger = new PerformanceLog(new NullStringSink());
    AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(logger);
    callbacks = new TestContextManagerCallbacks(
        resourceProvider, sdkManager, logger, scheduler);
    manager.callbacks = callbacks;
  }

  /**
   * Verify that package URI's for source files in [path] will be resolved
   * using a package root matching [expectation].
   */
  void _checkPackageRoot(String path, expectation) {
    // TODO(brianwilkerson) Figure out how to test this. Possibly by comparing
    // the contents of the package map (although that approach doesn't work at
    // the moment).
//    FolderDisposition disposition = callbacks.currentContextDispositions[path];
//    expect(disposition.packageRoot, expectation);
    // TODO(paulberry): we should also verify that the package map itself is
    // correct.  See dartbug.com/23909.
  }

  Map<String, List<Folder>> _packageMap(String contextPath) {
    Folder folder = resourceProvider.getFolder(contextPath);
    ContextInfo info = manager.getContextInfoFor(folder);
    return info.analysisDriver.sourceFactory?.packageMap;
  }
}

@reflectiveTest
class ContextManagerWithNewOptionsTest extends ContextManagerWithOptionsTest {
  String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;

  @failingTest
  test_analysis_options_parse_failure() async {
    // We have lost the ability to detect errors of this form.
    return super.test_analysis_options_parse_failure();
  }
}

@reflectiveTest
class ContextManagerWithOldOptionsTest extends ContextManagerWithOptionsTest {
  String get optionsFileName => AnalysisEngine.ANALYSIS_OPTIONS_FILE;
}

abstract class ContextManagerWithOptionsTest extends ContextManagerTest {
  String get optionsFileName;

  void deleteOptionsFile() {
    deleteFile('$projPath/$optionsFileName');
  }

  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>[], <String, 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
  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.
    String 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>[], <String, 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);
  }

  test_analysis_options_include() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$sdkExtPath/entry.dart');
    String 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>[], <String, String>{});
    await pumpEventQueue();
    // Verify options were set.
    expect(errorProcessors, hasLength(1));
    expect(lints, hasLength(1));
    expect(lints[0].name, 'camel_case_types');
  }

  test_analysis_options_include_package() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$sdkExtPath/entry.dart');
    String sdkExtSrcPath = '$projPath/sdk_ext/src';
    newFile('$sdkExtSrcPath/part.dart');
    // Setup package
    String 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:$booLibPosixPath\n');
    newFile('$projPath/$optionsFileName', content: r'''
include: package:boo/other_options.yaml
''');
    // Setup context.
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    await pumpEventQueue();
    // Verify options were set.
    expect(errorProcessors, hasLength(1));
    expect(lints, hasLength(1));
    expect(lints[0].name, 'camel_case_types');
  }

  test_analysis_options_parse_failure() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$sdkExtPath/entry.dart');
    String sdkExtSrcPath = '$projPath/sdk_ext/src';
    newFile('$sdkExtSrcPath/part.dart');
    // Setup analysis options file with ignore list.
    String optionsFilePath = newFile('$projPath/$optionsFileName', content: r'''
;
''').path;
    // Setup context.
    manager.setRoots(<String>[projPath], <String>[], <String, 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));
  }

  test_deleteRoot_hasAnalysisOptions() async {
    newFile('$projPath/$optionsFileName');

    // Add the root.
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    await pumpEventQueue();

    // Remove the root, with the analysis options file.
    // No exceptions.
    resourceProvider.deleteFolder(projPath);
    await pumpEventQueue();
  }

  @failingTest
  test_embedder_options() async {
    // This fails because the ContextBuilder doesn't pick up the strongMode
    // flag from the embedder.yaml file.
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$projPath/test', content: 'test.dart');
    newFile('$sdkExtPath/entry.dart');
    var synchronousSession = SynchronousSession(analysisOptions, null);
    List<int> bytes = new SummaryBuilder(
            [], RestrictedAnalysisContext(synchronousSession, null))
        .build();
    newFileWithBytes('$projPath/sdk.ds', bytes);
    // 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>[], <String, String>{});
    await pumpEventQueue();

    // Confirm that one context was created.
    int count = manager
        .numberOfContextsInAnalysisRoot(resourceProvider.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');
  }

  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>[], <String, String>{});

    // Verify filter setup.
    expect(errorProcessors, hasLength(1));
    expect(getProcessor(unused_local_variable).severity, isNull);
  }

  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>[], <String, String>{});

    // Verify filter setup.
    expect(errorProcessors, hasLength(2));

    expect(getProcessor(invalid_assignment_error).severity, isNull);
    expect(getProcessor(unused_local_variable).severity, ErrorSeverity.ERROR);
  }

  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>[], <String, String>{});

    // Verify filter setup.
    expect(errorProcessors, isNotNull);
    expect(errorProcessors, hasLength(2));
  }

  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>[], <String, String>{});

    // Verify filter setup.
    expect(errorProcessors, isEmpty);
  }

  test_non_analyzable_files_not_considered() async {
    // Set up project and get a reference to the driver.
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    Folder projectFolder = resourceProvider.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
  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 = resourceProvider.newFile('$projPath/bin/test.dart', r'''
main() {
  var paths = <int>[];
  var names = <String>[];
  paths.addAll(names.map((s) => s.length));
}
''');
    resourceProvider.newFile('$projPath/$optionsFileName', r'''
analyzer:
  strong-mode: false
''');
    // Create the context.
    manager.setRoots(<String>[projPath], <String>[], <String, 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'.
    resourceProvider.updateFile('$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
  test_path_filter_analysis_option() async {
    // This fails because we're not analyzing the analysis options file.
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/nope.dart');
    String sdkExtPath = '$projPath/sdk_ext';
    newFile('$sdkExtPath/entry.dart');
    String 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>[], <String, String>{});

    // Verify that analysis options was parsed and the ignore patterns applied.
    Folder projectFolder = resourceProvider.newFolder(projPath);
    var drivers = manager.getDriversInAnalysisRoot(projectFolder);
    expect(drivers, hasLength(1));
    AnalysisDriver driver = drivers[0];
    expect(
        driver.addedFiles,
        unorderedEquals(
            ['/my/proj/lib/main.dart', '/my/proj/$optionsFileName']));
  }

  test_path_filter_child_contexts_option() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/pubspec.yaml', content: r'''
name: foobar
''');
    String 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>[], <String, String>{});
    // Verify that the context in other_lib wasn't created and that the
    // context in lib was created.
    Folder projectFolder = resourceProvider.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')));
  }

  test_path_filter_recursive_wildcard_child_contexts_option() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/pubspec.yaml', content: r'''
  name: foobar
  ''');
    String 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>[], <String, String>{});

    // Verify that the context in other_lib wasn't created and that the
    // context in lib was created.
    Folder projectFolder = resourceProvider.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')));
  }

  test_path_filter_wildcard_child_contexts_option() async {
    // Create files.
    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
    newFile('$libPath/main.dart');
    newFile('$libPath/pubspec.yaml', content: r'''
name: foobar
''');
    String 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>[], <String, String>{});

    Folder projectFolder = resourceProvider.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() {
    String project = convertPath('/project');
    String projectPubspec = convertPath('$project/pubspec.yaml');
    String example = convertPath('$project/example');
    String examplePubspec = convertPath('$example/pubspec.yaml');
    // create files
    resourceProvider.newFile(projectPubspec, 'name: project');
    resourceProvider.newFile(examplePubspec, 'name: example');
    newFile('$project/$optionsFileName', content: r'''
analyzer:
  exclude:
    - 'example'
''');
    manager
        .setRoots(<String>[project, example], <String>[], <String, String>{});
    // verify
    {
      ContextInfo rootInfo = manager.rootInfo;
      expect(rootInfo.children, hasLength(1));
      {
        ContextInfo projectInfo = rootInfo.children[0];
        expect(projectInfo.folder.path, project);
        expect(projectInfo.children, hasLength(1));
        {
          ContextInfo 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() {
    String a = convertPath('/a');
    String c = convertPath('$a/b/c');
    String aPubspec = convertPath('$a/pubspec.yaml');
    String cPubspec = convertPath('$c/pubspec.yaml');
    // create files
    resourceProvider.newFile(aPubspec, 'name: aaa');
    resourceProvider.newFile(cPubspec, 'name: ccc');
    newFile('$a/$optionsFileName', content: r'''
analyzer:
  exclude:
    - 'b**'
''');
    manager.setRoots(<String>[a, c], <String>[], <String, String>{});
    // verify
    {
      ContextInfo rootInfo = manager.rootInfo;
      expect(rootInfo.children, hasLength(1));
      {
        ContextInfo aInfo = rootInfo.children[0];
        expect(aInfo.folder.path, a);
        expect(aInfo.children, hasLength(1));
        {
          ContextInfo cInfo = aInfo.children[0];
          expect(cInfo.folder.path, c);
          expect(cInfo.children, isEmpty);
        }
      }
    }
    expect(callbacks.currentContextRoots, hasLength(2));
    expect(callbacks.currentContextRoots, unorderedEquals([a, c]));
  }

  test_watchEvents() async {
    String libPath = newFolder('$projPath/${ContextManagerTest.LIB_NAME}').path;
    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
    newFile('$libPath/main.dart');
    await new Future.delayed(new 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
  NotificationManager notificationManager = new 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, AnalysisOptions options) {
    String path = folder.path;
    expect(currentContextRoots, isNot(contains(path)));
    expect(contextRoot, isNotNull);
    expect(contextRoot.root, path);
    currentContextTimestamps[path] = now;

    ContextBuilder builder =
        createContextBuilder(folder, options, useSummaries: true);
    builder.analysisDriverScheduler = scheduler;
    builder.byteStore = MemoryByteStore();
    builder.performanceLog = logger;
    builder.fileContentOverlay = FileContentOverlay();
    currentDriver = builder.buildDriver(contextRoot);

    driverMap[path] = currentDriver;
    currentDriver.exceptions.listen((ExceptionResult result) {
      AnalysisEngine.instance.logger
          .logError('Analysis failed: ${result.path}', result.exception);
    });
    return currentDriver;
  }

  @override
  void afterWatchEvent(WatchEvent event) {}

  @override
  void analysisOptionsUpdated(AnalysisDriver driver) {}

  @override
  void applyChangesToContext(Folder contextFolder, ChangeSet changeSet) {
    AnalysisDriver driver = driverMap[contextFolder.path];
    if (driver != null) {
      changeSet.addedSources.forEach((source) {
        driver.addFile(source.fullName);
      });
      changeSet.changedSources.forEach((source) {
        driver.changeFile(source.fullName);
      });
      changeSet.removedSources.forEach((source) {
        driver.removeFile(source.fullName);
      });
    }
  }

  @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, AnalysisOptions options,
      {bool useSummaries = false}) {
    ContextBuilderOptions builderOptions = new ContextBuilderOptions();
    builderOptions.defaultOptions = options;
    ContextBuilder builder = new 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>[];
    }
    AnalysisDriver driver = driverMap[contextPath];
    SourceFactory sourceFactory = driver.sourceFactory;
    return driver.addedFiles.map((String path) {
      File file = resourceProvider.getFile(path);
      Source source = file.createSource();
      Uri 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) {
    String path = folder.path;
    expect(currentContextRoots, contains(path));
    currentContextTimestamps.remove(path);
    currentContextFilePaths.remove(path);
    currentContextSources.remove(path);
    lastFlushedFiles = flushedFiles;
  }
}
