diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
deleted file mode 100644
index 1a83d55..0000000
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ /dev/null
@@ -1,994 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/error/error.dart' show AnalysisError;
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/dart/scanner/scanner.dart' show ScannerErrorCode;
-import 'package:analyzer/src/generated/engine.dart'
-    show
-        AnalysisContext,
-        AnalysisErrorInfo,
-        AnalysisErrorInfoImpl,
-        AnalysisOptions,
-        AnalysisOptionsImpl,
-        CacheState,
-        ChangeNoticeImpl,
-        InternalAnalysisContext;
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
-import 'package:analyzer/src/task/api/dart.dart';
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/dart.dart';
-import 'package:analyzer/src/task/dart_work_manager.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(DartWorkManagerTest);
-  });
-}
-
-@reflectiveTest
-class DartWorkManagerTest {
-  _InternalAnalysisContextMock context = new _InternalAnalysisContextMock();
-  AnalysisCache cache;
-  DartWorkManager manager;
-
-  CaughtException caughtException = new CaughtException(null, null);
-
-  Source source1 = new TestSource('1.dart');
-  Source source2 = new TestSource('2.dart');
-  Source source3 = new TestSource('3.dart');
-  Source source4 = new TestSource('4.dart');
-  CacheEntry entry1;
-  CacheEntry entry2;
-  CacheEntry entry3;
-  CacheEntry entry4;
-
-  void expect_librarySourceQueue(List<Source> sources) {
-    expect(manager.librarySourceQueue, unorderedEquals(sources));
-  }
-
-  void expect_unknownSourceQueue(List<Source> sources) {
-    expect(manager.unknownSourceQueue, unorderedEquals(sources));
-  }
-
-  void setUp() {
-    cache = context.analysisCache;
-    manager = new DartWorkManager(context);
-    entry1 = _getOrCreateEntry(source1);
-    entry2 = _getOrCreateEntry(source2);
-    entry3 = _getOrCreateEntry(source3);
-    entry4 = _getOrCreateEntry(source4);
-  }
-
-  void test_applyChange_add() {
-    // add source1
-    manager.applyChange([source1], [], []);
-    expect_unknownSourceQueue([source1]);
-    expect_librarySourceQueue([]);
-    // add source2
-    manager.applyChange([source2], [], []);
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source1, source2]);
-  }
-
-  void test_applyChange_add_duplicate() {
-    // add source1
-    manager.applyChange([source1], [], []);
-    expect_unknownSourceQueue([source1]);
-    expect_librarySourceQueue([]);
-    // add source2
-    manager.applyChange([source1], [], []);
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source1]);
-  }
-
-  void test_applyChange_addRemove() {
-    manager.applyChange([source1, source2], [], [source2, source3]);
-    expect_unknownSourceQueue([source1]);
-    expect_librarySourceQueue([]);
-  }
-
-  void test_applyChange_change() {
-    manager.librarySourceQueue.addAll([source1, source3]);
-    manager.unknownSourceQueue.addAll([source4]);
-    // change source1
-    manager.applyChange([], [source1], []);
-    expect_librarySourceQueue([source3]);
-    expect_unknownSourceQueue([source4, source1]);
-  }
-
-  /**
-   * When we perform limited invalidation, we keep [SOURCE_KIND] valid. So, we
-   * don't need to put such sources into [DartWorkManager.unknownSourceQueue],
-   * and remove from [DartWorkManager.librarySourceQueue].
-   */
-  void test_applyChange_change_hasSourceKind() {
-    entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    manager.librarySourceQueue.addAll([source1, source2]);
-    manager.unknownSourceQueue.addAll([source3]);
-    // change source1
-    manager.applyChange([], [source1, source2], []);
-    expect_librarySourceQueue([source1]);
-    expect_unknownSourceQueue([source2, source3]);
-  }
-
-  void test_applyChange_remove() {
-    manager.librarySourceQueue.addAll([source1, source3]);
-    manager.unknownSourceQueue.addAll([source4]);
-    // remove source1
-    manager.applyChange([], [], [source1]);
-    expect_librarySourceQueue([source3]);
-    expect_unknownSourceQueue([source4]);
-    // remove source3
-    manager.applyChange([], [], [source3]);
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source4]);
-    // remove source4
-    manager.applyChange([], [], [source4]);
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([]);
-  }
-
-  void test_applyChange_updatePartsLibraries_changeLibrary() {
-    Source part1 = new TestSource('part1.dart');
-    Source part2 = new TestSource('part2.dart');
-    Source part3 = new TestSource('part3.dart');
-    Source library1 = new TestSource('library1.dart');
-    Source library2 = new TestSource('library2.dart');
-    manager.partLibrariesMap[part1] = [library1, library2];
-    manager.partLibrariesMap[part2] = [library2];
-    manager.partLibrariesMap[part3] = [library1];
-    manager.libraryPartsMap[library1] = [part1, part3];
-    manager.libraryPartsMap[library2] = [part1, part2];
-    _getOrCreateEntry(part1).setValue(CONTAINING_LIBRARIES, [], []);
-    expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.VALID);
-    // change library1
-    manager.applyChange([], [library1], []);
-    expect(manager.partLibrariesMap[part1], unorderedEquals([library2]));
-    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
-    expect(manager.partLibrariesMap[part3], unorderedEquals([]));
-    expect(manager.libraryPartsMap[library1], isNull);
-    expect(manager.libraryPartsMap[library2], [part1, part2]);
-    expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.INVALID);
-  }
-
-  void test_applyChange_updatePartsLibraries_changePart() {
-    Source part1 = new TestSource('part1.dart');
-    Source part2 = new TestSource('part2.dart');
-    Source part3 = new TestSource('part3.dart');
-    Source library1 = new TestSource('library1.dart');
-    Source library2 = new TestSource('library2.dart');
-    manager.partLibrariesMap[part1] = [library1, library2];
-    manager.partLibrariesMap[part2] = [library2];
-    manager.partLibrariesMap[part3] = [library1];
-    manager.libraryPartsMap[library1] = [part1, part3];
-    manager.libraryPartsMap[library2] = [part1, part2];
-    _getOrCreateEntry(part1).setValue(CONTAINING_LIBRARIES, [], []);
-    expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.VALID);
-    // change part1
-    manager.applyChange([], [part1], []);
-    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
-    expect(manager.partLibrariesMap[part3], unorderedEquals([library1]));
-    expect(manager.libraryPartsMap[library1], [part1, part3]);
-    expect(manager.libraryPartsMap[library2], [part1, part2]);
-    expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.INVALID);
-  }
-
-  void test_applyChange_updatePartsLibraries_removeLibrary() {
-    Source part1 = new TestSource('part1.dart');
-    Source part2 = new TestSource('part2.dart');
-    Source part3 = new TestSource('part3.dart');
-    Source library1 = new TestSource('library1.dart');
-    Source library2 = new TestSource('library2.dart');
-    manager.partLibrariesMap[part1] = [library1, library2];
-    manager.partLibrariesMap[part2] = [library2];
-    manager.partLibrariesMap[part3] = [library1];
-    manager.libraryPartsMap[library1] = [part1, part3];
-    manager.libraryPartsMap[library2] = [part1, part2];
-    // remove library1
-    manager.applyChange([], [], [library1]);
-    expect(manager.partLibrariesMap[part1], unorderedEquals([library2]));
-    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
-    expect(manager.partLibrariesMap[part3], unorderedEquals([]));
-    expect(manager.libraryPartsMap[library1], isNull);
-    expect(manager.libraryPartsMap[library2], [part1, part2]);
-  }
-
-  void test_applyChange_updatePartsLibraries_removePart() {
-    Source part1 = new TestSource('part1.dart');
-    Source part2 = new TestSource('part2.dart');
-    Source part3 = new TestSource('part3.dart');
-    Source library1 = new TestSource('library1.dart');
-    Source library2 = new TestSource('library2.dart');
-    manager.partLibrariesMap[part1] = [library1, library2];
-    manager.partLibrariesMap[part2] = [library2];
-    manager.partLibrariesMap[part3] = [library1];
-    manager.libraryPartsMap[library1] = [part1, part3];
-    manager.libraryPartsMap[library2] = [part1, part2];
-    // remove part1
-    manager.applyChange([], [], [part1]);
-    expect(manager.partLibrariesMap[part1], isNull);
-    expect(manager.partLibrariesMap[part2], unorderedEquals([library2]));
-    expect(manager.partLibrariesMap[part3], unorderedEquals([library1]));
-    expect(manager.libraryPartsMap[library1], [part1, part3]);
-    expect(manager.libraryPartsMap[library2], [part1, part2]);
-  }
-
-  void test_applyPriorityTargets_isLibrary_computeErrors() {
-    context.setShouldErrorsBeAnalyzed(source2, true);
-    context.setShouldErrorsBeAnalyzed(source3, true);
-    entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    manager.priorityResultQueue
-        .add(new TargetedResult(source1, LIBRARY_ERRORS_READY));
-    manager.priorityResultQueue
-        .add(new TargetedResult(source2, LIBRARY_ERRORS_READY));
-    // -source1 +source3
-    manager.applyPriorityTargets([source2, source3]);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source2, LIBRARY_ERRORS_READY),
-          new TargetedResult(source3, LIBRARY_ERRORS_READY)
-        ]));
-    // get next request
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, LIBRARY_ERRORS_READY);
-  }
-
-  void test_applyPriorityTargets_isLibrary_computeUnit() {
-    context.setShouldErrorsBeAnalyzed(source2, false);
-    context.setShouldErrorsBeAnalyzed(source3, false);
-    entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    manager.priorityResultQueue
-        .add(new TargetedResult(source1, LIBRARY_ERRORS_READY));
-    manager.priorityResultQueue
-        .add(new TargetedResult(source2, LIBRARY_ERRORS_READY));
-    // -source1 +source3
-    manager.applyPriorityTargets([source2, source3]);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(
-              new LibrarySpecificUnit(source2, source2), RESOLVED_UNIT),
-          new TargetedResult(
-              new LibrarySpecificUnit(source3, source3), RESOLVED_UNIT),
-        ]));
-  }
-
-  void test_applyPriorityTargets_isPart() {
-    entry1.setValue(SOURCE_KIND, SourceKind.PART, []);
-    entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    // +source2 +source3
-    context.getLibrariesContainingMap[source1] = <Source>[source2, source3];
-    manager.applyPriorityTargets([source1]);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source2, LIBRARY_ERRORS_READY),
-          new TargetedResult(source3, LIBRARY_ERRORS_READY)
-        ]));
-    // get next request
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, LIBRARY_ERRORS_READY);
-  }
-
-  void test_applyPriorityTargets_isUnknown() {
-    manager.applyPriorityTargets([source2, source3]);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source2, SOURCE_KIND),
-          new TargetedResult(source3, SOURCE_KIND)
-        ]));
-    // get next request
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, SOURCE_KIND);
-  }
-
-  void test_getErrors() {
-    AnalysisError error1 =
-        new AnalysisError(source1, 1, 0, ScannerErrorCode.MISSING_DIGIT);
-    AnalysisError error2 =
-        new AnalysisError(source1, 2, 0, ScannerErrorCode.MISSING_DIGIT);
-    context.getLibrariesContainingMap[source1] = <Source>[source2];
-    entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
-    context
-        .getCacheEntry(new LibrarySpecificUnit(source2, source1))
-        .setValue(VERIFY_ERRORS, <AnalysisError>[error2], []);
-    List<AnalysisError> errors = manager.getErrors(source1);
-    expect(errors, unorderedEquals([error1, error2]));
-  }
-
-  void test_getErrors_hasFullList() {
-    AnalysisError error1 =
-        new AnalysisError(source1, 1, 0, ScannerErrorCode.MISSING_DIGIT);
-    AnalysisError error2 =
-        new AnalysisError(source1, 2, 0, ScannerErrorCode.MISSING_DIGIT);
-    context.getLibrariesContainingMap[source1] = <Source>[source2];
-    entry1.setValue(DART_ERRORS, <AnalysisError>[error1, error2], []);
-    List<AnalysisError> errors = manager.getErrors(source1);
-    expect(errors, unorderedEquals([error1, error2]));
-  }
-
-  void test_getLibrariesContainingPart() {
-    context.aboutToComputeEverything = false;
-    Source part1 = new TestSource('part1.dart');
-    Source part2 = new TestSource('part2.dart');
-    Source part3 = new TestSource('part3.dart');
-    Source library1 = new TestSource('library1.dart');
-    Source library2 = new TestSource('library2.dart');
-    manager.partLibrariesMap[part1] = [library1, library2];
-    manager.partLibrariesMap[part2] = [library2];
-    manager.libraryPartsMap[library1] = [part1];
-    manager.libraryPartsMap[library2] = [part1, part2];
-    // getLibrariesContainingPart
-    expect(manager.getLibrariesContainingPart(part1),
-        unorderedEquals([library1, library2]));
-    expect(
-        manager.getLibrariesContainingPart(part2), unorderedEquals([library2]));
-    expect(manager.getLibrariesContainingPart(part3), isEmpty);
-  }
-
-  void test_getLibrariesContainingPart_askResultProvider() {
-    Source part1 = new TestSource('part1.dart');
-    Source part2 = new TestSource('part2.dart');
-    Source part3 = new TestSource('part3.dart');
-    Source library1 = new TestSource('library1.dart');
-    Source library2 = new TestSource('library2.dart');
-    // configure AnalysisContext mock
-    context.aboutToComputeResultMap[CONTAINING_LIBRARIES] =
-        (CacheEntry entry, ResultDescriptor result) {
-      if (entry.target == part1) {
-        entry.setValue(result as ResultDescriptor<List<Source>>,
-            <Source>[library1, library2], []);
-        return true;
-      }
-      if (entry.target == part2) {
-        entry.setValue(
-            result as ResultDescriptor<List<Source>>, <Source>[library2], []);
-        return true;
-      }
-      return false;
-    };
-    // getLibrariesContainingPart
-    expect(manager.getLibrariesContainingPart(part1),
-        unorderedEquals([library1, library2]));
-    expect(
-        manager.getLibrariesContainingPart(part2), unorderedEquals([library2]));
-    expect(manager.getLibrariesContainingPart(part3), isEmpty);
-  }
-
-  void test_getLibrariesContainingPart_inSDK() {
-    _SourceMock part = new _SourceMock('part.dart');
-    part.isInSystemLibrary = true;
-    // SDK work manager
-    _DartWorkManagerMock sdkDartWorkManagerMock = new _DartWorkManagerMock();
-    sdkDartWorkManagerMock.librariesContainingPartMap[part] = <Source>[
-      source2,
-      source3
-    ];
-    // SDK context mock
-    _InternalAnalysisContextMock sdkContextMock =
-        new _InternalAnalysisContextMock();
-    sdkContextMock.workManagers = <WorkManager>[sdkDartWorkManagerMock];
-    // SDK mock
-    _DartSdkMock sdkMock = new _DartSdkMock();
-    sdkMock.context = sdkContextMock;
-    // SourceFactory mock
-    _SourceFactoryMock sourceFactory = new _SourceFactoryMock();
-    sourceFactory.dartSdk = sdkMock;
-    context.sourceFactory = sourceFactory;
-    // SDK source mock
-    _SourceMock source = new _SourceMock('test.dart');
-    source.source = source;
-    source.isInSystemLibrary = true;
-    // validate
-    expect(manager.getLibrariesContainingPart(part),
-        unorderedEquals([source2, source3]));
-  }
-
-  void test_getNextResult_hasLibraries_firstIsError() {
-    entry1.setErrorState(caughtException, [LIBRARY_ERRORS_READY]);
-    manager.librarySourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, LIBRARY_ERRORS_READY);
-    // source1 is out, source2 is waiting
-    expect_librarySourceQueue([source2]);
-  }
-
-  void test_getNextResult_hasLibraries_firstIsInvalid() {
-    entry1.setState(LIBRARY_ERRORS_READY, CacheState.INVALID);
-    manager.librarySourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source1);
-    expect(request.result, LIBRARY_ERRORS_READY);
-    // no changes until computed
-    expect_librarySourceQueue([source1, source2]);
-  }
-
-  void test_getNextResult_hasLibraries_firstIsValid() {
-    entry1.setValue(LIBRARY_ERRORS_READY, true, []);
-    manager.librarySourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, LIBRARY_ERRORS_READY);
-    // source1 is out, source2 is waiting
-    expect_librarySourceQueue([source2]);
-  }
-
-  void test_getNextResult_hasPriority_firstIsError() {
-    manager.addPriorityResult(source1, SOURCE_KIND);
-    manager.addPriorityResult(source2, SOURCE_KIND);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source1, SOURCE_KIND),
-          new TargetedResult(source2, SOURCE_KIND)
-        ]));
-    // configure state and get next result
-    entry1.setErrorState(caughtException, [SOURCE_KIND]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, SOURCE_KIND);
-    // source1 is out, source2 is waiting
-    expect(manager.priorityResultQueue,
-        unorderedEquals([new TargetedResult(source2, SOURCE_KIND)]));
-  }
-
-  void test_getNextResult_hasPriority_firstIsValid() {
-    manager.addPriorityResult(source1, SOURCE_KIND);
-    manager.addPriorityResult(source2, SOURCE_KIND);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source1, SOURCE_KIND),
-          new TargetedResult(source2, SOURCE_KIND)
-        ]));
-    // configure state and get next result
-    entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, SOURCE_KIND);
-    // source1 is out, source2 is waiting
-    expect(manager.priorityResultQueue,
-        unorderedEquals([new TargetedResult(source2, SOURCE_KIND)]));
-  }
-
-  void test_getNextResult_hasUnknown_firstIsError() {
-    entry1.setErrorState(caughtException, [SOURCE_KIND]);
-    manager.unknownSourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, SOURCE_KIND);
-    // source1 is out, source2 is waiting
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source2]);
-  }
-
-  void test_getNextResult_hasUnknown_firstIsInvalid() {
-    manager.unknownSourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source1);
-    expect(request.result, SOURCE_KIND);
-    // no changes until computed
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source1, source2]);
-  }
-
-  void test_getNextResult_hasUnknown_firstIsValid() {
-    entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    manager.unknownSourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, SOURCE_KIND);
-    // source1 is out, source2 is waiting
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source2]);
-  }
-
-  void test_getNextResult_nothingToDo() {
-    TargetedResult request = manager.getNextResult();
-    expect(request, isNull);
-  }
-
-  void test_getNextResultPriority_hasLibrary() {
-    manager.librarySourceQueue.addAll([source1]);
-    expect(manager.getNextResultPriority(), WorkOrderPriority.NORMAL);
-  }
-
-  void test_getNextResultPriority_hasPriority() {
-    manager.addPriorityResult(source1, SOURCE_KIND);
-    expect(manager.getNextResultPriority(), WorkOrderPriority.PRIORITY);
-  }
-
-  void test_getNextResultPriority_hasUnknown() {
-    manager.unknownSourceQueue.addAll([source1]);
-    expect(manager.getNextResultPriority(), WorkOrderPriority.NORMAL);
-  }
-
-  void test_getNextResultPriority_nothingToDo() {
-    expect(manager.getNextResultPriority(), WorkOrderPriority.NONE);
-  }
-
-  void test_onAnalysisOptionsChanged() {
-    context.everythingExists = true;
-    // set cache values
-    entry1.setValue(PARSED_UNIT, AstTestFactory.compilationUnit(), []);
-    entry1.setValue(IMPORTED_LIBRARIES, <Source>[], []);
-    entry1.setValue(EXPLICITLY_IMPORTED_LIBRARIES, <Source>[], []);
-    entry1.setValue(EXPORTED_LIBRARIES, <Source>[], []);
-    entry1.setValue(INCLUDED_PARTS, <Source>[], []);
-    // configure LibrarySpecificUnit
-    LibrarySpecificUnit unitTarget = new LibrarySpecificUnit(source2, source3);
-    CacheEntry unitEntry = new CacheEntry(unitTarget);
-    cache.put(unitEntry);
-    unitEntry.setValue(BUILD_LIBRARY_ERRORS, <AnalysisError>[], []);
-    expect(unitEntry.getState(BUILD_LIBRARY_ERRORS), CacheState.VALID);
-    // notify
-    manager.onAnalysisOptionsChanged();
-    // resolution is invalidated
-    expect(unitEntry.getState(BUILD_LIBRARY_ERRORS), CacheState.INVALID);
-    // ...but URIs are still value
-    expect(entry1.getState(PARSED_UNIT), CacheState.VALID);
-    expect(entry1.getState(IMPORTED_LIBRARIES), CacheState.VALID);
-    expect(entry1.getState(EXPLICITLY_IMPORTED_LIBRARIES), CacheState.VALID);
-    expect(entry1.getState(EXPORTED_LIBRARIES), CacheState.VALID);
-    expect(entry1.getState(INCLUDED_PARTS), CacheState.VALID);
-  }
-
-  void test_onResultInvalidated_scheduleInvalidatedLibraries() {
-    // make source3 implicit
-    entry3.explicitlyAdded = false;
-    // set SOURCE_KIND
-    entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    entry2.setValue(SOURCE_KIND, SourceKind.PART, []);
-    entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
-    // set LIBRARY_ERRORS_READY for source1 and source3
-    entry1.setValue(LIBRARY_ERRORS_READY, true, []);
-    entry3.setValue(LIBRARY_ERRORS_READY, true, []);
-    // invalidate LIBRARY_ERRORS_READY for source1, schedule it
-    entry1.setState(LIBRARY_ERRORS_READY, CacheState.INVALID);
-    expect_librarySourceQueue([source1]);
-    // invalidate LIBRARY_ERRORS_READY for source3, implicit, not scheduled
-    entry3.setState(LIBRARY_ERRORS_READY, CacheState.INVALID);
-    expect_librarySourceQueue([source1]);
-  }
-
-  void test_onSourceFactoryChanged() {
-    context.everythingExists = true;
-    // set cache values
-    entry1.setValue(PARSED_UNIT, AstTestFactory.compilationUnit(), []);
-    entry1.setValue(IMPORTED_LIBRARIES, <Source>[], []);
-    entry1.setValue(EXPLICITLY_IMPORTED_LIBRARIES, <Source>[], []);
-    entry1.setValue(EXPORTED_LIBRARIES, <Source>[], []);
-    entry1.setValue(INCLUDED_PARTS, <Source>[], []);
-    entry1.setValue(LIBRARY_SPECIFIC_UNITS, <LibrarySpecificUnit>[], []);
-    entry1.setValue(UNITS, <Source>[], []);
-    // configure LibrarySpecificUnit
-    LibrarySpecificUnit unitTarget = new LibrarySpecificUnit(source2, source3);
-    CacheEntry unitEntry = new CacheEntry(unitTarget);
-    cache.put(unitEntry);
-    unitEntry.setValue(BUILD_LIBRARY_ERRORS, <AnalysisError>[], []);
-    expect(unitEntry.getState(BUILD_LIBRARY_ERRORS), CacheState.VALID);
-    // notify
-    manager.onSourceFactoryChanged();
-    // resolution is invalidated
-    expect(unitEntry.getState(BUILD_LIBRARY_ERRORS), CacheState.INVALID);
-    // ...and URIs resolution too
-    expect(entry1.getState(PARSED_UNIT), CacheState.INVALID);
-    expect(entry1.getState(IMPORTED_LIBRARIES), CacheState.INVALID);
-    expect(entry1.getState(EXPLICITLY_IMPORTED_LIBRARIES), CacheState.INVALID);
-    expect(entry1.getState(EXPORTED_LIBRARIES), CacheState.INVALID);
-    expect(entry1.getState(INCLUDED_PARTS), CacheState.INVALID);
-    expect(entry1.getState(LIBRARY_SPECIFIC_UNITS), CacheState.INVALID);
-    expect(entry1.getState(UNITS), CacheState.INVALID);
-  }
-
-  void test_resultsComputed_errors_forLibrarySpecificUnit() {
-    LineInfo lineInfo = new LineInfo([0]);
-    AnalysisError error1 =
-        new AnalysisError(source1, 1, 0, ScannerErrorCode.MISSING_DIGIT);
-    AnalysisError error2 =
-        new AnalysisError(source1, 2, 0, ScannerErrorCode.MISSING_DIGIT);
-    context.getLibrariesContainingMap[source1] = <Source>[source2];
-    context.errorsMap[source1] =
-        new AnalysisErrorInfoImpl([error1, error2], lineInfo);
-    entry1.setValue(LINE_INFO, lineInfo, []);
-    entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
-    AnalysisTarget unitTarget = new LibrarySpecificUnit(source2, source1);
-    context
-        .getCacheEntry(unitTarget)
-        .setValue(VERIFY_ERRORS, <AnalysisError>[error2], []);
-    // RESOLVED_UNIT is ready, set errors
-    manager.resultsComputed(
-        unitTarget, {RESOLVED_UNIT: AstTestFactory.compilationUnit()});
-    // all of the errors are included
-    ChangeNoticeImpl notice = context.getNotice(source1);
-    expect(notice.errors, unorderedEquals([error1, error2]));
-    expect(notice.lineInfo, lineInfo);
-  }
-
-  void test_resultsComputed_errors_forSource() {
-    LineInfo lineInfo = new LineInfo([0]);
-    AnalysisError error1 =
-        new AnalysisError(source1, 1, 0, ScannerErrorCode.MISSING_DIGIT);
-    AnalysisError error2 =
-        new AnalysisError(source1, 2, 0, ScannerErrorCode.MISSING_DIGIT);
-    context.getLibrariesContainingMap[source1] = <Source>[source2];
-    context.errorsMap[source1] =
-        new AnalysisErrorInfoImpl([error1, error2], lineInfo);
-    entry1.setValue(LINE_INFO, lineInfo, []);
-    entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
-    entry1.setValue(PARSE_ERRORS, <AnalysisError>[error2], []);
-    // PARSED_UNIT is ready, set errors
-    manager.resultsComputed(
-        source1, {PARSED_UNIT: AstTestFactory.compilationUnit()});
-    // all of the errors are included
-    ChangeNoticeImpl notice = context.getNotice(source1);
-    expect(notice.errors, unorderedEquals([error1, error2]));
-    expect(notice.lineInfo, lineInfo);
-  }
-
-  void test_resultsComputed_includedParts_updatePartLibraries() {
-    Source part1 = new TestSource('part1.dart');
-    Source part2 = new TestSource('part2.dart');
-    Source part3 = new TestSource('part3.dart');
-    Source library1 = new TestSource('library1.dart');
-    Source library2 = new TestSource('library2.dart');
-    _getOrCreateEntry(part1).setValue(CONTAINING_LIBRARIES, [], []);
-    expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.VALID);
-    // configure AnalysisContext mock
-    context.prioritySources = <Source>[];
-    context.analyzeAllErrors = false;
-    // library1 parts
-    manager.resultsComputed(library1, <ResultDescriptor, dynamic>{
-      INCLUDED_PARTS: [part1, part2],
-      SOURCE_KIND: SourceKind.LIBRARY
-    });
-    expect(manager.partLibrariesMap[part1], [library1]);
-    expect(manager.partLibrariesMap[part2], [library1]);
-    expect(manager.partLibrariesMap[part3], isNull);
-    expect(manager.libraryPartsMap[library1], [part1, part2]);
-    expect(manager.libraryPartsMap[library2], isNull);
-    // library2 parts
-    manager.resultsComputed(library2, <ResultDescriptor, dynamic>{
-      INCLUDED_PARTS: [part2, part3],
-      SOURCE_KIND: SourceKind.LIBRARY
-    });
-    expect(manager.partLibrariesMap[part1], [library1]);
-    expect(manager.partLibrariesMap[part2], [library1, library2]);
-    expect(manager.partLibrariesMap[part3], [library2]);
-    expect(manager.libraryPartsMap[library1], [part1, part2]);
-    expect(manager.libraryPartsMap[library2], [part2, part3]);
-    // part1 CONTAINING_LIBRARIES
-    expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.INVALID);
-  }
-
-  void test_resultsComputed_inSDK() {
-    _DartWorkManagerMock sdkDartWorkManagerMock = new _DartWorkManagerMock();
-    // SDK context mock
-    _InternalAnalysisContextMock sdkContextMock =
-        new _InternalAnalysisContextMock();
-    sdkContextMock.workManagers = <WorkManager>[sdkDartWorkManagerMock];
-    // SDK mock
-    _DartSdkMock sdkMock = new _DartSdkMock();
-    sdkMock.context = sdkContextMock;
-    // SourceFactory mock
-    _SourceFactoryMock sourceFactory = new _SourceFactoryMock();
-    sourceFactory.dartSdk = sdkMock;
-    context.sourceFactory = sourceFactory;
-    // SDK source mock
-    _SourceMock source = new _SourceMock('test.dart');
-    source.source = source;
-    source.isInSystemLibrary = true;
-    // notify and validate
-    Map<ResultDescriptor, dynamic> outputs = <ResultDescriptor, dynamic>{};
-    manager.resultsComputed(source, outputs);
-    var bySourceMap = sdkDartWorkManagerMock.resultsComputedCounts[source];
-    expect(bySourceMap, isNotNull);
-    expect(bySourceMap[outputs], 1);
-  }
-
-  void test_resultsComputed_noSourceKind() {
-    manager.unknownSourceQueue.addAll([source1, source2]);
-    manager.resultsComputed(source1, {});
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source1, source2]);
-  }
-
-  void test_resultsComputed_notDart() {
-    manager.unknownSourceQueue.addAll([source1, source2]);
-    manager.resultsComputed(new TestSource('test.html'), {});
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source1, source2]);
-  }
-
-  void test_resultsComputed_parsedUnit() {
-    LineInfo lineInfo = new LineInfo([0]);
-    context.getLibrariesContainingMap[source1] = <Source>[];
-    context.errorsMap[source1] = new AnalysisErrorInfoImpl([], lineInfo);
-    entry1.setValue(LINE_INFO, lineInfo, []);
-    CompilationUnit unit = AstTestFactory.compilationUnit();
-    manager.resultsComputed(source1, {PARSED_UNIT: unit});
-    ChangeNoticeImpl notice = context.getNotice(source1);
-    expect(notice.parsedDartUnit, unit);
-    expect(notice.resolvedDartUnit, isNull);
-    expect(notice.lineInfo, lineInfo);
-  }
-
-  void test_resultsComputed_resolvedUnit() {
-    LineInfo lineInfo = new LineInfo([0]);
-    context.getLibrariesContainingMap[source2] = <Source>[];
-    context.errorsMap[source2] = new AnalysisErrorInfoImpl([], lineInfo);
-    entry2.setValue(LINE_INFO, lineInfo, []);
-    CompilationUnit unit = AstTestFactory.compilationUnit();
-    manager.resultsComputed(
-        new LibrarySpecificUnit(source1, source2), {RESOLVED_UNIT: unit});
-    ChangeNoticeImpl notice = context.getNotice(source2);
-    expect(notice.parsedDartUnit, isNull);
-    expect(notice.resolvedDartUnit, unit);
-    expect(notice.lineInfo, lineInfo);
-  }
-
-  void test_resultsComputed_sourceKind_isLibrary() {
-    manager.unknownSourceQueue.addAll([source1, source2, source3]);
-    context.prioritySources = <Source>[];
-    context.shouldErrorsBeAnalyzedMap[source2] = true;
-    manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
-    expect_librarySourceQueue([source2]);
-    expect_unknownSourceQueue([source1, source3]);
-  }
-
-  void test_resultsComputed_sourceKind_isLibrary_isPriority_computeErrors() {
-    manager.unknownSourceQueue.addAll([source1, source2, source3]);
-    context.prioritySources = <Source>[source2];
-    context.shouldErrorsBeAnalyzedMap[source2] = true;
-    manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
-    expect_unknownSourceQueue([source1, source3]);
-    expect(manager.priorityResultQueue,
-        unorderedEquals([new TargetedResult(source2, LIBRARY_ERRORS_READY)]));
-  }
-
-  void test_resultsComputed_sourceKind_isLibrary_isPriority_computeUnit() {
-    manager.unknownSourceQueue.addAll([source1, source2, source3]);
-    context.prioritySources = <Source>[source2];
-    context.shouldErrorsBeAnalyzedMap[source2] = false;
-    manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
-    expect_unknownSourceQueue([source1, source3]);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(
-              new LibrarySpecificUnit(source2, source2), RESOLVED_UNIT)
-        ]));
-  }
-
-  void test_resultsComputed_sourceKind_isPart() {
-    manager.unknownSourceQueue.addAll([source1, source2, source3]);
-    manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.PART});
-    expect_librarySourceQueue([]);
-    expect_unknownSourceQueue([source1, source3]);
-  }
-
-  void test_resultsComputed_updatePartsLibraries_partParsed() {
-    Source part = new TestSource('part.dart');
-    expect(manager.libraryPartsMap, isEmpty);
-    // part.dart parsed, no changes is the map of libraries
-    manager.resultsComputed(part, <ResultDescriptor, dynamic>{
-      SOURCE_KIND: SourceKind.PART,
-      INCLUDED_PARTS: <Source>[]
-    });
-    expect(manager.libraryPartsMap, isEmpty);
-  }
-
-  void test_unitIncrementallyResolved() {
-    manager.unitIncrementallyResolved(source1, source2);
-    expect_librarySourceQueue([source1]);
-  }
-
-  CacheEntry _getOrCreateEntry(Source source, [bool explicit = true]) {
-    CacheEntry entry = cache.get(source);
-    if (entry == null) {
-      entry = new CacheEntry(source);
-      entry.explicitlyAdded = explicit;
-      cache.put(entry);
-    }
-    return entry;
-  }
-}
-
-class _DartSdkMock implements DartSdk {
-  AnalysisContext context;
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-}
-
-class _DartWorkManagerMock implements DartWorkManager {
-  Map<Source, List<Source>> librariesContainingPartMap =
-      <Source, List<Source>>{};
-
-  Map<Source, Map<Map<ResultDescriptor, dynamic>, int>> resultsComputedCounts =
-      <Source, Map<Map<ResultDescriptor, dynamic>, int>>{};
-
-  @override
-  List<Source> getLibrariesContainingPart(Source part) {
-    return librariesContainingPartMap[part] ?? <Source>[];
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-
-  @override
-  void resultsComputed(
-      AnalysisTarget target, Map<ResultDescriptor, dynamic> outputs) {
-    Map<Map<ResultDescriptor, dynamic>, int> bySourceMap =
-        resultsComputedCounts.putIfAbsent(target, () => {});
-    bySourceMap[outputs] = (bySourceMap[outputs] ?? 0) + 1;
-  }
-}
-
-class _InternalAnalysisContextMock implements InternalAnalysisContext {
-  @override
-  CachePartition privateAnalysisCachePartition;
-
-  @override
-  AnalysisCache analysisCache;
-
-  @override
-  SourceFactory sourceFactory;
-
-  bool analyzeAllErrors;
-
-  bool everythingExists = false;
-
-  bool aboutToComputeEverything;
-
-  @override
-  List<Source> prioritySources = <Source>[];
-
-  @override
-  List<WorkManager> workManagers = <WorkManager>[];
-
-  Map<Source, List<Source>> getLibrariesContainingMap =
-      <Source, List<Source>>{};
-
-  Map<Source, bool> shouldErrorsBeAnalyzedMap = <Source, bool>{};
-
-  Map<ResultDescriptor, bool Function(CacheEntry entry, ResultDescriptor)>
-      aboutToComputeResultMap =
-      <ResultDescriptor, bool Function(CacheEntry entry, ResultDescriptor)>{};
-
-  Map<Source, AnalysisErrorInfo> errorsMap = <Source, AnalysisErrorInfo>{};
-
-  Map<Source, ChangeNoticeImpl> _pendingNotices = <Source, ChangeNoticeImpl>{};
-
-  @override
-  final AnalysisOptions analysisOptions = new AnalysisOptionsImpl();
-
-  @override
-  final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
-      new ReentrantSynchronousStream<InvalidatedResult>();
-
-  _InternalAnalysisContextMock() {
-    privateAnalysisCachePartition = new UniversalCachePartition(this);
-    analysisCache = new AnalysisCache([privateAnalysisCachePartition]);
-    analysisCache.onResultInvalidated.listen((InvalidatedResult event) {
-      onResultInvalidated.add(event);
-    });
-  }
-
-  @override
-  bool aboutToComputeResult(CacheEntry entry, ResultDescriptor result) {
-    if (aboutToComputeEverything != null) {
-      return aboutToComputeEverything;
-    }
-    bool Function(CacheEntry entry, ResultDescriptor) function =
-        aboutToComputeResultMap[result];
-    if (function == null) {
-      return false;
-    }
-    return function(entry, result);
-  }
-
-  @override
-  bool exists(Source source) {
-    return everythingExists;
-  }
-
-  @override
-  CacheEntry getCacheEntry(AnalysisTarget target) {
-    CacheEntry entry = analysisCache.get(target);
-    if (entry == null) {
-      entry = new CacheEntry(target);
-      analysisCache.put(entry);
-    }
-    return entry;
-  }
-
-  @override
-  AnalysisErrorInfo getErrors(Source source) => errorsMap[source];
-
-  List<Source> getLibrariesContaining(Source source) {
-    return getLibrariesContainingMap[source];
-  }
-
-  @override
-  ChangeNoticeImpl getNotice(Source source) {
-    return _pendingNotices.putIfAbsent(
-        source, () => new ChangeNoticeImpl(source));
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-
-  void setShouldErrorsBeAnalyzed(Source source, bool value) {
-    shouldErrorsBeAnalyzedMap[source] = value;
-  }
-
-  @override
-  bool shouldErrorsBeAnalyzed(Source source) {
-    if (analyzeAllErrors != null) {
-      return analyzeAllErrors;
-    }
-    return shouldErrorsBeAnalyzedMap[source];
-  }
-}
-
-class _SourceFactoryMock implements SourceFactory {
-  DartSdk dartSdk;
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-}
-
-class _SourceMock implements Source {
-  @override
-  final String shortName;
-
-  @override
-  bool isInSystemLibrary = false;
-
-  @override
-  Source source;
-
-  _SourceMock(this.shortName);
-
-  @override
-  String get fullName => '/' + shortName;
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-
-  @override
-  String toString() => fullName;
-}
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
deleted file mode 100644
index e5e3b2b..0000000
--- a/pkg/analyzer/test/src/task/general_test.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/general.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(GetContentTaskTest);
-  });
-}
-
-@reflectiveTest
-class GetContentTaskTest extends EngineTestCase {
-  test_buildInputs() {
-    AnalysisTarget target = new TestSource();
-    Map<String, TaskInput> inputs = GetContentTask.buildInputs(target);
-    expect(inputs, isEmpty);
-  }
-
-  test_constructor() {
-    AnalysisContext context = new _MockContext();
-    AnalysisTarget target = new TestSource();
-    GetContentTask task = new GetContentTask(context, target);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, target);
-  }
-
-  test_createTask() {
-    AnalysisContext context = new _MockContext();
-    AnalysisTarget target = new TestSource();
-    GetContentTask task = GetContentTask.createTask(context, target);
-    expect(task, isNotNull);
-    expect(task.context, context);
-    expect(task.target, target);
-  }
-
-  test_descriptor() {
-    AnalysisContext context = new _MockContext();
-    AnalysisTarget target = new TestSource();
-    GetContentTask task = new GetContentTask(context, target);
-    expect(task.descriptor, GetContentTask.DESCRIPTOR);
-  }
-
-  test_perform() {
-    _MockContext context = new _MockContext();
-    Source target = new TestSource();
-    GetContentTask task = new GetContentTask(context, target);
-    context.getContentsResponse[target] =
-        () => new TimestampedData<String>(42, 'foo');
-    task.perform();
-    expect(task.caughtException, isNull);
-    expect(task.outputs, hasLength(2));
-    expect(task.outputs[CONTENT], 'foo');
-    expect(task.outputs[MODIFICATION_TIME], 42);
-  }
-
-  void test_perform_exception() {
-    _MockContext context = new _MockContext();
-    Source target = new TestSource();
-    GetContentTask task = new GetContentTask(context, target);
-    context.getContentsResponse[target] = () => throw 'My exception!';
-    task.perform();
-    expect(task.caughtException, isNull);
-    expect(task.outputs, hasLength(2));
-    expect(task.outputs[CONTENT], '');
-    expect(task.outputs[MODIFICATION_TIME], -1);
-  }
-}
-
-class _MockContext implements AnalysisContext {
-  Map<Source, TimestampedData<String> Function()> getContentsResponse =
-      <Source, TimestampedData<String> Function()>{};
-
-  String get name => 'mock';
-
-  @override
-  TimestampedData<String> getContents(Source source) {
-    TimestampedData<String> Function() response = getContentsResponse[source];
-    if (response == null) {
-      fail('Unexpected invocation of getContents');
-    }
-    return response();
-  }
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    fail('Unexpected invocation of ${invocation.memberName}');
-  }
-}
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
deleted file mode 100644
index c8963d3..0000000
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ /dev/null
@@ -1,1073 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/inputs.dart';
-import 'package:analyzer/src/task/model.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(ConstantTaskInputBuilderTest);
-    defineReflectiveTests(ConstantTaskInputTest);
-    defineReflectiveTests(ListTaskInputImplTest);
-    defineReflectiveTests(ListToListTaskInputTest);
-    defineReflectiveTests(ListToListTaskInputBuilderTest);
-    defineReflectiveTests(ListToMapTaskInputBuilderTest);
-    defineReflectiveTests(ListToMapTaskInputTest);
-    defineReflectiveTests(ObjectToListTaskInputBuilderTest);
-    defineReflectiveTests(ObjectToListTaskInputTest);
-    defineReflectiveTests(SimpleTaskInputTest);
-    defineReflectiveTests(SimpleTaskInputBuilderTest);
-    defineReflectiveTests(TopLevelTaskInputBuilderTest);
-  });
-}
-
-@reflectiveTest
-class ConstantTaskInputBuilderTest extends EngineTestCase {
-  static final int value = 7;
-  static final ConstantTaskInput<int> input = new ConstantTaskInput<int>(value);
-
-  ConstantTaskInputBuilder builder;
-
-  void setUp() {
-    super.setUp();
-    builder = new ConstantTaskInputBuilder(input);
-  }
-
-  test_create() {
-    expect(builder, isNotNull);
-    expect(builder.input, input);
-  }
-
-  test_currentResult_afterOneMoveNext() {
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_beforeMoveNext() {
-    expect(builder.currentResult, null);
-  }
-
-  test_currentTarget_afterOneMoveNext() {
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_beforeMoveNext() {
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentValue_afterOneMoveNext() {
-    builder.moveNext();
-    expect(() {
-      builder.currentValue = 'value';
-    }, throwsStateError);
-  }
-
-  test_currentValue_beforeMoveNext() {
-    expect(() {
-      builder.currentValue = 'value';
-    }, throwsStateError);
-  }
-
-  test_currentValueNotAvailable_afterOneMoveNext() {
-    builder.moveNext();
-    expect(() {
-      builder.currentValueNotAvailable();
-    }, throwsStateError);
-  }
-
-  test_currentValueNotAvailable_beforeMoveNext() {
-    expect(() {
-      builder.currentValueNotAvailable();
-    }, throwsStateError);
-  }
-
-  test_inputValue_afterOneMoveNext() {
-    builder.moveNext();
-    expect(builder.inputValue, value);
-  }
-
-  test_inputValue_beforeMoveNext() {
-    expect(builder.inputValue, value);
-  }
-
-  test_moveNext() {
-    expect(builder.moveNext(), false);
-    expect(builder.moveNext(), false);
-  }
-}
-
-@reflectiveTest
-class ConstantTaskInputTest extends EngineTestCase {
-  test_create() {
-    int value = 3;
-    ConstantTaskInput<int> input = new ConstantTaskInput<int>(value);
-    expect(input, isNotNull);
-    expect(input.value, value);
-  }
-
-  test_createBuilder() {
-    ConstantTaskInput<int> input = new ConstantTaskInput<int>(5);
-    expect(input.createBuilder(), new TypeMatcher<ConstantTaskInputBuilder>());
-  }
-}
-
-@reflectiveTest
-class ListTaskInputImplTest extends EngineTestCase {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptor<List<AnalysisTarget>> result1 =
-      new ResultDescriptorImpl<List<AnalysisTarget>>('result1', null);
-  static final result2 = new ResultDescriptorImpl<int>('result2', null);
-
-  test_create() {
-    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    expect(input, isNotNull);
-    expect(input.target, target);
-    expect(input.result, result1);
-  }
-
-  test_createBuilder() {
-    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    expect(input.createBuilder(), new TypeMatcher<SimpleTaskInputBuilder>());
-  }
-
-  test_toList() {
-    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    ListTaskInput<String> input2 =
-        input.toList((target) => new SimpleTaskInput<String>(target, null));
-    expect(
-        input2, new TypeMatcher<ListToListTaskInput<AnalysisTarget, String>>());
-  }
-
-  test_toListOf() {
-    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    ListTaskInput<int> input2 = input.toListOf(result2);
-    expect(input2, new TypeMatcher<ListToListTaskInput<AnalysisTarget, int>>());
-  }
-
-  test_toMap() {
-    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    MapTaskInput<AnalysisTarget, String> input2 =
-        input.toMap((target) => new SimpleTaskInput<String>(target, null));
-    expect(
-        input2, new TypeMatcher<ListToMapTaskInput<AnalysisTarget, String>>());
-  }
-
-  test_toMapOf() {
-    var input = new ListTaskInputImpl<AnalysisTarget>(target, result1);
-    MapTaskInput<AnalysisTarget, int> input2 = input.toMapOf(result2);
-    expect(input2, new TypeMatcher<ListToMapTaskInput<AnalysisTarget, int>>());
-  }
-}
-
-@reflectiveTest
-class ListToListTaskInputBuilderTest extends EngineTestCase {
-  static final AnalysisTarget target1 = new TestSource();
-  static final ResultDescriptorImpl<List> result1 =
-      new ResultDescriptorImpl<List>('result1', null);
-  static final ResultDescriptorImpl result2 =
-      new ResultDescriptorImpl('result2', null);
-  static final ListToListTaskInput input = new ListToListTaskInput(
-      result1.of(target1), (element) => result2.of(element));
-
-  test_create() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(builder, isNotNull);
-    expect(builder.input, input);
-  }
-
-  test_currentResult_afterComplete() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValue = [];
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterCurrentValueNotAvailable() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterOneMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    expect(builder.currentResult, result1);
-  }
-
-  test_currentResult_beforeMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(builder.currentResult, null);
-  }
-
-  test_currentTarget_afterComplete() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValue = [];
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterCurrentValueNotAvailable() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterOneMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    expect(builder.currentTarget, target1);
-  }
-
-  test_currentTarget_beforeMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentValue_afterOneMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValue = [];
-  }
-
-  test_currentValue_beforeMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(() {
-      builder.currentValue = [];
-    }, throwsStateError);
-  }
-
-  test_currentValueNotAvailable_afterOneMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-  }
-
-  test_currentValueNotAvailable_beforeMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(() {
-      builder.currentValueNotAvailable();
-    }, throwsStateError);
-  }
-
-  test_inputValue_afterComplete() {
-    AnalysisTarget target2 = new TestSource();
-    AnalysisTarget target3 = new TestSource();
-    String value2 = 'value2';
-    String value3 = 'value3';
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext(); // Advance to requesting the list
-    builder.currentValue = [target2, target3];
-    builder.moveNext(); // Advance to requesting result2 for target2
-    builder.currentValue = value2;
-    builder.moveNext(); // Advance to requesting result2 for target3
-    builder.currentValue = value3;
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<List>());
-    List list = inputValue;
-    expect(list.length, 2);
-    expect(list[0], value2);
-    expect(list[1], value3);
-  }
-
-  test_inputValue_afterFirstValueNotAvailable() {
-    AnalysisTarget target2 = new TestSource();
-    AnalysisTarget target3 = new TestSource();
-    String value3 = 'value3';
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext(); // Advance to requesting the list
-    builder.currentValue = [target2, target3];
-    builder.moveNext(); // Advance to requesting result2 for target2
-    builder.currentValueNotAvailable();
-    builder.moveNext(); // Advance to requesting result2 for target3
-    builder.currentValue = value3;
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<List>());
-    List list = inputValue;
-    expect(list, orderedEquals([value3]));
-  }
-
-  test_inputValue_afterListNotAvailable() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext(); // Advance to requesting the list
-    builder.currentValueNotAvailable();
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<List>());
-    List list = inputValue;
-    expect(list, isEmpty);
-  }
-
-  test_inputValue_afterOneMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    builder.moveNext();
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_inputValue_beforeMoveNext() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_moveNext_withoutSet() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(builder.moveNext(), true);
-    expect(() => builder.moveNext(), throwsStateError);
-  }
-
-  test_moveNext_withSet() {
-    ListToListTaskInputBuilder builder = new ListToListTaskInputBuilder(input);
-    expect(builder.moveNext(), true);
-    builder.currentValue = [];
-    expect(builder.moveNext(), false);
-    expect(builder.moveNext(), false);
-  }
-}
-
-@reflectiveTest
-class ListToListTaskInputTest extends EngineTestCase {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl<List> result =
-      new ResultDescriptorImpl<List>('result', null);
-
-  test_create() {
-    SimpleTaskInput<List> baseAccessor = result.of(target);
-    GenerateTaskInputs generate = (object) => null;
-    ListToListTaskInput input = new ListToListTaskInput(baseAccessor, generate);
-    expect(input, isNotNull);
-    expect(input.baseAccessor, baseAccessor);
-    expect(input.generateTaskInputs, equals(generate));
-  }
-
-  test_createBuilder() {
-    SimpleTaskInput<List> baseAccessor = result.of(target);
-    GenerateTaskInputs generate = (object) => null;
-    ListToListTaskInput input = new ListToListTaskInput(baseAccessor, generate);
-    expect(input.createBuilder(), isNotNull);
-  }
-}
-
-@reflectiveTest
-class ListToMapTaskInputBuilderTest extends EngineTestCase {
-  static final AnalysisTarget target1 = new TestSource('target1');
-  static final ResultDescriptorImpl<List> result1 =
-      new ResultDescriptorImpl<List>('result1', null);
-  static final ResultDescriptorImpl result2 =
-      new ResultDescriptorImpl('result2', null);
-  static final ListToMapTaskInput input = new ListToMapTaskInput(
-      result1.of(target1), (element) => result2.of(element));
-
-  test_create() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(builder, isNotNull);
-    expect(builder.input, input);
-  }
-
-  test_currentResult_afterComplete() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValue = [];
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterCurrentValueNotAvailable() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterOneMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    expect(builder.currentResult, result1);
-  }
-
-  test_currentResult_beforeMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(builder.currentResult, null);
-  }
-
-  test_currentTarget_afterComplete() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValue = [];
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterCurrentValueNotAvailable() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterOneMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    expect(builder.currentTarget, target1);
-  }
-
-  test_currentTarget_beforeMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentValue_afterOneMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValue = [];
-  }
-
-  test_currentValue_beforeMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(() {
-      builder.currentValue = [];
-    }, throwsStateError);
-  }
-
-  test_currentValueNotAvailable_afterOneMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-  }
-
-  test_currentValueNotAvailable_beforeMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(() {
-      builder.currentValueNotAvailable();
-    }, throwsStateError);
-  }
-
-  test_inputValue_afterComplete() {
-    AnalysisTarget target2 = new TestSource('target2');
-    AnalysisTarget target3 = new TestSource('target3');
-    String value2 = 'value2';
-    String value3 = 'value3';
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext(); // Advance to requesting the list
-    builder.currentValue = [target2, target3];
-    builder.moveNext(); // Advance to requesting result2 for target2
-    builder.currentValue = value2;
-    builder.moveNext(); // Advance to requesting result2 for target3
-    builder.currentValue = value3;
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<Map>());
-    expect(inputValue.length, 2);
-    expect(inputValue, containsPair(target2, value2));
-    expect(inputValue, containsPair(target3, value3));
-  }
-
-  test_inputValue_afterFirstValueNotAvailable() {
-    AnalysisTarget target2 = new TestSource('target2');
-    AnalysisTarget target3 = new TestSource('target3');
-    String value3 = 'value3';
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext(); // Advance to requesting the list
-    builder.currentValue = [target2, target3];
-    builder.moveNext(); // Advance to requesting result2 for target2
-    builder.currentValueNotAvailable();
-    builder.moveNext(); // Advance to requesting result2 for target3
-    builder.currentValue = value3;
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<Map>());
-    expect(inputValue, hasLength(1));
-    expect(inputValue, containsPair(target3, value3));
-  }
-
-  test_inputValue_afterListNotAvailable() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext(); // Advance to requesting the list
-    builder.currentValueNotAvailable();
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<Map>());
-    expect(inputValue, isEmpty);
-  }
-
-  test_inputValue_afterOneMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    builder.moveNext();
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_inputValue_beforeMoveNext() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_moveNext_withoutSet() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(builder.moveNext(), true);
-    expect(() => builder.moveNext(), throwsStateError);
-  }
-
-  test_moveNext_withSet() {
-    ListToMapTaskInputBuilder builder = new ListToMapTaskInputBuilder(input);
-    expect(builder.moveNext(), true);
-    builder.currentValue = [];
-    expect(builder.moveNext(), false);
-    expect(builder.moveNext(), false);
-  }
-}
-
-@reflectiveTest
-class ListToMapTaskInputTest extends EngineTestCase {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl<List> result =
-      new ResultDescriptorImpl<List>('result', null);
-
-  test_create() {
-    SimpleTaskInput<List> baseAccessor = result.of(target);
-    GenerateTaskInputs generate = (object) => null;
-    ListToMapTaskInput input = new ListToMapTaskInput(baseAccessor, generate);
-    expect(input, isNotNull);
-    expect(input.baseAccessor, baseAccessor);
-    expect(input.generateTaskInputs, equals(generate));
-  }
-
-  test_createBuilder() {
-    SimpleTaskInput<List> baseAccessor = result.of(target);
-    GenerateTaskInputs generate = (object) => null;
-    ListToMapTaskInput input = new ListToMapTaskInput(baseAccessor, generate);
-    expect(input.createBuilder(), isNotNull);
-  }
-}
-
-@reflectiveTest
-class ObjectToListTaskInputBuilderTest {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl result =
-      new ResultDescriptorImpl('result', null);
-  static final SimpleTaskInput baseInput = new SimpleTaskInput(target, result);
-  static final mapper = (Object x) => [x];
-  static final ObjectToListTaskInput input =
-      new ObjectToListTaskInput(baseInput, mapper);
-
-  ObjectToListTaskInputBuilder builder;
-
-  void setUp() {
-    builder = new ObjectToListTaskInputBuilder(input);
-  }
-
-  test_create() {
-    expect(builder, isNotNull);
-    expect(builder.input, input);
-  }
-
-  test_currentResult_afterComplete() {
-    builder.moveNext();
-    builder.currentValue = 'value';
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterCurrentValueNotAvailable() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterOneMoveNext() {
-    builder.moveNext();
-    expect(builder.currentResult, result);
-  }
-
-  test_currentResult_beforeMoveNext() {
-    expect(builder.currentResult, null);
-  }
-
-  test_currentTarget_afterComplete() {
-    builder.moveNext();
-    builder.currentValue = 'value';
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterCurrentValueNotAvailable() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterOneMoveNext() {
-    builder.moveNext();
-    expect(builder.currentTarget, target);
-  }
-
-  test_currentTarget_beforeMoveNext() {
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentValue_afterOneMoveNext() {
-    builder.moveNext();
-    builder.currentValue = 'value';
-  }
-
-  test_currentValue_beforeMoveNext() {
-    expect(() {
-      builder.currentValue = 'value';
-    }, throwsStateError);
-  }
-
-  test_currentValueNotAvailable_afterOneMoveNext() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-  }
-
-  test_currentValueNotAvailable_beforeMoveNext() {
-    expect(() {
-      builder.currentValueNotAvailable();
-    }, throwsStateError);
-  }
-
-  test_inputValue_afterComplete() {
-    builder.moveNext();
-    String value = 'value';
-    builder.currentValue = value;
-    builder.moveNext();
-    expect(builder.inputValue, [value]);
-  }
-
-  test_inputValue_afterCurrentValueNotAvailable() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.inputValue, [null]);
-  }
-
-  test_inputValue_afterOneMoveNext() {
-    builder.moveNext();
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_inputValue_beforeMoveNext() {
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_moveNext_withoutSet() {
-    expect(builder.moveNext(), true);
-    expect(() => builder.moveNext(), throwsStateError);
-  }
-
-  test_moveNext_withSet() {
-    expect(builder.moveNext(), true);
-    builder.currentValue = 'value';
-    expect(builder.moveNext(), false);
-    expect(builder.moveNext(), false);
-  }
-}
-
-@reflectiveTest
-class ObjectToListTaskInputTest extends EngineTestCase {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl result =
-      new ResultDescriptorImpl('result', null);
-
-  test_create() {
-    SimpleTaskInput baseInput = new SimpleTaskInput(target, result);
-    var mapper = (Object x) => [x];
-    ObjectToListTaskInput input = new ObjectToListTaskInput(baseInput, mapper);
-    expect(input, isNotNull);
-    expect(input.baseInput, baseInput);
-    expect(input.mapper, equals(mapper));
-  }
-
-  test_createBuilder() {
-    SimpleTaskInput baseInput = new SimpleTaskInput(target, result);
-    var mapper = (Object x) => [x];
-    ObjectToListTaskInput input = new ObjectToListTaskInput(baseInput, mapper);
-    expect(
-        input.createBuilder(), new TypeMatcher<ObjectToListTaskInputBuilder>());
-  }
-}
-
-@reflectiveTest
-class SimpleTaskInputBuilderTest {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl result =
-      new ResultDescriptorImpl('result', null);
-  static final SimpleTaskInput input = new SimpleTaskInput(target, result);
-
-  SimpleTaskInputBuilder builder;
-
-  void setUp() {
-    builder = new SimpleTaskInputBuilder(input);
-  }
-
-  test_create() {
-    expect(builder, isNotNull);
-    expect(builder.input, input);
-  }
-
-  test_currentResult_afterComplete() {
-    builder.moveNext();
-    builder.currentValue = 'value';
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterCurrentValueNotAvailable() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterOneMoveNext() {
-    builder.moveNext();
-    expect(builder.currentResult, result);
-  }
-
-  test_currentResult_beforeMoveNext() {
-    expect(builder.currentResult, null);
-  }
-
-  test_currentTarget_afterComplete() {
-    builder.moveNext();
-    builder.currentValue = 'value';
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterCurrentValueNotAvailable() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterOneMoveNext() {
-    builder.moveNext();
-    expect(builder.currentTarget, target);
-  }
-
-  test_currentTarget_beforeMoveNext() {
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentValue_afterOneMoveNext() {
-    builder.moveNext();
-    builder.currentValue = 'value';
-  }
-
-  test_currentValue_beforeMoveNext() {
-    expect(() {
-      builder.currentValue = 'value';
-    }, throwsStateError);
-  }
-
-  test_currentValueNotAvailable_afterOneMoveNext() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-  }
-
-  test_currentValueNotAvailable_beforeMoveNext() {
-    expect(() {
-      builder.currentValueNotAvailable();
-    }, throwsStateError);
-  }
-
-  test_inputValue_afterComplete() {
-    builder.moveNext();
-    String value = 'value';
-    builder.currentValue = value;
-    builder.moveNext();
-    expect(builder.inputValue, value);
-  }
-
-  test_inputValue_afterCurrentValueNotAvailable() {
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.inputValue, isNull);
-  }
-
-  test_inputValue_afterOneMoveNext() {
-    builder.moveNext();
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_inputValue_beforeMoveNext() {
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_moveNext_withoutSet() {
-    expect(builder.moveNext(), true);
-    expect(() => builder.moveNext(), throwsStateError);
-  }
-
-  test_moveNext_withSet() {
-    expect(builder.moveNext(), true);
-    builder.currentValue = 'value';
-    expect(builder.moveNext(), false);
-    expect(builder.moveNext(), false);
-  }
-}
-
-@reflectiveTest
-class SimpleTaskInputTest extends EngineTestCase {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl result =
-      new ResultDescriptorImpl('result', null);
-
-  test_create() {
-    SimpleTaskInput input = new SimpleTaskInput(target, result);
-    expect(input, isNotNull);
-    expect(input.target, target);
-    expect(input.result, result);
-  }
-
-  test_createBuilder() {
-    SimpleTaskInput input = new SimpleTaskInput(target, result);
-    expect(input.createBuilder(), new TypeMatcher<SimpleTaskInputBuilder>());
-  }
-}
-
-@reflectiveTest
-class TopLevelTaskInputBuilderTest extends EngineTestCase {
-  static final AnalysisTarget target = new TestSource();
-  static final ResultDescriptorImpl result1 =
-      new ResultDescriptorImpl('result1', null);
-  static final ResultDescriptorImpl result2 =
-      new ResultDescriptorImpl('result2', null);
-  static final SimpleTaskInput input1 = new SimpleTaskInput(target, result1);
-  static final SimpleTaskInput input2 = new SimpleTaskInput(target, result2);
-
-  test_create() {
-    Map<String, TaskInput> inputDescriptors = {};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(builder, isNotNull);
-    expect(builder.inputDescriptors, inputDescriptors);
-  }
-
-  test_currentResult_afterComplete() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValue = 'value1';
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterCurrentValueNotAvailable() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentResult, null);
-  }
-
-  test_currentResult_afterOneMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1, 'two': input2};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    expect(builder.currentResult, result1);
-  }
-
-  test_currentResult_afterTwoMoveNext_withConstantInput() {
-    ConstantTaskInput<int> constantInput = new ConstantTaskInput<int>(11);
-    Map<String, TaskInput> inputDescriptors = <String, TaskInput>{
-      'one': input1,
-      'constant': constantInput,
-      'two': input2
-    };
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValue = 'value1';
-    builder.moveNext();
-    expect(builder.currentResult, result2);
-  }
-
-  test_currentResult_beforeMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(builder.currentResult, null);
-  }
-
-  test_currentTarget_afterComplete() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValue = 'value1';
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterCurrentValueNotAvailable() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-    builder.moveNext();
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentTarget_afterOneMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    expect(builder.currentTarget, target);
-  }
-
-  test_currentTarget_afterTwoMoveNext_withConstantInput() {
-    ConstantTaskInput<int> constantInput = new ConstantTaskInput<int>(11);
-    Map<String, TaskInput> inputDescriptors = <String, TaskInput>{
-      'one': input1,
-      'constant': constantInput,
-      'two': input2
-    };
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValue = 'value1';
-    builder.moveNext();
-    expect(builder.currentTarget, target);
-  }
-
-  test_currentTarget_beforeMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(builder.currentTarget, null);
-  }
-
-  test_currentValue_afterOneMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValue = 'value1';
-  }
-
-  test_currentValue_beforeMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(() {
-      builder.currentValue = 'value1';
-    }, throwsStateError);
-  }
-
-  test_currentValueNotAvailable_afterOneMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    builder.currentValueNotAvailable();
-  }
-
-  test_currentValueNotAvailable_beforeMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(() {
-      builder.currentValueNotAvailable();
-    }, throwsStateError);
-  }
-
-  test_inputValue_afterComplete() {
-    String key1 = 'one';
-    String key2 = 'two';
-    String value1 = 'value1';
-    String value2 = 'value2';
-    Map<String, TaskInput> inputDescriptors = {key1: input1, key2: input2};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext(); // Advance to requesting result1 for target
-    builder.currentValue = value1;
-    builder.moveNext(); // Advance to requesting result2 for target
-    builder.currentValue = value2;
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<Map>());
-    Map inputs = inputValue;
-    expect(inputs.length, 2);
-    expect(inputs, containsPair(key1, value1));
-    expect(inputs, containsPair(key2, value2));
-  }
-
-  test_inputValue_afterOneMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext();
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_inputValue_afterOneValueNotAvailable() {
-    String key1 = 'one';
-    String key2 = 'two';
-    String value2 = 'value2';
-    Map<String, TaskInput> inputDescriptors = {key1: input1, key2: input2};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    builder.moveNext(); // Advance to requesting result1 for target
-    builder.currentValueNotAvailable();
-    builder.moveNext(); // Advance to requesting result2 for target
-    builder.currentValue = value2;
-    builder.moveNext(); // Advance to the end
-    var inputValue = builder.inputValue;
-    expect(inputValue, new TypeMatcher<Map>());
-    Map inputs = inputValue;
-    expect(inputs, hasLength(1));
-    expect(inputs, containsPair(key2, value2));
-  }
-
-  test_inputValue_beforeMoveNext() {
-    Map<String, TaskInput> inputDescriptors = {};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(() => builder.inputValue, throwsStateError);
-  }
-
-  test_moveNext_withoutSet() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(builder.moveNext(), true);
-    expect(() => builder.moveNext(), throwsStateError);
-  }
-
-  test_moveNext_withSet() {
-    Map<String, TaskInput> inputDescriptors = {'one': input1};
-    TopLevelTaskInputBuilder builder =
-        new TopLevelTaskInputBuilder(inputDescriptors);
-    expect(builder.moveNext(), true);
-    builder.currentValue = 'value1';
-    expect(builder.moveNext(), false);
-    expect(builder.moveNext(), false);
-  }
-}
diff --git a/pkg/analyzer/test/src/task/manager_test.dart b/pkg/analyzer/test/src/task/manager_test.dart
deleted file mode 100644
index b91e829..0000000
--- a/pkg/analyzer/test/src/task/manager_test.dart
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/manager.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(TaskManagerTest);
-  });
-}
-
-@reflectiveTest
-class TaskManagerTest extends EngineTestCase {
-  static final ResultDescriptor result1 = new ResultDescriptor('result1', null);
-  static final ResultDescriptor result2 = new ResultDescriptor('result2', null);
-
-  test_addGeneralResult() {
-    TaskManager manager = new TaskManager();
-    manager.addGeneralResult(result1);
-    Set<ResultDescriptor> results = manager.generalResults;
-    expect(results, unorderedEquals([result1]));
-  }
-
-  test_addPriorityResult() {
-    TaskManager manager = new TaskManager();
-    manager.addPriorityResult(result1);
-    Set<ResultDescriptor> results = manager.priorityResults;
-    expect(results, unorderedEquals([result1]));
-  }
-
-  test_addTaskDescriptor() {
-    TaskManager manager = new TaskManager();
-    TaskDescriptor descriptor =
-        new TaskDescriptor('task', null, null, [result1]);
-    manager.addTaskDescriptor(descriptor);
-    expect(manager.taskMap.length, 1);
-  }
-
-  test_constructor() {
-    TaskManager manager = new TaskManager();
-    expect(manager, isNotNull);
-    expect(manager.generalResults, isEmpty);
-    expect(manager.priorityResults, isEmpty);
-  }
-
-  test_findTask_defined() {
-    TaskManager manager = new TaskManager();
-    TaskDescriptor descriptor =
-        new TaskDescriptor('task', null, null, [result1]);
-    manager.addTaskDescriptor(descriptor);
-    AnalysisTarget target = new TestSource();
-    expect(manager.findTask(target, result1), descriptor);
-  }
-
-  test_findTask_empty() {
-    TaskManager manager = new TaskManager();
-    AnalysisTarget target = new TestSource();
-    expect(() => manager.findTask(target, result1),
-        throwsA(new TypeMatcher<AnalysisException>()));
-  }
-
-  test_findTask_multiple() {
-    TaskManager manager = new TaskManager();
-    TaskDescriptor descriptor1 =
-        new TaskDescriptor('task1', null, null, [result1]);
-    manager.addTaskDescriptor(descriptor1);
-    TaskDescriptor descriptor2 =
-        new TaskDescriptor('task2', null, null, [result1]);
-    manager.addTaskDescriptor(descriptor2);
-    TaskDescriptor descriptor3 =
-        new TaskDescriptor('task3', null, null, [result2]);
-    manager.addTaskDescriptor(descriptor3);
-
-    AnalysisTarget target = new TestSource();
-    TaskDescriptor task = manager.findTask(target, result1);
-    expect(task == descriptor1 || task == descriptor2, true);
-  }
-
-  test_findTask_undefined() {
-    TaskManager manager = new TaskManager();
-    TaskDescriptor descriptor =
-        new TaskDescriptor('task', null, null, [result1]);
-    manager.addTaskDescriptor(descriptor);
-    AnalysisTarget target = new TestSource();
-    expect(() => manager.findTask(target, result2),
-        throwsA(new TypeMatcher<AnalysisException>()));
-  }
-
-  test_removeGeneralResult_absent() {
-    TaskManager manager = new TaskManager();
-    manager.addGeneralResult(result1);
-    Set<ResultDescriptor> results = manager.generalResults;
-    expect(results, unorderedEquals([result1]));
-  }
-
-  test_removeGeneralResult_present() {
-    TaskManager manager = new TaskManager();
-    manager.addGeneralResult(result1);
-    manager.addGeneralResult(result2);
-    Set<ResultDescriptor> results = manager.generalResults;
-    expect(results, unorderedEquals([result1, result2]));
-    manager.removeGeneralResult(result1);
-    expect(results, unorderedEquals([result2]));
-  }
-
-  test_removePriorityResult_absent() {
-    TaskManager manager = new TaskManager();
-    manager.addPriorityResult(result1);
-    manager.removePriorityResult(result2);
-    Set<ResultDescriptor> results = manager.priorityResults;
-    expect(results, unorderedEquals([result1]));
-  }
-
-  test_removePriorityResult_present() {
-    TaskManager manager = new TaskManager();
-    manager.addPriorityResult(result1);
-    manager.addPriorityResult(result2);
-    Set<ResultDescriptor> results = manager.priorityResults;
-    expect(results, unorderedEquals([result1, result2]));
-    manager.removePriorityResult(result1);
-    expect(results, unorderedEquals([result2]));
-  }
-}
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
deleted file mode 100644
index 65b78ca..0000000
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/model.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/test_support.dart';
-import 'test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(AnalysisTaskTest);
-    defineReflectiveTests(ResultDescriptorImplTest);
-    defineReflectiveTests(SimpleResultCachingPolicyTest);
-    defineReflectiveTests(TaskDescriptorImplTest);
-  });
-}
-
-@reflectiveTest
-class AnalysisTaskTest extends EngineTestCase {
-  test_getRequiredInput_missingKey() {
-    AnalysisTarget target = new TestSource();
-    AnalysisTask task = new TestAnalysisTask(null, target);
-    task.inputs = {'a': 'b'};
-    expect(() => task.getRequiredInput('c'),
-        throwsA(new TypeMatcher<AnalysisException>()));
-  }
-
-  test_getRequiredInput_noInputs() {
-    AnalysisTarget target = new TestSource();
-    AnalysisTask task = new TestAnalysisTask(null, target);
-    expect(() => task.getRequiredInput('x'),
-        throwsA(new TypeMatcher<AnalysisException>()));
-  }
-
-  test_getRequiredInput_valid() {
-    AnalysisTarget target = new TestSource();
-    AnalysisTask task = new TestAnalysisTask(null, target);
-    String key = 'a';
-    String value = 'b';
-    task.inputs = {key: value};
-    expect(task.getRequiredInput(key), value);
-  }
-
-  test_getRequiredSource() {
-    AnalysisTarget target = new TestSource();
-    AnalysisTask task = new TestAnalysisTask(null, target);
-    expect(task.getRequiredSource(), target);
-  }
-}
-
-@reflectiveTest
-class ResultDescriptorImplTest extends EngineTestCase {
-  test_create_withCachingPolicy() {
-    ResultCachingPolicy policy = new SimpleResultCachingPolicy(128, 16);
-    ResultDescriptorImpl result =
-        new ResultDescriptorImpl('result', null, cachingPolicy: policy);
-    expect(result.cachingPolicy, same(policy));
-  }
-
-  test_create_withoutCachingPolicy() {
-    ResultDescriptorImpl result = new ResultDescriptorImpl('result', null);
-    ResultCachingPolicy cachingPolicy = result.cachingPolicy;
-    expect(cachingPolicy, isNotNull);
-    expect(cachingPolicy.maxActiveSize, -1);
-    expect(cachingPolicy.maxIdleSize, -1);
-  }
-
-  test_create_withoutContribution() {
-    expect(new ResultDescriptorImpl('name', null), isNotNull);
-  }
-
-  test_inputFor() {
-    AnalysisTarget target = new TestSource();
-    ResultDescriptorImpl result = new ResultDescriptorImpl('result', null);
-    TaskInput input = result.of(target);
-    expect(input, isNotNull);
-  }
-
-  test_name() {
-    String name = 'result';
-    ResultDescriptorImpl result = new ResultDescriptorImpl(name, null);
-    expect(result.name, name);
-  }
-}
-
-@reflectiveTest
-class SimpleResultCachingPolicyTest extends EngineTestCase {
-  test_create() {
-    ResultCachingPolicy policy = new SimpleResultCachingPolicy(256, 32);
-    expect(policy.maxActiveSize, 256);
-    expect(policy.maxIdleSize, 32);
-    expect(policy.measure(null), 1);
-  }
-}
-
-@reflectiveTest
-class TaskDescriptorImplTest extends EngineTestCase {
-  test_create_noOptionalArgs() {
-    String name = 'name';
-    BuildTask buildTask = (context, target) => null;
-    CreateTaskInputs createTaskInputs = (target) => null;
-    List<ResultDescriptor> results = <ResultDescriptor>[];
-    TaskDescriptorImpl descriptor =
-        new TaskDescriptorImpl(name, buildTask, createTaskInputs, results);
-    expect(descriptor, isNotNull);
-    expect(descriptor.name, name);
-    expect(descriptor.buildTask, equals(buildTask));
-    expect(descriptor.createTaskInputs, equals(createTaskInputs));
-    expect(descriptor.suitabilityFor(null), TaskSuitability.LOWEST);
-    expect(descriptor.results, results);
-  }
-
-  test_create_withIsAppropriateFor() {
-    String name = 'name';
-    BuildTask buildTask = (context, target) => null;
-    CreateTaskInputs createTaskInputs = (target) => null;
-    List<ResultDescriptor> results = <ResultDescriptor>[];
-    SuitabilityFor suitabilityFor = (target) => TaskSuitability.NONE;
-    TaskDescriptorImpl descriptor = new TaskDescriptorImpl(
-        name, buildTask, createTaskInputs, results,
-        suitabilityFor: suitabilityFor);
-    expect(descriptor, isNotNull);
-    expect(descriptor.name, name);
-    expect(descriptor.buildTask, equals(buildTask));
-    expect(descriptor.createTaskInputs, equals(createTaskInputs));
-    expect(descriptor.suitabilityFor(null), TaskSuitability.NONE);
-    expect(descriptor.results, results);
-  }
-
-  test_createTask() {
-    BuildTask buildTask =
-        (context, target) => new TestAnalysisTask(context, target);
-    CreateTaskInputs createTaskInputs = (target) => null;
-    List<ResultDescriptor> results = <ResultDescriptor>[];
-    TaskDescriptorImpl descriptor =
-        new TaskDescriptorImpl('name', buildTask, createTaskInputs, results);
-    AnalysisContext context = null;
-    AnalysisTarget target = new TestSource();
-    Map<String, dynamic> inputs = {};
-    AnalysisTask createTask = descriptor.createTask(context, target, inputs);
-    expect(createTask, isNotNull);
-    expect(createTask.context, context);
-    expect(createTask.inputs, inputs);
-    expect(createTask.target, target);
-  }
-}
diff --git a/pkg/analyzer/test/src/task/options_work_manager_test.dart b/pkg/analyzer/test/src/task/options_work_manager_test.dart
deleted file mode 100644
index 8845781..0000000
--- a/pkg/analyzer/test/src/task/options_work_manager_test.dart
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/error/error.dart' show AnalysisError;
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/error/codes.dart' show AnalysisOptionsErrorCode;
-import 'package:analyzer/src/generated/engine.dart'
-    show
-        AnalysisEngine,
-        AnalysisErrorInfo,
-        AnalysisErrorInfoImpl,
-        CacheState,
-        ChangeNoticeImpl,
-        InternalAnalysisContext;
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/task/api/dart.dart';
-import 'package:analyzer/src/task/api/general.dart';
-import 'package:analyzer/src/task/api/model.dart';
-import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/task/options_work_manager.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../../generated/test_support.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(OptionsWorkManagerNewFileTest);
-    defineReflectiveTests(OptionsWorkManagerOldFileTest);
-  });
-}
-
-@reflectiveTest
-class OptionsWorkManagerNewFileTest extends OptionsWorkManagerTest {
-  String get optionsFile => AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE;
-}
-
-@reflectiveTest
-class OptionsWorkManagerOldFileTest extends OptionsWorkManagerTest {
-  String get optionsFile => AnalysisEngine.ANALYSIS_OPTIONS_FILE;
-}
-
-abstract class OptionsWorkManagerTest {
-  _InternalAnalysisContextMock context = new _InternalAnalysisContextMock();
-  AnalysisCache cache;
-  OptionsWorkManager manager;
-
-  CaughtException caughtException = new CaughtException(null, null);
-
-  Source source1;
-
-  Source source2;
-  Source source3;
-  Source source4;
-  CacheEntry entry1;
-  CacheEntry entry2;
-  CacheEntry entry3;
-  CacheEntry entry4;
-  String get optionsFile;
-
-  void expect_sourceQueue(List<Source> sources) {
-    expect(manager.sourceQueue, unorderedEquals(sources));
-  }
-
-  void setUp() {
-    cache = context.analysisCache;
-    manager = new OptionsWorkManager(context);
-    source1 = new TestSource('test1/$optionsFile');
-    source2 = new TestSource('test2/$optionsFile');
-    source3 = new TestSource('test3/$optionsFile');
-    source4 = new TestSource('test4/$optionsFile');
-    entry1 = context.getCacheEntry(source1);
-    entry2 = context.getCacheEntry(source2);
-    entry3 = context.getCacheEntry(source3);
-    entry4 = context.getCacheEntry(source4);
-  }
-
-  void test_applyChange_add() {
-    // add source1
-    manager.applyChange([source1], [], []);
-    expect_sourceQueue([source1]);
-    // add source2
-    manager.applyChange([source2], [], []);
-    expect_sourceQueue([source1, source2]);
-  }
-
-  void test_applyChange_add_duplicate() {
-    // add source1
-    manager.applyChange([source1], [], []);
-    expect_sourceQueue([source1]);
-    // add source1 again
-    manager.applyChange([source1], [], []);
-    expect_sourceQueue([source1]);
-  }
-
-  void test_applyChange_change() {
-    // change source1
-    manager.applyChange([], [source1], []);
-    expect_sourceQueue([source1]);
-  }
-
-  void test_applyChange_change_afterAdd() {
-    manager.applyChange([source1, source2], [], []);
-    // change source1
-    manager.applyChange([], [source1], []);
-    expect_sourceQueue([source1, source2]);
-  }
-
-  void test_applyChange_remove() {
-    manager.applyChange([source1, source2], [], []);
-    // remove source1
-    manager.applyChange([], [], [source1]);
-    expect_sourceQueue([source2]);
-    // remove source2
-    manager.applyChange([], [], [source2]);
-    expect_sourceQueue([]);
-    // remove source3
-    manager.applyChange([], [], [source3]);
-    expect_sourceQueue([]);
-  }
-
-  void test_applyPriorityTargets() {
-    context.setShouldErrorsBeAnalyzed(source2, true);
-    context.setShouldErrorsBeAnalyzed(source3, true);
-    manager.priorityResultQueue
-        .add(new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS));
-    manager.priorityResultQueue
-        .add(new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS));
-    // -source1 +source3
-    manager.applyPriorityTargets([source2, source3]);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS),
-          new TargetedResult(source3, ANALYSIS_OPTIONS_ERRORS)
-        ]));
-    // get next request
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
-  }
-
-  void test_getErrors() {
-    AnalysisError error1 = new AnalysisError(
-        source1, 1, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
-    AnalysisError error2 = new AnalysisError(
-        source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
-    entry1
-        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
-
-    List<AnalysisError> errors = manager.getErrors(source1);
-    expect(errors, unorderedEquals([error1, error2]));
-  }
-
-  void test_getNextResult_hasNormal_firstIsError() {
-    entry1.setErrorState(caughtException, [ANALYSIS_OPTIONS_ERRORS]);
-    manager.sourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
-    // source1 is out, source2 is waiting
-    expect_sourceQueue([source2]);
-  }
-
-  void test_getNextResult_hasNormal_firstIsInvalid() {
-    entry1.setState(ANALYSIS_OPTIONS_ERRORS, CacheState.INVALID);
-    manager.sourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source1);
-    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
-    // no changes until computed
-    expect_sourceQueue([source1, source2]);
-  }
-
-  void test_getNextResult_hasNormal_firstIsValid() {
-    entry1.setValue(ANALYSIS_OPTIONS_ERRORS, [], []);
-    manager.sourceQueue.addAll([source1, source2]);
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source2);
-    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
-    // source1 is out, source2 is waiting
-    expect_sourceQueue([source2]);
-  }
-
-  void test_getNextResult_hasNormalAndPriority() {
-    entry1.setState(ANALYSIS_OPTIONS_ERRORS, CacheState.INVALID);
-    manager.sourceQueue.addAll([source1, source2]);
-    manager.addPriorityResult(source3, ANALYSIS_OPTIONS_ERRORS);
-
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source3);
-    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
-    // no changes until computed
-    expect_sourceQueue([source1, source2]);
-  }
-
-  void test_getNextResult_hasPriority() {
-    manager.addPriorityResult(source1, ANALYSIS_OPTIONS_ERRORS);
-    manager.addPriorityResult(source2, ANALYSIS_OPTIONS_ERRORS);
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS),
-          new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS)
-        ]));
-
-    TargetedResult request = manager.getNextResult();
-    expect(request.target, source1);
-    expect(request.result, ANALYSIS_OPTIONS_ERRORS);
-    // no changes until computed
-    expect(
-        manager.priorityResultQueue,
-        unorderedEquals([
-          new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS),
-          new TargetedResult(source2, ANALYSIS_OPTIONS_ERRORS)
-        ]));
-  }
-
-  void test_getNextResult_nothingToDo() {
-    TargetedResult request = manager.getNextResult();
-    expect(request, isNull);
-  }
-
-  void test_getNextResultPriority_hasPriority() {
-    manager.addPriorityResult(source1, SOURCE_KIND);
-    expect(manager.getNextResultPriority(), WorkOrderPriority.PRIORITY);
-  }
-
-  void test_getNextResultPriority_hasSource() {
-    manager.sourceQueue.addAll([source1]);
-    expect(manager.getNextResultPriority(), WorkOrderPriority.NORMAL);
-  }
-
-  void test_getNextResultPriority_nothingToDo() {
-    expect(manager.getNextResultPriority(), WorkOrderPriority.NONE);
-  }
-
-  void test_resultsComputed_errors() {
-    AnalysisError error1 = new AnalysisError(
-        source1, 1, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
-    AnalysisError error2 = new AnalysisError(
-        source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
-    LineInfo lineInfo = new LineInfo([0]);
-    entry1.setValue(LINE_INFO, lineInfo, []);
-    entry1
-        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
-    // RESOLVED_UNIT is ready, set errors
-    manager.resultsComputed(source1, {ANALYSIS_OPTIONS_ERRORS: null});
-    // all of the errors are included
-    ChangeNoticeImpl notice = context.getNotice(source1);
-    expect(notice.errors, unorderedEquals([error1, error2]));
-    expect(notice.lineInfo, lineInfo);
-  }
-}
-
-class _InternalAnalysisContextMock implements InternalAnalysisContext {
-  @override
-  CachePartition privateAnalysisCachePartition;
-
-  @override
-  AnalysisCache analysisCache;
-
-  Map<Source, bool> shouldErrorsBeAnalyzedMap = <Source, bool>{};
-
-  Map<Source, ChangeNoticeImpl> _pendingNotices = <Source, ChangeNoticeImpl>{};
-
-  _InternalAnalysisContextMock() {
-    privateAnalysisCachePartition = new UniversalCachePartition(this);
-    analysisCache = new AnalysisCache([privateAnalysisCachePartition]);
-  }
-
-  @override
-  CacheEntry getCacheEntry(AnalysisTarget target) {
-    CacheEntry entry = analysisCache.get(target);
-    if (entry == null) {
-      entry = new CacheEntry(target);
-      analysisCache.put(entry);
-    }
-    return entry;
-  }
-
-  @override
-  AnalysisErrorInfo getErrors(Source source) {
-    List<AnalysisError> errors = AnalysisError.NO_ERRORS;
-    if (AnalysisEngine.isAnalysisOptionsFileName(source.shortName)) {
-      errors = getCacheEntry(source).getValue(ANALYSIS_OPTIONS_ERRORS);
-    }
-    return new AnalysisErrorInfoImpl(
-        errors, getCacheEntry(source).getValue(LINE_INFO));
-  }
-
-  @override
-  ChangeNoticeImpl getNotice(Source source) =>
-      _pendingNotices.putIfAbsent(source, () => new ChangeNoticeImpl(source));
-
-  @override
-  noSuchMethod(Invocation invocation) {
-    throw new StateError('Unexpected invocation of ${invocation.memberName}');
-  }
-
-  void setShouldErrorsBeAnalyzed(Source source, bool value) {
-    shouldErrorsBeAnalyzedMap[source] = value;
-  }
-
-  @override
-  bool shouldErrorsBeAnalyzed(Source source) {
-    return shouldErrorsBeAnalyzedMap[source];
-  }
-}
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index f66959e..d6f96c1f 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -4,25 +4,12 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'dart_work_manager_test.dart' as dart_work_manager_test;
-import 'general_test.dart' as general_test;
-import 'inputs_test.dart' as inputs_test;
-import 'manager_test.dart' as manager_test;
-import 'model_test.dart' as model_test;
 import 'options_test.dart' as options_test;
-import 'options_work_manager_test.dart' as options_work_manager_test;
 import 'strong/test_all.dart' as strong_mode_test_all;
 
-/// Utility for manually running all tests.
 main() {
   defineReflectiveSuite(() {
-    dart_work_manager_test.main();
-    general_test.main();
-    inputs_test.main();
-    manager_test.main();
-    model_test.main();
     options_test.main();
-    options_work_manager_test.main();
     strong_mode_test_all.main();
   }, name: 'task');
 }
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
deleted file mode 100644
index 7415324..0000000
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:analyzer/exception/exception.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/task/api/model.dart';
-
-/**
- * A configurable analysis task that can be used by tests.
- */
-class TestAnalysisTask extends AnalysisTask {
-  /**
-   * The descriptor describing this task.
-   */
-  TaskDescriptor descriptor;
-
-  /**
-   * The exception that is to be "thrown" by this task.
-   */
-  CaughtException exception;
-
-  /**
-   * The results whose values are to be provided as outputs from this task.
-   */
-  List<ResultDescriptor> results;
-
-  /**
-   * The next value that is to be used for a result.
-   */
-  int value;
-
-  @override
-  final bool handlesDependencyCycles;
-
-  TestAnalysisTask(AnalysisContext context, AnalysisTarget target,
-      {this.descriptor,
-      this.exception,
-      this.handlesDependencyCycles: false,
-      this.results,
-      this.value: 1})
-      : super(context, target);
-
-  @override
-  String get description => 'Test task';
-
-  @override
-  internalPerform() {
-    if (exception != null) {
-      caughtException = exception;
-    } else if (results != null) {
-      for (ResultDescriptor result in results) {
-        outputs[result] = value++;
-      }
-    } else if (descriptor != null) {
-      for (ResultDescriptor result in descriptor.results) {
-        outputs[result] = value++;
-      }
-    }
-  }
-}
