// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// This code was auto-generated, is not intended to be edited, and is subject to
// significant change. Please see the README file for more information.

library engine.engine_test;

import 'dart:async';
import 'dart:collection';

import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/generated/ast.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/element.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/html.dart' as ht;
import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_engine_io.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/scanner.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/sdk_io.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:analyzer/src/string_source.dart';
import 'package:analyzer/src/task/task_dart.dart';
import 'package:typed_mock/typed_mock.dart';
import 'package:unittest/unittest.dart';
import 'package:watcher/src/utils.dart';

import '../reflective_tests.dart';
import 'all_the_rest_test.dart';
import 'resolver_test.dart';
import 'test_support.dart';


main() {
  groupSep = ' | ';
  runReflectiveTests(AnalysisCacheTest);
  runReflectiveTests(AnalysisContextImplTest);
  runReflectiveTests(AnalysisTaskTest);
  runReflectiveTests(AnalysisOptionsImplTest);
  runReflectiveTests(DartEntryTest);
  runReflectiveTests(GenerateDartErrorsTaskTest);
  runReflectiveTests(GenerateDartHintsTaskTest);
  runReflectiveTests(GenerateDartLintsTaskTest);
  runReflectiveTests(GetContentTaskTest);
  runReflectiveTests(HtmlEntryTest);
  runReflectiveTests(IncrementalAnalysisCacheTest);
  runReflectiveTests(IncrementalAnalysisTaskTest);
  runReflectiveTests(LintGeneratorTest);
  runReflectiveTests(ParseDartTaskTest);
  runReflectiveTests(ParseHtmlTaskTest);
  runReflectiveTests(PartitionManagerTest);
  runReflectiveTests(ResolveDartLibraryTaskTest);
  runReflectiveTests(ResolveDartUnitTaskTest);
  runReflectiveTests(ResolveHtmlTaskTest);
  runReflectiveTests(ScanDartTaskTest);
  runReflectiveTests(SdkCachePartitionTest);
  runReflectiveTests(SourcesChangedEventTest);
  runReflectiveTests(UniversalCachePartitionTest);
  runReflectiveTests(WorkManagerTest);
}


@reflectiveTest
class AnalysisCacheTest extends EngineTestCase {
  void test_creation() {
    expect(new AnalysisCache(new List<CachePartition>(0)), isNotNull);
  }

  void test_get() {
    AnalysisCache cache = new AnalysisCache(new List<CachePartition>(0));
    TestSource source = new TestSource();
    expect(cache.get(source), isNull);
  }

  void test_iterator() {
    CachePartition partition =
        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
    TestSource source = new TestSource();
    DartEntry entry = new DartEntry();
    cache.put(source, entry);
    MapIterator<Source, SourceEntry> iterator = cache.iterator();
    expect(iterator.moveNext(), isTrue);
    expect(iterator.key, same(source));
    expect(iterator.value, same(entry));
    expect(iterator.moveNext(), isFalse);
  }

  void test_put_noFlush() {
    CachePartition partition =
        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
    TestSource source = new TestSource();
    DartEntry entry = new DartEntry();
    cache.put(source, entry);
    expect(cache.get(source), same(entry));
  }

  void test_setMaxCacheSize() {
    CachePartition partition = new UniversalCachePartition(
        null,
        8,
        new _AnalysisCacheTest_test_setMaxCacheSize());
    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
    int size = 6;
    for (int i = 0; i < size; i++) {
      Source source = new TestSource("/test$i.dart");
      DartEntry entry = new DartEntry();
      entry.setValue(DartEntry.PARSED_UNIT, null);
      cache.put(source, entry);
      cache.accessedAst(source);
    }
    _assertNonFlushedCount(size, cache);
    int newSize = size - 2;
    partition.maxCacheSize = newSize;
    _assertNonFlushedCount(newSize, cache);
  }

  void test_size() {
    CachePartition partition =
        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
    int size = 4;
    for (int i = 0; i < size; i++) {
      Source source = new TestSource("/test$i.dart");
      cache.put(source, new DartEntry());
      cache.accessedAst(source);
    }
    expect(cache.size(), size);
  }

  void _assertNonFlushedCount(int expectedCount, AnalysisCache cache) {
    int nonFlushedCount = 0;
    MapIterator<Source, SourceEntry> iterator = cache.iterator();
    while (iterator.moveNext()) {
      if (iterator.value.getState(DartEntry.PARSED_UNIT) !=
          CacheState.FLUSHED) {
        nonFlushedCount++;
      }
    }
    expect(nonFlushedCount, expectedCount);
  }
}


@reflectiveTest
class AnalysisContextImplTest extends EngineTestCase {
  /**
   * An analysis context whose source factory is [sourceFactory].
   */
  AnalysisContextImpl _context;

  /**
   * The source factory associated with the analysis [context].
   */
  SourceFactory _sourceFactory;

  void fail_extractContext() {
    fail("Implement this");
  }

  void fail_mergeContext() {
    fail("Implement this");
  }

  void fail_performAnalysisTask_importedLibraryDelete_html() {
    Source htmlSource = _addSource("/page.html", r'''
<html><body><script type="application/dart">
  import 'libB.dart';
  main() {print('hello dart');}
</script></body></html>''');
    Source libBSource = _addSource("/libB.dart", "library libB;");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedHtmlUnit(htmlSource),
        isNotNull,
        reason: "htmlUnit resolved 1");
    expect(
        _context.getResolvedCompilationUnit2(libBSource, libBSource),
        isNotNull,
        reason: "libB resolved 1");
    expect(
        !_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
        isTrue,
        reason: "htmlSource doesn't have errors");
    // remove libB.dart content and analyze
    _context.setContents(libBSource, null);
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedHtmlUnit(htmlSource),
        isNotNull,
        reason: "htmlUnit resolved 1");
    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
    expect(
        _hasAnalysisErrorWithErrorSeverity(errors),
        isTrue,
        reason: "htmlSource has an error");
  }

  void fail_recordLibraryElements() {
    fail("Implement this");
  }

  @override
  void setUp() {
    _context = new AnalysisContextImpl();
    _sourceFactory = new SourceFactory(
        [new DartUriResolver(DirectoryBasedDartSdk.defaultSdk), new FileUriResolver()]);
    _context.sourceFactory = _sourceFactory;
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.con1(_context.analysisOptions);
    options.cacheSize = 256;
    _context.analysisOptions = options;
  }

  @override
  void tearDown() {
    _context = null;
    _sourceFactory = null;
    super.tearDown();
  }

  Future test_applyChanges_add() {
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(source);
    _context.applyChanges(changeSet);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertNoMoreEvents();
    });
  }

  Future test_applyChanges_change() {
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    _context.applyChanges(changeSet1);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    Source source2 =
        new FileBasedSource.con1(FileUtilities2.createFile("/test2.dart"));
    ChangeSet changeSet2 = new ChangeSet();
    changeSet2.addedSource(source2);
    changeSet2.changedSource(source);
    _context.applyChanges(changeSet2);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
      listener.assertNoMoreEvents();
    });
  }

  Future test_applyChanges_change_content() {
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    _context.applyChanges(changeSet1);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    Source source2 =
        new FileBasedSource.con1(FileUtilities2.createFile("/test2.dart"));
    ChangeSet changeSet2 = new ChangeSet();
    changeSet2.addedSource(source2);
    changeSet2.changedContent(source, 'library test;');
    _context.applyChanges(changeSet2);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
      listener.assertNoMoreEvents();
    });
  }

  void test_applyChanges_change_flush_element() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source librarySource = _addSource("/lib.dart", r'''
library lib;
int a = 0;''');
    expect(_context.computeLibraryElement(librarySource), isNotNull);
    _context.setContents(librarySource, r'''
library lib;
int aa = 0;''');
    expect(_context.getLibraryElement(librarySource), isNull);
  }

  Future test_applyChanges_change_multiple() {
    _context = AnalysisContextFactory.contextWithCore();
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    _sourceFactory = _context.sourceFactory;
    String libraryContents1 = r'''
library lib;
part 'part.dart';
int a = 0;''';
    Source librarySource = _addSource("/lib.dart", libraryContents1);
    String partContents1 = r'''
part of lib;
int b = a;''';
    Source partSource = _addSource("/part.dart", partContents1);
    _context.computeLibraryElement(librarySource);
    String libraryContents2 = r'''
library lib;
part 'part.dart';
int aa = 0;''';
    _context.setContents(librarySource, libraryContents2);
    String partContents2 = r'''
part of lib;
int b = aa;''';
    _context.setContents(partSource, partContents2);
    _context.computeLibraryElement(librarySource);
    CompilationUnit libraryUnit =
        _context.resolveCompilationUnit2(librarySource, librarySource);
    CompilationUnit partUnit =
        _context.resolveCompilationUnit2(partSource, librarySource);
    TopLevelVariableDeclaration declaration =
        libraryUnit.declarations[0] as TopLevelVariableDeclaration;
    Element declarationElement = declaration.variables.variables[0].element;
    TopLevelVariableDeclaration use =
        partUnit.declarations[0] as TopLevelVariableDeclaration;
    Element useElement =
        (use.variables.variables[0].initializer as SimpleIdentifier).staticElement;
    expect(
        (useElement as PropertyAccessorElement).variable,
        same(declarationElement));
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [partSource]);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertEvent(changedSources: [partSource]);
      listener.assertNoMoreEvents();
    });
  }

  Future test_applyChanges_change_range() {
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    _context.applyChanges(changeSet1);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    Source source2 =
        new FileBasedSource.con1(FileUtilities2.createFile("/test2.dart"));
    ChangeSet changeSet2 = new ChangeSet();
    changeSet2.addedSource(source2);
    changeSet2.changedRange(source, 'library test;', 0, 0, 13);
    _context.applyChanges(changeSet2);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
      listener.assertNoMoreEvents();
    });
  }

  void test_applyChanges_empty() {
    _context.applyChanges(new ChangeSet());
    expect(_context.performAnalysisTask().changeNotices, isNull);
  }

  void test_applyChanges_overriddenSource() {
    // Note: addSource adds the source to the contentCache.
    Source source = _addSource("/test.dart", "library test;");
    _context.computeErrors(source);
    while (!_context.sourcesNeedingProcessing.isEmpty) {
      _context.performAnalysisTask();
    }
    // Adding the source as a changedSource should have no effect since
    // it is already overridden in the content cache.
    ChangeSet changeSet = new ChangeSet();
    changeSet.changedSource(source);
    _context.applyChanges(changeSet);
    expect(_context.sourcesNeedingProcessing, hasLength(0));
  }

  Future test_applyChanges_remove() {
    _context = AnalysisContextFactory.contextWithCore();
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    _sourceFactory = _context.sourceFactory;
    String libAContents = r'''
library libA;
import 'libB.dart';''';
    Source libA = _addSource("/libA.dart", libAContents);
    String libBContents = "library libB;";
    Source libB = _addSource("/libB.dart", libBContents);
    LibraryElement libAElement = _context.computeLibraryElement(libA);
    List<LibraryElement> importedLibraries = libAElement.importedLibraries;
    expect(importedLibraries, hasLength(2));
    _context.computeErrors(libA);
    _context.computeErrors(libB);
    expect(_context.sourcesNeedingProcessing, hasLength(0));
    _context.setContents(libB, null);
    _removeSource(libB);
    List<Source> sources = _context.sourcesNeedingProcessing;
    expect(sources, hasLength(1));
    expect(sources[0], same(libA));
    libAElement = _context.computeLibraryElement(libA);
    importedLibraries = libAElement.importedLibraries;
    expect(importedLibraries, hasLength(1));
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [libA]);
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [libB]);
      listener.assertEvent(changedSources: [libB]);
      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
      listener.assertNoMoreEvents();
    });
  }

  Future test_applyChanges_removeContainer() {
    _context = AnalysisContextFactory.contextWithCore();
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    _sourceFactory = _context.sourceFactory;
    String libAContents = r'''
library libA;
import 'libB.dart';''';
    Source libA = _addSource("/libA.dart", libAContents);
    String libBContents = "library libB;";
    Source libB = _addSource("/libB.dart", libBContents);
    _context.computeLibraryElement(libA);
    _context.computeErrors(libA);
    _context.computeErrors(libB);
    expect(_context.sourcesNeedingProcessing, hasLength(0));
    ChangeSet changeSet = new ChangeSet();
    SourceContainer removedContainer =
        new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB);
    changeSet.removedContainer(removedContainer);
    _context.applyChanges(changeSet);
    List<Source> sources = _context.sourcesNeedingProcessing;
    expect(sources, hasLength(1));
    expect(sources[0], same(libA));
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [libA]);
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [libB]);
      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
      listener.assertNoMoreEvents();
    });
  }

  void test_computeDocumentationComment_block() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    String comment = "/** Comment */";
    Source source = _addSource("/test.dart", """
$comment
class A {}""");
    LibraryElement libraryElement = _context.computeLibraryElement(source);
    expect(libraryElement, isNotNull);
    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
    expect(libraryElement, isNotNull);
    expect(_context.computeDocumentationComment(classElement), comment);
  }

  void test_computeDocumentationComment_none() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.dart", "class A {}");
    LibraryElement libraryElement = _context.computeLibraryElement(source);
    expect(libraryElement, isNotNull);
    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
    expect(libraryElement, isNotNull);
    expect(_context.computeDocumentationComment(classElement), isNull);
  }

  void test_computeDocumentationComment_null() {
    expect(_context.computeDocumentationComment(null), isNull);
  }

  void test_computeDocumentationComment_singleLine_multiple_EOL_n() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    String comment = "/// line 1\n/// line 2\n/// line 3\n";
    Source source = _addSource("/test.dart", "${comment}class A {}");
    LibraryElement libraryElement = _context.computeLibraryElement(source);
    expect(libraryElement, isNotNull);
    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
    expect(libraryElement, isNotNull);
    String actual = _context.computeDocumentationComment(classElement);
    expect(actual, "/// line 1\n/// line 2\n/// line 3");
  }

  void test_computeDocumentationComment_singleLine_multiple_EOL_rn() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    String comment = "/// line 1\r\n/// line 2\r\n/// line 3\r\n";
    Source source = _addSource("/test.dart", "${comment}class A {}");
    LibraryElement libraryElement = _context.computeLibraryElement(source);
    expect(libraryElement, isNotNull);
    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
    expect(libraryElement, isNotNull);
    String actual = _context.computeDocumentationComment(classElement);
    expect(actual, "/// line 1\n/// line 2\n/// line 3");
  }

  void test_computeErrors_dart_none() {
    Source source = _addSource("/lib.dart", "library lib;");
    List<AnalysisError> errors = _context.computeErrors(source);
    expect(errors, hasLength(0));
  }

  void test_computeErrors_dart_part() {
    Source librarySource =
        _addSource("/lib.dart", "library lib; part 'part.dart';");
    Source partSource = _addSource("/part.dart", "part of 'lib';");
    _context.parseCompilationUnit(librarySource);
    List<AnalysisError> errors = _context.computeErrors(partSource);
    expect(errors, isNotNull);
    expect(errors.length > 0, isTrue);
  }

  void test_computeErrors_dart_some() {
    Source source = _addSource("/lib.dart", "library 'lib';");
    List<AnalysisError> errors = _context.computeErrors(source);
    expect(errors, isNotNull);
    expect(errors.length > 0, isTrue);
  }

  void test_computeErrors_html_none() {
    Source source = _addSource("/test.html", "<html></html>");
    List<AnalysisError> errors = _context.computeErrors(source);
    expect(errors, hasLength(0));
  }

  void test_computeExportedLibraries_none() {
    Source source = _addSource("/test.dart", "library test;");
    expect(_context.computeExportedLibraries(source), hasLength(0));
  }

  void test_computeExportedLibraries_some() {
    //    addSource("/lib1.dart", "library lib1;");
    //    addSource("/lib2.dart", "library lib2;");
    Source source = _addSource(
        "/test.dart",
        "library test; export 'lib1.dart'; export 'lib2.dart';");
    expect(_context.computeExportedLibraries(source), hasLength(2));
  }

  void test_computeHtmlElement_nonHtml() {
    Source source = _addSource("/test.dart", "library test;");
    expect(_context.computeHtmlElement(source), isNull);
  }

  void test_computeHtmlElement_valid() {
    Source source = _addSource("/test.html", "<html></html>");
    HtmlElement element = _context.computeHtmlElement(source);
    expect(element, isNotNull);
    expect(_context.computeHtmlElement(source), same(element));
  }

  void test_computeImportedLibraries_none() {
    Source source = _addSource("/test.dart", "library test;");
    expect(_context.computeImportedLibraries(source), hasLength(0));
  }

  void test_computeImportedLibraries_some() {
    //    addSource("/lib1.dart", "library lib1;");
    //    addSource("/lib2.dart", "library lib2;");
    Source source = _addSource(
        "/test.dart",
        "library test; import 'lib1.dart'; import 'lib2.dart';");
    expect(_context.computeImportedLibraries(source), hasLength(2));
  }

  void test_computeKindOf_html() {
    Source source = _addSource("/test.html", "");
    expect(_context.computeKindOf(source), same(SourceKind.HTML));
  }

  void test_computeKindOf_library() {
    Source source = _addSource("/test.dart", "library lib;");
    expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
  }

  void test_computeKindOf_libraryAndPart() {
    Source source = _addSource("/test.dart", "library lib; part of lib;");
    expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
  }

  void test_computeKindOf_part() {
    Source source = _addSource("/test.dart", "part of lib;");
    expect(_context.computeKindOf(source), same(SourceKind.PART));
  }

  void test_computeLibraryElement() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.dart", "library lib;");
    LibraryElement element = _context.computeLibraryElement(source);
    expect(element, isNotNull);
  }

  void test_computeLineInfo_dart() {
    Source source = _addSource("/test.dart", r'''
library lib;

main() {}''');
    LineInfo info = _context.computeLineInfo(source);
    expect(info, isNotNull);
  }

  void test_computeLineInfo_html() {
    Source source = _addSource("/test.html", r'''
<html>
  <body>
    <h1>A</h1>
  </body>
</html>''');
    LineInfo info = _context.computeLineInfo(source);
    expect(info, isNotNull);
  }

  void test_computeResolvableCompilationUnit_dart_exception() {
    TestSource source = _addSourceWithException("/test.dart");
    try {
      _context.computeResolvableCompilationUnit(source);
      fail("Expected AnalysisException");
    } on AnalysisException catch (exception) {
      // Expected
    }
  }

  void test_computeResolvableCompilationUnit_html_exception() {
    Source source = _addSource("/lib.html", "<html></html>");
    try {
      _context.computeResolvableCompilationUnit(source);
      fail("Expected AnalysisException");
    } on AnalysisException catch (exception) {
      // Expected
    }
  }

  void test_computeResolvableCompilationUnit_valid() {
    Source source = _addSource("/lib.dart", "library lib;");
    CompilationUnit parsedUnit = _context.parseCompilationUnit(source);
    expect(parsedUnit, isNotNull);
    CompilationUnit resolvedUnit =
        _context.computeResolvableCompilationUnit(source);
    expect(resolvedUnit, isNotNull);
    expect(resolvedUnit, same(parsedUnit));
  }

  Future test_computeResolvedCompilationUnitAsync() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    // Complete all pending analysis tasks and flush the AST so that it won't
    // be available immediately.
    _performPendingAnalysisTasks();
    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
    dartEntry.flushAstStructures();
    bool completed = false;
    _context.computeResolvedCompilationUnitAsync(
        source,
        source).then((CompilationUnit unit) {
      expect(unit, isNotNull);
      completed = true;
    });
    return pumpEventQueue().then((_) {
      expect(completed, isFalse);
      _performPendingAnalysisTasks();
    }).then((_) => pumpEventQueue()).then((_) {
      expect(completed, isTrue);
    });
  }

  Future test_computeResolvedCompilationUnitAsync_afterDispose() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    // Complete all pending analysis tasks and flush the AST so that it won't
    // be available immediately.
    _performPendingAnalysisTasks();
    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
    dartEntry.flushAstStructures();
    // Dispose of the context.
    _context.dispose();
    // Any attempt to start an asynchronous computation should return a future
    // which completes with error.
    CancelableFuture<CompilationUnit> future =
        _context.computeResolvedCompilationUnitAsync(source, source);
    bool completed = false;
    future.then((CompilationUnit unit) {
      fail('Future should have completed with error');
    }, onError: (error) {
      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
      completed = true;
    });
    return pumpEventQueue().then((_) {
      expect(completed, isTrue);
    });
  }

  Future test_computeResolvedCompilationUnitAsync_cancel() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    // Complete all pending analysis tasks and flush the AST so that it won't
    // be available immediately.
    _performPendingAnalysisTasks();
    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
    dartEntry.flushAstStructures();
    CancelableFuture<CompilationUnit> future =
        _context.computeResolvedCompilationUnitAsync(source, source);
    bool completed = false;
    future.then((CompilationUnit unit) {
      fail('Future should have been canceled');
    }, onError: (error) {
      expect(error, new isInstanceOf<FutureCanceledError>());
      completed = true;
    });
    expect(completed, isFalse);
    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
    future.cancel();
    expect(_context.pendingFutureSources_forTesting, isEmpty);
    return pumpEventQueue().then((_) {
      expect(completed, isTrue);
      expect(_context.pendingFutureSources_forTesting, isEmpty);
    });
  }

  Future test_computeResolvedCompilationUnitAsync_dispose() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    // Complete all pending analysis tasks and flush the AST so that it won't
    // be available immediately.
    _performPendingAnalysisTasks();
    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
    dartEntry.flushAstStructures();
    CancelableFuture<CompilationUnit> future =
        _context.computeResolvedCompilationUnitAsync(source, source);
    bool completed = false;
    future.then((CompilationUnit unit) {
      fail('Future should have completed with error');
    }, onError: (error) {
      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
      completed = true;
    });
    expect(completed, isFalse);
    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
    // Disposing of the context should cause all pending futures to complete
    // with AnalysisNotScheduled, so that no clients are left hanging.
    _context.dispose();
    expect(_context.pendingFutureSources_forTesting, isEmpty);
    return pumpEventQueue().then((_) {
      expect(completed, isTrue);
      expect(_context.pendingFutureSources_forTesting, isEmpty);
    });
  }

  Future test_computeResolvedCompilationUnitAsync_unrelatedLibrary() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source librarySource = _addSource("/lib.dart", "library lib;");
    Source partSource = _addSource("/part.dart", "part of foo;");
    bool completed = false;
    _context.computeResolvedCompilationUnitAsync(
        partSource,
        librarySource).then((_) {
      fail('Expected resolution to fail');
    }, onError: (e) {
      expect(e, new isInstanceOf<AnalysisNotScheduledError>());
      completed = true;
    });
    return pumpEventQueue().then((_) {
      expect(completed, isFalse);
      _performPendingAnalysisTasks();
    }).then((_) => pumpEventQueue()).then((_) {
      expect(completed, isTrue);
    });
  }

  void test_dispose() {
    expect(_context.isDisposed, isFalse);
    _context.dispose();
    expect(_context.isDisposed, isTrue);
  }

  void test_exists_false() {
    TestSource source = new TestSource();
    source.exists2 = false;
    expect(_context.exists(source), isFalse);
  }

  void test_exists_null() {
    expect(_context.exists(null), isFalse);
  }

  void test_exists_overridden() {
    Source source = new TestSource();
    _context.setContents(source, "");
    expect(_context.exists(source), isTrue);
  }

  void test_exists_true() {
    expect(
        _context.exists(new AnalysisContextImplTest_Source_exists_true()),
        isTrue);
  }

  void test_getAnalysisOptions() {
    expect(_context.analysisOptions, isNotNull);
  }

  void test_getContents_fromSource() {
    String content = "library lib;";
    TimestampedData<String> contents =
        _context.getContents(new TestSource('/test.dart', content));
    expect(contents.data.toString(), content);
  }

  void test_getContents_overridden() {
    String content = "library lib;";
    Source source = new TestSource();
    _context.setContents(source, content);
    TimestampedData<String> contents = _context.getContents(source);
    expect(contents.data.toString(), content);
  }

  void test_getContents_unoverridden() {
    String content = "library lib;";
    Source source = new TestSource('/test.dart', content);
    _context.setContents(source, "part of lib;");
    _context.setContents(source, null);
    TimestampedData<String> contents = _context.getContents(source);
    expect(contents.data.toString(), content);
  }

  void test_getDeclaredVariables() {
    _context = AnalysisContextFactory.contextWithCore();
    expect(_context.declaredVariables, isNotNull);
  }

  void test_getElement() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    LibraryElement core =
        _context.computeLibraryElement(_sourceFactory.forUri("dart:core"));
    expect(core, isNotNull);
    ClassElement classObject =
        _findClass(core.definingCompilationUnit, "Object");
    expect(classObject, isNotNull);
    ElementLocation location = classObject.location;
    Element element = _context.getElement(location);
    expect(element, same(classObject));
  }

  void test_getElement_constructor_named() {
    Source source = _addSource("/lib.dart", r'''
class A {
  A.named() {}
}''');
    _analyzeAll_assertFinished();
    LibraryElement library = _context.computeLibraryElement(source);
    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
    ConstructorElement constructor = classA.constructors[0];
    ElementLocation location = constructor.location;
    Element element = _context.getElement(location);
    expect(element, same(constructor));
  }

  void test_getElement_constructor_unnamed() {
    Source source = _addSource("/lib.dart", r'''
class A {
  A() {}
}''');
    _analyzeAll_assertFinished();
    LibraryElement library = _context.computeLibraryElement(source);
    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
    ConstructorElement constructor = classA.constructors[0];
    ElementLocation location = constructor.location;
    Element element = _context.getElement(location);
    expect(element, same(constructor));
  }

  void test_getElement_enum() {
    Source source = _addSource('/test.dart', 'enum MyEnum {A, B, C}');
    _analyzeAll_assertFinished();
    LibraryElement library = _context.computeLibraryElement(source);
    ClassElement myEnum = library.definingCompilationUnit.getEnum('MyEnum');
    ElementLocation location = myEnum.location;
    Element element = _context.getElement(location);
    expect(element, same(myEnum));
  }

  void test_getErrors_dart_none() {
    Source source = _addSource("/lib.dart", "library lib;");
    List<AnalysisError> errors = _context.getErrors(source).errors;
    expect(errors, hasLength(0));
    _context.computeErrors(source);
    errors = _context.getErrors(source).errors;
    expect(errors, hasLength(0));
  }

  void test_getErrors_dart_some() {
    Source source = _addSource("/lib.dart", "library 'lib';");
    List<AnalysisError> errors = _context.getErrors(source).errors;
    expect(errors, hasLength(0));
    _context.computeErrors(source);
    errors = _context.getErrors(source).errors;
    expect(errors, hasLength(1));
  }

  void test_getErrors_html_none() {
    Source source = _addSource("/test.html", "<html></html>");
    List<AnalysisError> errors = _context.getErrors(source).errors;
    expect(errors, hasLength(0));
    _context.computeErrors(source);
    errors = _context.getErrors(source).errors;
    expect(errors, hasLength(0));
  }

  void test_getErrors_html_some() {
    Source source = _addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.dart'/>
</head></html>''');
    List<AnalysisError> errors = _context.getErrors(source).errors;
    expect(errors, hasLength(0));
    _context.computeErrors(source);
    errors = _context.getErrors(source).errors;
    expect(errors, hasLength(1));
  }

  void test_getHtmlElement_dart() {
    Source source = _addSource("/test.dart", "");
    expect(_context.getHtmlElement(source), isNull);
    expect(_context.computeHtmlElement(source), isNull);
    expect(_context.getHtmlElement(source), isNull);
  }

  void test_getHtmlElement_html() {
    Source source = _addSource("/test.html", "<html></html>");
    HtmlElement element = _context.getHtmlElement(source);
    expect(element, isNull);
    _context.computeHtmlElement(source);
    element = _context.getHtmlElement(source);
    expect(element, isNotNull);
  }

  void test_getHtmlFilesReferencing_html() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source htmlSource = _addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.dart'/>
<script type='application/dart' src='test.js'/>
</head></html>''');
    Source librarySource = _addSource("/test.dart", "library lib;");
    Source secondHtmlSource = _addSource("/test.html", "<html></html>");
    _context.computeLibraryElement(librarySource);
    List<Source> result = _context.getHtmlFilesReferencing(secondHtmlSource);
    expect(result, hasLength(0));
    _context.parseHtmlUnit(htmlSource);
    result = _context.getHtmlFilesReferencing(secondHtmlSource);
    expect(result, hasLength(0));
  }

  void test_getHtmlFilesReferencing_library() {
    Source htmlSource = _addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.dart'/>
<script type='application/dart' src='test.js'/>
</head></html>''');
    Source librarySource = _addSource("/test.dart", "library lib;");
    List<Source> result = _context.getHtmlFilesReferencing(librarySource);
    expect(result, hasLength(0));
    _context.parseHtmlUnit(htmlSource);
    result = _context.getHtmlFilesReferencing(librarySource);
    expect(result, hasLength(1));
    expect(result[0], htmlSource);
  }

  void test_getHtmlFilesReferencing_part() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source htmlSource = _addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.dart'/>
<script type='application/dart' src='test.js'/>
</head></html>''');
    Source librarySource =
        _addSource("/test.dart", "library lib; part 'part.dart';");
    Source partSource = _addSource("/part.dart", "part of lib;");
    _context.computeLibraryElement(librarySource);
    List<Source> result = _context.getHtmlFilesReferencing(partSource);
    expect(result, hasLength(0));
    _context.parseHtmlUnit(htmlSource);
    result = _context.getHtmlFilesReferencing(partSource);
    expect(result, hasLength(1));
    expect(result[0], htmlSource);
  }

  void test_getHtmlSources() {
    List<Source> sources = _context.htmlSources;
    expect(sources, hasLength(0));
    Source source = _addSource("/test.html", "");
    _context.computeKindOf(source);
    sources = _context.htmlSources;
    expect(sources, hasLength(1));
    expect(sources[0], source);
  }

  void test_getKindOf_html() {
    Source source = _addSource("/test.html", "");
    expect(_context.getKindOf(source), same(SourceKind.HTML));
  }

  void test_getKindOf_library() {
    Source source = _addSource("/test.dart", "library lib;");
    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
    _context.computeKindOf(source);
    expect(_context.getKindOf(source), same(SourceKind.LIBRARY));
  }

  void test_getKindOf_part() {
    Source source = _addSource("/test.dart", "part of lib;");
    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
    _context.computeKindOf(source);
    expect(_context.getKindOf(source), same(SourceKind.PART));
  }

  void test_getKindOf_unknown() {
    Source source = _addSource("/test.css", "");
    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
  }

  void test_getLaunchableClientLibrarySources() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    List<Source> sources = _context.launchableClientLibrarySources;
    expect(sources, hasLength(0));
    Source source = _addSource("/test.dart", r'''
import 'dart:html';
main() {}''');
    _context.computeLibraryElement(source);
    sources = _context.launchableClientLibrarySources;
    expect(sources, hasLength(1));
  }

  void test_getLaunchableServerLibrarySources() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    List<Source> sources = _context.launchableServerLibrarySources;
    expect(sources, hasLength(0));
    Source source = _addSource("/test.dart", "main() {}");
    _context.computeLibraryElement(source);
    sources = _context.launchableServerLibrarySources;
    expect(sources, hasLength(1));
  }

  void test_getLibrariesContaining() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source librarySource = _addSource("/lib.dart", r'''
library lib;
part 'part.dart';''');
    Source partSource = _addSource("/part.dart", "part of lib;");
    _context.computeLibraryElement(librarySource);
    List<Source> result = _context.getLibrariesContaining(librarySource);
    expect(result, hasLength(1));
    expect(result[0], librarySource);
    result = _context.getLibrariesContaining(partSource);
    expect(result, hasLength(1));
    expect(result[0], librarySource);
  }

  void test_getLibrariesDependingOn() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source libASource = _addSource("/libA.dart", "library libA;");
    _addSource("/libB.dart", "library libB;");
    Source lib1Source = _addSource("/lib1.dart", r'''
library lib1;
import 'libA.dart';
export 'libB.dart';''');
    Source lib2Source = _addSource("/lib2.dart", r'''
library lib2;
import 'libB.dart';
export 'libA.dart';''');
    _context.computeLibraryElement(lib1Source);
    _context.computeLibraryElement(lib2Source);
    List<Source> result = _context.getLibrariesDependingOn(libASource);
    expect(result, unorderedEquals([lib1Source, lib2Source]));
  }

  void test_getLibrariesReferencedFromHtml() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source htmlSource = _addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.dart'/>
<script type='application/dart' src='test.js'/>
</head></html>''');
    Source librarySource = _addSource("/test.dart", "library lib;");
    _context.computeLibraryElement(librarySource);
    _context.parseHtmlUnit(htmlSource);
    List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
    expect(result, hasLength(1));
    expect(result[0], librarySource);
  }

  void test_getLibrariesReferencedFromHtml_no() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source htmlSource = _addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.js'/>
</head></html>''');
    _addSource("/test.dart", "library lib;");
    _context.parseHtmlUnit(htmlSource);
    List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
    expect(result, hasLength(0));
  }

  void test_getLibraryElement() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.dart", "library lib;");
    LibraryElement element = _context.getLibraryElement(source);
    expect(element, isNull);
    _context.computeLibraryElement(source);
    element = _context.getLibraryElement(source);
    expect(element, isNotNull);
  }

  void test_getLibrarySources() {
    List<Source> sources = _context.librarySources;
    int originalLength = sources.length;
    Source source = _addSource("/test.dart", "library lib;");
    _context.computeKindOf(source);
    sources = _context.librarySources;
    expect(sources, hasLength(originalLength + 1));
    for (Source returnedSource in sources) {
      if (returnedSource == source) {
        return;
      }
    }
    fail("The added source was not in the list of library sources");
  }

  void test_getLineInfo() {
    Source source = _addSource("/test.dart", r'''
library lib;

main() {}''');
    LineInfo info = _context.getLineInfo(source);
    expect(info, isNull);
    _context.parseCompilationUnit(source);
    info = _context.getLineInfo(source);
    expect(info, isNotNull);
  }

  void test_getModificationStamp_fromSource() {
    int stamp = 42;
    expect(
        _context.getModificationStamp(
            new AnalysisContextImplTest_Source_getModificationStamp_fromSource(stamp)),
        stamp);
  }

  void test_getModificationStamp_overridden() {
    int stamp = 42;
    Source source =
        new AnalysisContextImplTest_Source_getModificationStamp_overridden(stamp);
    _context.setContents(source, "");
    expect(stamp != _context.getModificationStamp(source), isTrue);
  }

  void test_getPublicNamespace_element() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.dart", "class A {}");
    LibraryElement library = _context.computeLibraryElement(source);
    Namespace namespace = _context.getPublicNamespace(library);
    expect(namespace, isNotNull);
    EngineTestCase.assertInstanceOf(
        (obj) => obj is ClassElement,
        ClassElement,
        namespace.get("A"));
  }

  void test_getRefactoringUnsafeSources() {
    // not sources initially
    List<Source> sources = _context.refactoringUnsafeSources;
    expect(sources, hasLength(0));
    // add new source, unresolved
    Source source = _addSource("/test.dart", "library lib;");
    sources = _context.refactoringUnsafeSources;
    expect(sources, hasLength(1));
    expect(sources[0], source);
    // resolve source
    _context.computeLibraryElement(source);
    sources = _context.refactoringUnsafeSources;
    expect(sources, hasLength(0));
  }

  void test_getResolvedCompilationUnit_library() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library libb;");
    LibraryElement library = _context.computeLibraryElement(source);
    expect(_context.getResolvedCompilationUnit(source, library), isNotNull);
    _context.setContents(source, "library lib;");
    expect(_context.getResolvedCompilationUnit(source, library), isNull);
  }

  void test_getResolvedCompilationUnit_library_null() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    expect(_context.getResolvedCompilationUnit(source, null), isNull);
  }

  void test_getResolvedCompilationUnit_source_dart() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
    _context.resolveCompilationUnit2(source, source);
    expect(_context.getResolvedCompilationUnit2(source, source), isNotNull);
  }

  void test_getResolvedCompilationUnit_source_html() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.html", "<html></html>");
    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
    expect(_context.resolveCompilationUnit2(source, source), isNull);
    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
  }

  void test_getResolvedHtmlUnit() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.html", "<html></html>");
    expect(_context.getResolvedHtmlUnit(source), isNull);
    _context.resolveHtmlUnit(source);
    expect(_context.getResolvedHtmlUnit(source), isNotNull);
  }

  void test_getSourceFactory() {
    expect(_context.sourceFactory, same(_sourceFactory));
  }

  void test_getStatistics() {
    AnalysisContextStatistics statistics = _context.statistics;
    expect(statistics, isNotNull);
    // The following lines are fragile.
    // The values depend on the number of libraries in the SDK.
//    assertLength(0, statistics.getCacheRows());
//    assertLength(0, statistics.getExceptions());
//    assertLength(0, statistics.getSources());
  }

  void test_isClientLibrary_dart() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.dart", r'''
import 'dart:html';

main() {}''');
    expect(_context.isClientLibrary(source), isFalse);
    expect(_context.isServerLibrary(source), isFalse);
    _context.computeLibraryElement(source);
    expect(_context.isClientLibrary(source), isTrue);
    expect(_context.isServerLibrary(source), isFalse);
  }

  void test_isClientLibrary_html() {
    Source source = _addSource("/test.html", "<html></html>");
    expect(_context.isClientLibrary(source), isFalse);
  }

  void test_isServerLibrary_dart() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/test.dart", r'''
library lib;

main() {}''');
    expect(_context.isClientLibrary(source), isFalse);
    expect(_context.isServerLibrary(source), isFalse);
    _context.computeLibraryElement(source);
    expect(_context.isClientLibrary(source), isFalse);
    expect(_context.isServerLibrary(source), isTrue);
  }

  void test_isServerLibrary_html() {
    Source source = _addSource("/test.html", "<html></html>");
    expect(_context.isServerLibrary(source), isFalse);
  }

  void test_parseCompilationUnit_errors() {
    Source source = _addSource("/lib.dart", "library {");
    CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
    expect(compilationUnit, isNotNull);
    List<AnalysisError> errors = _context.getErrors(source).errors;
    expect(errors, isNotNull);
    expect(errors.length > 0, isTrue);
  }

  void test_parseCompilationUnit_exception() {
    Source source = _addSourceWithException("/test.dart");
    try {
      _context.parseCompilationUnit(source);
      fail("Expected AnalysisException");
    } on AnalysisException catch (exception) {
      // Expected
    }
  }

  void test_parseCompilationUnit_html() {
    Source source = _addSource("/test.html", "<html></html>");
    expect(_context.parseCompilationUnit(source), isNull);
  }

  void test_parseCompilationUnit_noErrors() {
    Source source = _addSource("/lib.dart", "library lib;");
    CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
    expect(compilationUnit, isNotNull);
    expect(_context.getErrors(source).errors, hasLength(0));
  }

  void test_parseCompilationUnit_nonExistentSource() {
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    try {
      _context.parseCompilationUnit(source);
      fail("Expected AnalysisException because file does not exist");
    } on AnalysisException catch (exception) {
      // Expected result
    }
  }

  void test_parseHtmlUnit_noErrors() {
    Source source = _addSource("/lib.html", "<html></html>");
    ht.HtmlUnit unit = _context.parseHtmlUnit(source);
    expect(unit, isNotNull);
  }

  void test_parseHtmlUnit_resolveDirectives() {
    Source libSource = _addSource("/lib.dart", r'''
library lib;
class ClassA {}''');
    Source source = _addSource("/lib.html", r'''
<html>
<head>
  <script type='application/dart'>
    import 'lib.dart';
    ClassA v = null;
  </script>
</head>
<body>
</body>
</html>''');
    ht.HtmlUnit unit = _context.parseHtmlUnit(source);
    // import directive should be resolved
    ht.XmlTagNode htmlNode = unit.tagNodes[0];
    ht.XmlTagNode headNode = htmlNode.tagNodes[0];
    ht.HtmlScriptTagNode scriptNode = headNode.tagNodes[0];
    CompilationUnit script = scriptNode.script;
    ImportDirective importNode = script.directives[0] as ImportDirective;
    expect(importNode.uriContent, isNotNull);
    expect(importNode.source, libSource);
  }

  void test_performAnalysisTask_addPart() {
    Source libSource = _addSource("/lib.dart", r'''
library lib;
part 'part.dart';''');
    // run all tasks without part
    _analyzeAll_assertFinished();
    // add part and run all tasks
    Source partSource = _addSource("/part.dart", r'''
part of lib;
''');
    _analyzeAll_assertFinished();
    // "libSource" should be here
    List<Source> librariesWithPart =
        _context.getLibrariesContaining(partSource);
    expect(librariesWithPart, unorderedEquals([libSource]));
  }

  void test_performAnalysisTask_changeLibraryContents() {
    Source libSource =
        _addSource("/test.dart", "library lib; part 'test-part.dart';");
    Source partSource = _addSource("/test-part.dart", "part of lib;");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 1");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 1");
    // update and analyze #1
    _context.setContents(libSource, "library lib;");
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNull,
        reason: "library changed 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part changed 2");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part resolved 2");
    // update and analyze #2
    _context.setContents(libSource, "library lib; part 'test-part.dart';");
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNull,
        reason: "library changed 3");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part changed 3");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 3");
  }

  void test_performAnalysisTask_changeLibraryThenPartContents() {
    Source libSource =
        _addSource("/test.dart", "library lib; part 'test-part.dart';");
    Source partSource = _addSource("/test-part.dart", "part of lib;");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 1");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 1");
    // update and analyze #1
    _context.setContents(libSource, "library lib;");
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNull,
        reason: "library changed 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part changed 2");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part resolved 2");
    // update and analyze #2
    _context.setContents(partSource, "part of lib; // 1");
    // Assert that changing the part's content does not effect the library
    // now that it is no longer part of that library
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library changed 3");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part changed 3");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 3");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part resolved 3");
  }

  void test_performAnalysisTask_changePartContents_makeItAPart() {
    Source libSource = _addSource("/lib.dart", r'''
library lib;
part 'part.dart';
void f(x) {}''');
    Source partSource = _addSource("/part.dart", "void g() { f(null); }");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 1");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 1");
    // update and analyze
    _context.setContents(partSource, r'''
part of lib;
void g() { f(null); }''');
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNull,
        reason: "library changed 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part changed 2");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 2");
    expect(_context.getErrors(libSource).errors, hasLength(0));
    expect(_context.getErrors(partSource).errors, hasLength(0));
  }

  /**
   * https://code.google.com/p/dart/issues/detail?id=12424
   */
  void test_performAnalysisTask_changePartContents_makeItNotPart() {
    Source libSource = _addSource("/lib.dart", r'''
library lib;
part 'part.dart';
void f(x) {}''');
    Source partSource = _addSource("/part.dart", r'''
part of lib;
void g() { f(null); }''');
    _analyzeAll_assertFinished();
    expect(_context.getErrors(libSource).errors, hasLength(0));
    expect(_context.getErrors(partSource).errors, hasLength(0));
    // Remove 'part' directive, which should make "f(null)" an error.
    _context.setContents(partSource, r'''
//part of lib;
void g() { f(null); }''');
    _analyzeAll_assertFinished();
    expect(_context.getErrors(libSource).errors.length != 0, isTrue);
  }

  void test_performAnalysisTask_changePartContents_noSemanticChanges() {
    Source libSource =
        _addSource("/test.dart", "library lib; part 'test-part.dart';");
    Source partSource = _addSource("/test-part.dart", "part of lib;");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 1");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 1");
    // update and analyze #1
    _context.setContents(partSource, "part of lib; // 1");
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNull,
        reason: "library changed 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part changed 2");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 2");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 2");
    // update and analyze #2
    _context.setContents(partSource, "part of lib; // 12");
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNull,
        reason: "library changed 3");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNull,
        reason: "part changed 3");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libSource, libSource),
        isNotNull,
        reason: "library resolved 3");
    expect(
        _context.getResolvedCompilationUnit2(partSource, libSource),
        isNotNull,
        reason: "part resolved 3");
  }

  void test_performAnalysisTask_importedLibraryAdd() {
    Source libASource =
        _addSource("/libA.dart", "library libA; import 'libB.dart';");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libASource, libASource),
        isNotNull,
        reason: "libA resolved 1");
    expect(
        _hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
        isTrue,
        reason: "libA has an error");
    // add libB.dart and analyze
    Source libBSource = _addSource("/libB.dart", "library libB;");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libASource, libASource),
        isNotNull,
        reason: "libA resolved 2");
    expect(
        _context.getResolvedCompilationUnit2(libBSource, libBSource),
        isNotNull,
        reason: "libB resolved 2");
    expect(
        !_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
        isTrue,
        reason: "libA doesn't have errors");
  }

  void test_performAnalysisTask_importedLibraryAdd_html() {
    Source htmlSource = _addSource("/page.html", r'''
<html><body><script type="application/dart">
  import '/libB.dart';
  main() {print('hello dart');}
</script></body></html>''');
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedHtmlUnit(htmlSource),
        isNotNull,
        reason: "htmlUnit resolved 1");
    expect(
        _hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
        isTrue,
        reason: "htmlSource has an error");
    // add libB.dart and analyze
    Source libBSource = _addSource("/libB.dart", "library libB;");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedHtmlUnit(htmlSource),
        isNotNull,
        reason: "htmlUnit resolved 1");
    expect(
        _context.getResolvedCompilationUnit2(libBSource, libBSource),
        isNotNull,
        reason: "libB resolved 2");
    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
    // TODO (danrubel) commented out to fix red bots
//    expect(
//        !_hasAnalysisErrorWithErrorSeverity(errors),
//        isTrue,
//        reason: "htmlSource doesn't have errors");
  }

  void test_performAnalysisTask_importedLibraryDelete() {
    Source libASource =
        _addSource("/libA.dart", "library libA; import 'libB.dart';");
    Source libBSource = _addSource("/libB.dart", "library libB;");
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libASource, libASource),
        isNotNull,
        reason: "libA resolved 1");
    expect(
        _context.getResolvedCompilationUnit2(libBSource, libBSource),
        isNotNull,
        reason: "libB resolved 1");
    expect(
        !_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
        isTrue,
        reason: "libA doesn't have errors");
    // remove libB.dart content and analyze
    _context.setContents(libBSource, null);
    _analyzeAll_assertFinished();
    expect(
        _context.getResolvedCompilationUnit2(libASource, libASource),
        isNotNull,
        reason: "libA resolved 2");
    expect(
        _hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
        isTrue,
        reason: "libA has an error");
  }

  void test_performAnalysisTask_IOException() {
    TestSource source = _addSourceWithException2("/test.dart", "library test;");
    int oldTimestamp = _context.getModificationStamp(source);
    source.generateExceptionOnRead = false;
    _analyzeAll_assertFinished();
    expect(source.readCount, 1);
    source.generateExceptionOnRead = true;
    do {
      _changeSource(source, "");
      // Ensure that the timestamp differs,
      // so that analysis engine notices the change
    } while (oldTimestamp == _context.getModificationStamp(source));
    _analyzeAll_assertFinished();
    expect(source.readCount, 2);
  }

  void test_performAnalysisTask_missingPart() {
    Source source =
        _addSource("/test.dart", "library lib; part 'no-such-file.dart';");
    _analyzeAll_assertFinished();
    expect(
        _context.getLibraryElement(source),
        isNotNull,
        reason: "performAnalysisTask failed to compute an element model");
  }

  void test_performAnalysisTask_modifiedAfterParse() {
    // TODO(scheglov) no threads in Dart
//    Source source = _addSource("/test.dart", "library lib;");
//    int initialTime = _context.getModificationStamp(source);
//    List<Source> sources = new List<Source>();
//    sources.add(source);
//    _context.analysisPriorityOrder = sources;
//    _context.parseCompilationUnit(source);
//    while (initialTime == JavaSystem.currentTimeMillis()) {
//      Thread.sleep(1);
//      // Force the modification time to be different.
//    }
//    _context.setContents(source, "library test;");
//    JUnitTestCase.assertTrue(initialTime != _context.getModificationStamp(source));
//    _analyzeAll_assertFinished();
//    JUnitTestCase.assertNotNullMsg("performAnalysisTask failed to compute an element model", _context.getLibraryElement(source));
  }

  void test_resolveCompilationUnit_import_relative() {
    _context = AnalysisContextFactory.contextWithCore();
    Source sourceA =
        _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
    _addSource("/libB.dart", "library libB; class B{}");
    CompilationUnit compilationUnit =
        _context.resolveCompilationUnit2(sourceA, sourceA);
    LibraryElement library = compilationUnit.element.library;
    List<LibraryElement> importedLibraries = library.importedLibraries;
    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
    List<LibraryElement> visibleLibraries = library.visibleLibraries;
    assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
  }

  void test_resolveCompilationUnit_import_relative_cyclic() {
    _context = AnalysisContextFactory.contextWithCore();
    Source sourceA =
        _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
    _addSource("/libB.dart", "library libB; import 'libA.dart'; class B{}");
    CompilationUnit compilationUnit =
        _context.resolveCompilationUnit2(sourceA, sourceA);
    LibraryElement library = compilationUnit.element.library;
    List<LibraryElement> importedLibraries = library.importedLibraries;
    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
    List<LibraryElement> visibleLibraries = library.visibleLibraries;
    assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
  }

  void test_resolveCompilationUnit_library() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    LibraryElement library = _context.computeLibraryElement(source);
    CompilationUnit compilationUnit =
        _context.resolveCompilationUnit(source, library);
    expect(compilationUnit, isNotNull);
    expect(compilationUnit.element, isNotNull);
  }

  void test_resolveCompilationUnit_source() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    CompilationUnit compilationUnit =
        _context.resolveCompilationUnit2(source, source);
    expect(compilationUnit, isNotNull);
  }

  void test_resolveCompilationUnit_sourceChangeDuringResolution() {
    _context = new _AnalysisContext_sourceChangeDuringResolution();
    AnalysisContextFactory.initContextWithCore(_context);
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    CompilationUnit compilationUnit =
        _context.resolveCompilationUnit2(source, source);
    expect(compilationUnit, isNotNull);
    expect(_context.getLineInfo(source), isNotNull);
  }

  void test_resolveHtmlUnit() {
    Source source = _addSource("/lib.html", "<html></html>");
    ht.HtmlUnit unit = _context.resolveHtmlUnit(source);
    expect(unit, isNotNull);
  }

  void test_setAnalysisOptions() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    options.cacheSize = 42;
    options.dart2jsHint = false;
    options.hint = false;
    _context.analysisOptions = options;
    AnalysisOptions result = _context.analysisOptions;
    expect(result.cacheSize, options.cacheSize);
    expect(result.dart2jsHint, options.dart2jsHint);
    expect(result.hint, options.hint);
  }

  void test_setAnalysisOptions_reduceAnalysisPriorityOrder() {
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.con1(_context.analysisOptions);
    List<Source> sources = new List<Source>();
    for (int index = 0; index < options.cacheSize; index++) {
      sources.add(_addSource("/lib.dart$index", ""));
    }
    _context.analysisPriorityOrder = sources;
    int oldPriorityOrderSize = _getPriorityOrder(_context).length;
    options.cacheSize = options.cacheSize - 10;
    _context.analysisOptions = options;
    expect(oldPriorityOrderSize > _getPriorityOrder(_context).length, isTrue);
  }

  void test_setAnalysisPriorityOrder_empty() {
    _context.analysisPriorityOrder = new List<Source>();
  }

  void test_setAnalysisPriorityOrder_lessThanCacheSize() {
    AnalysisOptions options = _context.analysisOptions;
    List<Source> sources = new List<Source>();
    for (int index = 0; index < options.cacheSize; index++) {
      sources.add(_addSource("/lib.dart$index", ""));
    }
    _context.analysisPriorityOrder = sources;
    expect(options.cacheSize > _getPriorityOrder(_context).length, isTrue);
  }

  void test_setAnalysisPriorityOrder_nonEmpty() {
    List<Source> sources = new List<Source>();
    sources.add(_addSource("/lib.dart", "library lib;"));
    _context.analysisPriorityOrder = sources;
  }

  Future test_setChangedContents_libraryWithPart() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    options.incremental = true;
    _context = AnalysisContextFactory.contextWithCoreAndOptions(options);
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    _sourceFactory = _context.sourceFactory;
    String oldCode = r'''
library lib;
part 'part.dart';
int a = 0;''';
    Source librarySource = _addSource("/lib.dart", oldCode);
    String partContents = r'''
part of lib;
int b = a;''';
    Source partSource = _addSource("/part.dart", partContents);
    LibraryElement element = _context.computeLibraryElement(librarySource);
    CompilationUnit unit =
        _context.getResolvedCompilationUnit(librarySource, element);
    expect(unit, isNotNull);
    int offset = oldCode.indexOf("int a") + 4;
    String newCode = r'''
library lib;
part 'part.dart';
int ya = 0;''';
    expect(_getIncrementalAnalysisCache(_context), isNull);
    _context.setChangedContents(librarySource, newCode, offset, 0, 1);
    expect(_context.getContents(librarySource).data, newCode);
    IncrementalAnalysisCache incrementalCache =
        _getIncrementalAnalysisCache(_context);
    expect(incrementalCache.librarySource, librarySource);
    expect(incrementalCache.resolvedUnit, same(unit));
    expect(
        _context.getResolvedCompilationUnit2(partSource, librarySource),
        isNull);
    expect(incrementalCache.newContents, newCode);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [partSource]);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertNoMoreEvents();
    });
  }

  void test_setChangedContents_notResolved() {
    _context = AnalysisContextFactory.contextWithCore();
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.con1(_context.analysisOptions);
    options.incremental = true;
    _context.analysisOptions = options;
    _sourceFactory = _context.sourceFactory;
    String oldCode = r'''
library lib;
int a = 0;''';
    Source librarySource = _addSource("/lib.dart", oldCode);
    int offset = oldCode.indexOf("int a") + 4;
    String newCode = r'''
library lib;
int ya = 0;''';
    _context.setChangedContents(librarySource, newCode, offset, 0, 1);
    expect(_context.getContents(librarySource).data, newCode);
    expect(_getIncrementalAnalysisCache(_context), isNull);
  }

  Future test_setContents_libraryWithPart() {
    _context = AnalysisContextFactory.contextWithCore();
    SourcesChangedListener listener = new SourcesChangedListener();
    _context.onSourcesChanged.listen(listener.onData);
    _sourceFactory = _context.sourceFactory;
    String libraryContents1 = r'''
library lib;
part 'part.dart';
int a = 0;''';
    Source librarySource = _addSource("/lib.dart", libraryContents1);
    String partContents1 = r'''
part of lib;
int b = a;''';
    Source partSource = _addSource("/part.dart", partContents1);
    _context.computeLibraryElement(librarySource);
    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
        librarySource,
        librarySource,
        null,
        null,
        null,
        0,
        0,
        0);
    _setIncrementalAnalysisCache(_context, incrementalCache);
    expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
    String libraryContents2 = r'''
library lib;
part 'part.dart';
int aa = 0;''';
    _context.setContents(librarySource, libraryContents2);
    expect(
        _context.getResolvedCompilationUnit2(partSource, librarySource),
        isNull);
    expect(_getIncrementalAnalysisCache(_context), isNull);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [partSource]);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertNoMoreEvents();
    });
  }

  void test_setContents_null() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source librarySource = _addSource("/lib.dart", r'''
library lib;
int a = 0;''');
    _context.computeLibraryElement(librarySource);
    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
        librarySource,
        librarySource,
        null,
        null,
        null,
        0,
        0,
        0);
    _setIncrementalAnalysisCache(_context, incrementalCache);
    expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
    _context.setContents(librarySource, null);
    expect(
        _context.getResolvedCompilationUnit2(librarySource, librarySource),
        isNull);
    expect(_getIncrementalAnalysisCache(_context), isNull);
  }

  void test_setContents_unchanged_consistentModificationTime() {
    String contents = "// foo";
    Source source = _addSource("/test.dart", contents);
    // do all, no tasks
    _analyzeAll_assertFinished();
    {
      AnalysisResult result = _context.performAnalysisTask();
      expect(result.changeNotices, isNull);
    }
    // set the same contents, still no tasks
    _context.setContents(source, contents);
    {
      AnalysisResult result = _context.performAnalysisTask();
      expect(result.changeNotices, isNull);
    }
  }

  void test_setSourceFactory() {
    expect(_context.sourceFactory, _sourceFactory);
    SourceFactory factory = new SourceFactory([]);
    _context.sourceFactory = factory;
    expect(_context.sourceFactory, factory);
  }

  void test_unreadableSource() {
    _context = AnalysisContextFactory.contextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source test1 = _addSource("/test1.dart", r'''
import 'test2.dart';
library test1;''');
    Source test2 = _addSource("/test2.dart", r'''
import 'test1.dart';
import 'test3.dart';
library test2;''');
    Source test3 = _addSourceWithException("/test3.dart");
    _analyzeAll_assertFinished();
    // test1 and test2 should have been successfully analyzed
    // despite the fact that test3 couldn't be read.
    expect(_context.computeLibraryElement(test1), isNotNull);
    expect(_context.computeLibraryElement(test2), isNotNull);
    expect(_context.computeLibraryElement(test3), isNull);
  }

  void test_updateAnalysis() {
    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    AnalysisDelta delta = new AnalysisDelta();
    delta.setAnalysisLevel(source, AnalysisLevel.ALL);
    _context.applyAnalysisDelta(delta);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    delta = new AnalysisDelta();
    delta.setAnalysisLevel(source, AnalysisLevel.NONE);
    _context.applyAnalysisDelta(delta);
    expect(_context.sourcesNeedingProcessing.contains(source), isFalse);
  }

  void xtest_performAnalysisTask_stress() {
    int maxCacheSize = 4;
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.con1(_context.analysisOptions);
    options.cacheSize = maxCacheSize;
    _context.analysisOptions = options;
    int sourceCount = maxCacheSize + 2;
    List<Source> sources = new List<Source>();
    ChangeSet changeSet = new ChangeSet();
    for (int i = 0; i < sourceCount; i++) {
      Source source = _addSource("/lib$i.dart", "library lib$i;");
      sources.add(source);
      changeSet.addedSource(source);
    }
    _context.applyChanges(changeSet);
    _context.analysisPriorityOrder = sources;
    for (int i = 0; i < 1000; i++) {
      List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
      if (notice == null) {
        //System.out.println("test_performAnalysisTask_stress: " + i);
        break;
      }
    }
    List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
    if (notice != null) {
      fail(
          "performAnalysisTask failed to terminate after analyzing all sources");
    }
  }

  Source _addSource(String fileName, String contents) {
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile(fileName));
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(source);
    _context.applyChanges(changeSet);
    _context.setContents(source, contents);
    return source;
  }

  TestSource _addSourceWithException(String fileName) {
    return _addSourceWithException2(fileName, "");
  }

  TestSource _addSourceWithException2(String fileName, String contents) {
    TestSource source = new TestSource(fileName, contents);
    source.generateExceptionOnRead = true;
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(source);
    _context.applyChanges(changeSet);
    return source;
  }

  /**
   * Perform analysis tasks up to 512 times and asserts that that was enough.
   */
  void _analyzeAll_assertFinished() {
    _analyzeAll_assertFinished2(512);
  }

  /**
   * Perform analysis tasks up to the given number of times and asserts that that was enough.
   *
   * @param maxIterations the maximum number of tasks to perform
   */
  void _analyzeAll_assertFinished2(int maxIterations) {
    for (int i = 0; i < maxIterations; i++) {
      List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
      if (notice == null) {
        return;
      }
    }
    fail("performAnalysisTask failed to terminate after analyzing all sources");
  }

  void _changeSource(TestSource source, String contents) {
    source.setContents(contents);
    ChangeSet changeSet = new ChangeSet();
    changeSet.changedSource(source);
    _context.applyChanges(changeSet);
  }

  /**
   * Search the given compilation unit for a class with the given name. Return the class with the
   * given name, or `null` if the class cannot be found.
   *
   * @param unit the compilation unit being searched
   * @param className the name of the class being searched for
   * @return the class with the given name
   */
  ClassElement _findClass(CompilationUnitElement unit, String className) {
    for (ClassElement classElement in unit.types) {
      if (classElement.displayName == className) {
        return classElement;
      }
    }
    return null;
  }

  IncrementalAnalysisCache
      _getIncrementalAnalysisCache(AnalysisContextImpl context2) {
    return context2.test_incrementalAnalysisCache;
  }

  List<Source> _getPriorityOrder(AnalysisContextImpl context2) {
    return context2.test_priorityOrder;
  }

  void _performPendingAnalysisTasks([int maxTasks = 20]) {
    for (int i = 0; _context.performAnalysisTask().hasMoreWork; i++) {
      if (i > maxTasks) {
        fail('Analysis did not terminate.');
      }
    }
  }

  void _removeSource(Source source) {
    ChangeSet changeSet = new ChangeSet();
    changeSet.removedSource(source);
    _context.applyChanges(changeSet);
  }

  void _setIncrementalAnalysisCache(AnalysisContextImpl context,
      IncrementalAnalysisCache incrementalCache) {
    context.test_incrementalAnalysisCache = incrementalCache;
  }

  /**
   * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in
   * the given [AnalysisErrorInfo].
   */
  static bool _hasAnalysisErrorWithErrorSeverity(AnalysisErrorInfo errorInfo) {
    List<AnalysisError> errors = errorInfo.errors;
    for (AnalysisError analysisError in errors) {
      if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) {
        return true;
      }
    }
    return false;
  }
}


class AnalysisContextImplTest_Source_exists_true extends TestSource {
  @override
  bool exists() => true;
}


class AnalysisContextImplTest_Source_getModificationStamp_fromSource extends
    TestSource {
  int stamp;
  AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
  @override
  int get modificationStamp => stamp;
}


class AnalysisContextImplTest_Source_getModificationStamp_overridden extends
    TestSource {
  int stamp;
  AnalysisContextImplTest_Source_getModificationStamp_overridden(this.stamp);
  @override
  int get modificationStamp => stamp;
}


@reflectiveTest
class AnalysisOptionsImplTest extends EngineTestCase {
  void test_AnalysisOptionsImpl_copy() {
    bool booleanValue = true;
    for (int i = 0; i < 2; i++, booleanValue = !booleanValue) {
      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
      options.analyzeFunctionBodies = booleanValue;
      options.cacheSize = i;
      options.dart2jsHint = booleanValue;
      options.generateSdkErrors = booleanValue;
      options.hint = booleanValue;
      options.incremental = booleanValue;
      options.preserveComments = booleanValue;
      AnalysisOptionsImpl copy = new AnalysisOptionsImpl.con1(options);
      expect(copy.analyzeFunctionBodies, options.analyzeFunctionBodies);
      expect(copy.cacheSize, options.cacheSize);
      expect(copy.dart2jsHint, options.dart2jsHint);
      expect(copy.generateSdkErrors, options.generateSdkErrors);
      expect(copy.hint, options.hint);
      expect(copy.incremental, options.incremental);
      expect(copy.preserveComments, options.preserveComments);
    }
  }

  void test_getAnalyzeFunctionBodies() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.analyzeFunctionBodies;
    options.analyzeFunctionBodies = value;
    expect(options.analyzeFunctionBodies, value);
  }

  void test_getCacheSize() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    expect(options.cacheSize, AnalysisOptionsImpl.DEFAULT_CACHE_SIZE);
    int value = options.cacheSize + 1;
    options.cacheSize = value;
    expect(options.cacheSize, value);
  }

  void test_getDart2jsHint() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.dart2jsHint;
    options.dart2jsHint = value;
    expect(options.dart2jsHint, value);
  }

  void test_getGenerateSdkErrors() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.generateSdkErrors;
    options.generateSdkErrors = value;
    expect(options.generateSdkErrors, value);
  }

  void test_getHint() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.hint;
    options.hint = value;
    expect(options.hint, value);
  }

  void test_getIncremental() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.incremental;
    options.incremental = value;
    expect(options.incremental, value);
  }

  void test_getPreserveComments() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.preserveComments;
    options.preserveComments = value;
    expect(options.preserveComments, value);
  }
}


class AnalysisTask_test_perform_exception extends AnalysisTask {
  AnalysisTask_test_perform_exception(InternalAnalysisContext arg0)
      : super(arg0);
  @override
  String get taskDescription => null;
  @override
  accept(AnalysisTaskVisitor visitor) {
    expect(exception, isNotNull);
    return null;
  }
  @override
  void internalPerform() {
    throw new AnalysisException("Forced exception");
  }
}


@reflectiveTest
class AnalysisTaskTest extends EngineTestCase {
  void test_perform_exception() {
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    AnalysisTask task = new AnalysisTask_test_perform_exception(context);
    task.perform(new TestTaskVisitor<Object>());
  }
}


class CompilationUnitMock extends TypedMock implements CompilationUnit {
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}


@reflectiveTest
class DartEntryTest extends EngineTestCase {
  void test_allErrors() {
    Source source = new TestSource();
    DartEntry entry = new DartEntry();
    expect(entry.allErrors, hasLength(0));
    entry.setValue(
        DartEntry.SCAN_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(source, ScannerErrorCode.UNTERMINATED_STRING_LITERAL)]);
    entry.setValue(
        DartEntry.PARSE_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(source, ParserErrorCode.ABSTRACT_CLASS_MEMBER)]);
    entry.setValueInLibrary(
        DartEntry.RESOLUTION_ERRORS,
        source,
        <AnalysisError>[
            new AnalysisError.con1(
                source,
                CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)]);
    entry.setValueInLibrary(
        DartEntry.VERIFICATION_ERRORS,
        source,
        <AnalysisError>[
            new AnalysisError.con1(source, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)]);
    entry.setValueInLibrary(
        DartEntry.HINTS,
        source,
        <AnalysisError>[new AnalysisError.con1(source, HintCode.DEAD_CODE)]);
    expect(entry.allErrors, hasLength(5));
  }

  void test_creation() {
    Source librarySource = new TestSource();
    DartEntry entry = new DartEntry();
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.PUBLIC_NAMESPACE),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
        same(CacheState.INVALID));
  }

  void test_getResolvableCompilationUnit_none() {
    DartEntry entry = new DartEntry();
    expect(entry.resolvableCompilationUnit, isNull);
  }

  void test_getResolvableCompilationUnit_parsed_accessed() {
    Source librarySource = new TestSource("/lib.dart");
    String importUri = "/f1.dart";
    Source importSource = new TestSource(importUri);
    ImportDirective importDirective =
        AstFactory.importDirective3(importUri, null);
    importDirective.source = importSource;
    importDirective.uriContent = importUri;
    String exportUri = "/f2.dart";
    Source exportSource = new TestSource(exportUri);
    ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
    exportDirective.source = exportSource;
    exportDirective.uriContent = exportUri;
    String partUri = "/f3.dart";
    Source partSource = new TestSource(partUri);
    PartDirective partDirective = AstFactory.partDirective2(partUri);
    partDirective.source = partSource;
    partDirective.uriContent = partUri;
    CompilationUnit unit =
        AstFactory.compilationUnit3([importDirective, exportDirective, partDirective]);
    DartEntry entry = new DartEntry();
    entry.setValue(DartEntry.PARSED_UNIT, unit);
    entry.getValue(DartEntry.PARSED_UNIT);
    CompilationUnit result = entry.resolvableCompilationUnit;
    expect(result, same(unit));
    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
    result = entry.resolvableCompilationUnit;
    expect(result, isNot(same(unit)));
    NodeList<Directive> directives = result.directives;
    ImportDirective resultImportDirective = directives[0] as ImportDirective;
    expect(resultImportDirective.uriContent, importUri);
    expect(resultImportDirective.source, same(importSource));
    ExportDirective resultExportDirective = directives[1] as ExportDirective;
    expect(resultExportDirective.uriContent, exportUri);
    expect(resultExportDirective.source, same(exportSource));
    PartDirective resultPartDirective = directives[2] as PartDirective;
    expect(resultPartDirective.uriContent, partUri);
    expect(resultPartDirective.source, same(partSource));
  }

  void test_getResolvableCompilationUnit_parsed_notAccessed() {
    CompilationUnit unit = AstFactory.compilationUnit();
    DartEntry entry = new DartEntry();
    entry.setValue(DartEntry.PARSED_UNIT, unit);
    expect(entry.resolvableCompilationUnit, same(unit));
  }

  void test_getResolvableCompilationUnit_resolved() {
    String importUri = "f1.dart";
    Source importSource = new TestSource(importUri);
    ImportDirective importDirective =
        AstFactory.importDirective3(importUri, null);
    importDirective.source = importSource;
    importDirective.uriContent = importUri;
    String exportUri = "f2.dart";
    Source exportSource = new TestSource(exportUri);
    ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
    exportDirective.source = exportSource;
    exportDirective.uriContent = exportUri;
    String partUri = "f3.dart";
    Source partSource = new TestSource(partUri);
    PartDirective partDirective = AstFactory.partDirective2(partUri);
    partDirective.source = partSource;
    partDirective.uriContent = partUri;
    CompilationUnit unit =
        AstFactory.compilationUnit3([importDirective, exportDirective, partDirective]);
    DartEntry entry = new DartEntry();
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        new TestSource("lib.dart"),
        unit);
    CompilationUnit result = entry.resolvableCompilationUnit;
    expect(result, isNot(same(unit)));
    NodeList<Directive> directives = result.directives;
    ImportDirective resultImportDirective = directives[0] as ImportDirective;
    expect(resultImportDirective.uriContent, importUri);
    expect(resultImportDirective.source, same(importSource));
    ExportDirective resultExportDirective = directives[1] as ExportDirective;
    expect(resultExportDirective.uriContent, exportUri);
    expect(resultExportDirective.source, same(exportSource));
    PartDirective resultPartDirective = directives[2] as PartDirective;
    expect(resultPartDirective.uriContent, partUri);
    expect(resultPartDirective.source, same(partSource));
  }

  void test_getState_invalid_resolutionErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.getState(DartEntry.RESOLUTION_ERRORS);
      fail("Expected IllegalArgumentException for RESOLUTION_ERRORS");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_getState_invalid_verificationErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.getState(DartEntry.VERIFICATION_ERRORS);
      fail("Expected IllegalArgumentException for VERIFICATION_ERRORS");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_getStateInLibrary_invalid_element() {
    DartEntry entry = new DartEntry();
    try {
      entry.getStateInLibrary(DartEntry.ELEMENT, new TestSource());
      fail("Expected IllegalArgumentException for ELEMENT");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_getValue_containingLibraries() {
    Source testSource = new TestSource();
    DartEntry entry = new DartEntry();
    List<Source> value = entry.containingLibraries;
    expect(value, hasLength(0));
    entry.addContainingLibrary(testSource);
    value = entry.containingLibraries;
    expect(value, hasLength(1));
    expect(value[0], testSource);
    entry.removeContainingLibrary(testSource);
    value = entry.containingLibraries;
    expect(value, hasLength(0));
  }

  void test_getValue_invalid_resolutionErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.getValue(DartEntry.RESOLUTION_ERRORS);
      fail("Expected IllegalArgumentException for RESOLUTION_ERRORS");
    } on ArgumentError catch (exception) {
    }
  }

  void test_getValue_invalid_verificationErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.getValue(DartEntry.VERIFICATION_ERRORS);
      fail("Expected IllegalArgumentException for VERIFICATION_ERRORS");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_getValueInLibrary_invalid_element() {
    DartEntry entry = new DartEntry();
    try {
      entry.getValueInLibrary(DartEntry.ELEMENT, new TestSource());
      fail("Expected IllegalArgumentException for ELEMENT");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_getValueInLibrary_invalid_resolutionErrors_multiple() {
    Source source1 = new TestSource();
    Source source2 = new TestSource();
    Source source3 = new TestSource();
    DartEntry entry = new DartEntry();
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source1,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source2,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source3,
        AstFactory.compilationUnit());
    try {
      entry.getValueInLibrary(DartEntry.ELEMENT, source3);
      fail("Expected IllegalArgumentException for ELEMENT");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_hasInvalidData_false() {
    DartEntry entry = new DartEntry();
    entry.recordScanError(new CaughtException(new AnalysisException(), null));
    expect(entry.hasInvalidData(DartEntry.ELEMENT), isFalse);
    expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isFalse);
    expect(entry.hasInvalidData(DartEntry.HINTS), isFalse);
    expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isFalse);
    expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isFalse);
    expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isFalse);
    expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isFalse);
    expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isFalse);
    expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isFalse);
    expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isFalse);
    expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isFalse);
    expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isFalse);
    expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isFalse);
    expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isFalse);
    expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isFalse);
  }

  void test_hasInvalidData_true() {
    DartEntry entry = new DartEntry();
    expect(entry.hasInvalidData(DartEntry.ELEMENT), isTrue);
    expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isTrue);
    expect(entry.hasInvalidData(DartEntry.HINTS), isTrue);
    expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isTrue);
    expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isTrue);
    expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isTrue);
    expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isTrue);
    expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isTrue);
    expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isTrue);
    expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isTrue);
    expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isTrue);
    expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isTrue);
    expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isTrue);
    expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isTrue);
    expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isTrue);
  }

  void test_invalidateAllInformation() {
    Source librarySource = new TestSource();
    DartEntry entry = _entryWithValidState(librarySource);
    entry.invalidateAllInformation();
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.PUBLIC_NAMESPACE),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
        same(CacheState.INVALID));
  }

  void test_invalidateAllResolutionInformation() {
    Source librarySource = new TestSource();
    DartEntry entry = _entryWithValidState(librarySource);
    entry.invalidateAllResolutionInformation(false);
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.PUBLIC_NAMESPACE),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
        same(CacheState.INVALID));
  }

  void test_invalidateAllResolutionInformation_includingUris() {
    Source librarySource = new TestSource();
    DartEntry entry = _entryWithValidState(librarySource);
    entry.invalidateAllResolutionInformation(true);
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.INVALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.PUBLIC_NAMESPACE),
        same(CacheState.INVALID));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
        same(CacheState.INVALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
        same(CacheState.INVALID));
  }

  void test_isClient() {
    DartEntry entry = new DartEntry();
    // true
    entry.setValue(DartEntry.IS_CLIENT, true);
    expect(entry.getValue(DartEntry.IS_CLIENT), isTrue);
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
    // invalidate
    entry.setState(DartEntry.IS_CLIENT, CacheState.INVALID);
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
    // false
    entry.setValue(DartEntry.IS_CLIENT, false);
    expect(entry.getValue(DartEntry.IS_CLIENT), isFalse);
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
  }

  void test_isLaunchable() {
    DartEntry entry = new DartEntry();
    // true
    entry.setValue(DartEntry.IS_LAUNCHABLE, true);
    expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isTrue);
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
    // invalidate
    entry.setState(DartEntry.IS_LAUNCHABLE, CacheState.INVALID);
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
    // false
    entry.setValue(DartEntry.IS_LAUNCHABLE, false);
    expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isFalse);
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
  }

  void test_recordBuildElementError() {
    Source firstLibrary = new TestSource('first.dart');
    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
    entry.recordBuildElementErrorInLibrary(
        firstLibrary,
        new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.ERROR));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
        same(CacheState.VALID));
  }

  void test_recordContentError() {
    Source firstLibrary = new TestSource('first.dart');
//    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary);
    entry.recordContentError(
        new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.ERROR));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.ERROR));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.ERROR));

    // The following lines are commented out because we don't currently have
    // any way of setting the state for data associated with a library we
    // don't know anything about.
//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
  }

  void test_recordHintErrorInLibrary() {
    Source firstLibrary = new TestSource('first.dart');
    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
    entry.recordHintErrorInLibrary(
        firstLibrary,
        new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
        same(CacheState.VALID));
  }

  void test_recordParseError() {
    Source firstLibrary = new TestSource('first.dart');
//    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary);
    entry.recordParseError(new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.ERROR));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.ERROR));

    // The following lines are commented out because we don't currently have
    // any way of setting the state for data associated with a library we
    // don't know anything about.
//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
  }

  void test_recordResolutionError() {
    Source firstLibrary = new TestSource('first.dart');
//    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary);
    entry.recordResolutionError(
        new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.ERROR));

    // The following lines are commented out because we don't currently have
    // any way of setting the state for data associated with a library we
    // don't know anything about.
//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
  }

  void test_recordResolutionErrorInLibrary() {
    Source firstLibrary = new TestSource('first.dart');
    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
    entry.recordResolutionErrorInLibrary(
        firstLibrary,
        new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.ERROR));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
        same(CacheState.VALID));
  }

  void test_recordScanError() {
    Source firstLibrary = new TestSource('first.dart');
//    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary);
    entry.recordScanError(new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.ERROR));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.ERROR));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.ERROR));

    // The following lines are commented out because we don't currently have
    // any way of setting the state for data associated with a library we
    // don't know anything about.
//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
  }

  void test_recordVerificationErrorInLibrary() {
    Source firstLibrary = new TestSource('first.dart');
    Source secondLibrary = new TestSource('second.dart');
    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
    entry.recordVerificationErrorInLibrary(
        firstLibrary,
        new CaughtException(new AnalysisException(), null));
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
        same(CacheState.ERROR));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
        same(CacheState.ERROR));

    expect(
        entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
        same(CacheState.VALID));
    expect(
        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
        same(CacheState.VALID));
  }

  void test_removeResolution_multiple_first() {
    Source source1 = new TestSource('first.dart');
    Source source2 = new TestSource('second.dart');
    Source source3 = new TestSource('third.dart');
    DartEntry entry = new DartEntry();
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source1,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source2,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source3,
        AstFactory.compilationUnit());
    entry.removeResolution(source1);
  }

  void test_removeResolution_multiple_last() {
    Source source1 = new TestSource('first.dart');
    Source source2 = new TestSource('second.dart');
    Source source3 = new TestSource('third.dart');
    DartEntry entry = new DartEntry();
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source1,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source2,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source3,
        AstFactory.compilationUnit());
    entry.removeResolution(source3);
  }

  void test_removeResolution_multiple_middle() {
    Source source1 = new TestSource('first.dart');
    Source source2 = new TestSource('second.dart');
    Source source3 = new TestSource('third.dart');
    DartEntry entry = new DartEntry();
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source1,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source2,
        AstFactory.compilationUnit());
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source3,
        AstFactory.compilationUnit());
    entry.removeResolution(source2);
  }

  void test_removeResolution_single() {
    Source source1 = new TestSource();
    DartEntry entry = new DartEntry();
    entry.setValueInLibrary(
        DartEntry.RESOLVED_UNIT,
        source1,
        AstFactory.compilationUnit());
    entry.removeResolution(source1);
  }

  void test_resolvableCompilationUnit_builtUnit() {
    Source librarySource = new TestSource('/lib.dart');
    CompilationUnit unit = AstFactory.compilationUnit();
    CompilationUnitElement element =
        ElementFactory.compilationUnit('test.dart');
    unit.element = element;
    DartEntry entry = new DartEntry();
    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
    entry.setValueInLibrary(DartEntry.BUILT_UNIT, librarySource, unit);
    entry.invalidateAllResolutionInformation(false);
    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
    expect(resolvableUnit, isNotNull);
    expect(resolvableUnit.element, isNull);
    expect(entry.resolvableCompilationUnit, isNull);
  }

  void test_resolvableCompilationUnit_none() {
    DartEntry entry = new DartEntry();
    expect(entry.resolvableCompilationUnit, isNull);
  }

  void test_resolvableCompilationUnit_parsed() {
    CompilationUnit unit = AstFactory.compilationUnit();
    DartEntry entry = new DartEntry();
    entry.setValue(DartEntry.PARSED_UNIT, unit);
    expect(entry.resolvableCompilationUnit, unit);
    expect(entry.resolvableCompilationUnit, isNull);
  }

  void test_resolvableCompilationUnit_resolved() {
    Source librarySource = new TestSource('/lib.dart');
    CompilationUnit unit = AstFactory.compilationUnit();
    CompilationUnitElement element =
        ElementFactory.compilationUnit('test.dart');
    unit.element = element;
    DartEntry entry = new DartEntry();
    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
    entry.invalidateAllResolutionInformation(false);
    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
    expect(resolvableUnit, isNotNull);
    expect(resolvableUnit.element, isNull);
    expect(entry.resolvableCompilationUnit, isNull);
  }

  void test_setState_element() {
    _setState(DartEntry.ELEMENT);
  }

  void test_setState_exportedLibraries() {
    _setState(DartEntry.EXPORTED_LIBRARIES);
  }

  void test_setState_hints() {
    _setStateInLibrary(DartEntry.HINTS);
  }

  void test_setState_importedLibraries() {
    _setState(DartEntry.IMPORTED_LIBRARIES);
  }

  void test_setState_includedParts() {
    _setState(DartEntry.INCLUDED_PARTS);
  }

  void test_setState_invalid_element() {
    DartEntry entry = new DartEntry();
    try {
      entry.setStateInLibrary(DartEntry.ELEMENT, null, CacheState.FLUSHED);
      fail("Expected IllegalArgumentException for ELEMENT");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_setState_invalid_resolutionErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.setState(DartEntry.RESOLUTION_ERRORS, CacheState.FLUSHED);
      fail("Expected IllegalArgumentException for RESOLUTION_ERRORS");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_setState_invalid_validState() {
    DartEntry entry = new DartEntry();
    try {
      entry.setState(SourceEntry.LINE_INFO, CacheState.VALID);
      fail("Expected ArgumentError for a state of VALID");
    } on ArgumentError catch (exception) {
    }
  }

  void test_setState_invalid_verificationErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.setState(DartEntry.VERIFICATION_ERRORS, CacheState.FLUSHED);
      fail("Expected IllegalArgumentException for VERIFICATION_ERRORS");
    } on ArgumentError catch (exception) {
      // Expected
    }
  }

  void test_setState_isClient() {
    _setState(DartEntry.IS_CLIENT);
  }

  void test_setState_isLaunchable() {
    _setState(DartEntry.IS_LAUNCHABLE);
  }

  void test_setState_lineInfo() {
    _setState(SourceEntry.LINE_INFO);
  }

  void test_setState_parsedUnit() {
    _setState(DartEntry.PARSED_UNIT);
  }

  void test_setState_parseErrors() {
    _setState(DartEntry.PARSE_ERRORS);
  }

  void test_setState_publicNamespace() {
    _setState(DartEntry.PUBLIC_NAMESPACE);
  }

  void test_setState_resolutionErrors() {
    _setStateInLibrary(DartEntry.RESOLUTION_ERRORS);
  }

  void test_setState_resolvedUnit() {
    _setStateInLibrary(DartEntry.RESOLVED_UNIT);
  }

  void test_setState_scanErrors() {
    _setState(DartEntry.SCAN_ERRORS);
  }

  void test_setState_sourceKind() {
    _setState(DartEntry.SOURCE_KIND);
  }

  void test_setState_tokenStream() {
    _setState(DartEntry.TOKEN_STREAM);
  }

  void test_setState_verificationErrors() {
    _setStateInLibrary(DartEntry.VERIFICATION_ERRORS);
  }

  void test_setValue_element() {
    _setValue(
        DartEntry.ELEMENT,
        new LibraryElementImpl.forNode(null, AstFactory.libraryIdentifier2(["lib"])));
  }

  void test_setValue_exportedLibraries() {
    _setValue(DartEntry.EXPORTED_LIBRARIES, <Source>[new TestSource()]);
  }

  void test_setValue_hints() {
    _setValueInLibrary(
        DartEntry.HINTS,
        <AnalysisError>[new AnalysisError.con1(null, HintCode.DEAD_CODE)]);
  }

  void test_setValue_importedLibraries() {
    _setValue(DartEntry.IMPORTED_LIBRARIES, <Source>[new TestSource()]);
  }

  void test_setValue_includedParts() {
    _setValue(DartEntry.INCLUDED_PARTS, <Source>[new TestSource()]);
  }

  void test_setValue_isClient() {
    _setValue(DartEntry.IS_CLIENT, true);
  }

  void test_setValue_isLaunchable() {
    _setValue(DartEntry.IS_LAUNCHABLE, true);
  }

  void test_setValue_lineInfo() {
    _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
  }

  void test_setValue_parsedUnit() {
    _setValue(DartEntry.PARSED_UNIT, AstFactory.compilationUnit());
  }

  void test_setValue_parseErrors() {
    _setValue(
        DartEntry.PARSE_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(null, ParserErrorCode.ABSTRACT_CLASS_MEMBER)]);
  }

  void test_setValue_publicNamespace() {
    _setValue(
        DartEntry.PUBLIC_NAMESPACE,
        new Namespace(new HashMap<String, Element>()));
  }

  void test_setValue_resolutionErrors() {
    _setValueInLibrary(
        DartEntry.RESOLUTION_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(
                null,
                CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)]);
  }

  void test_setValue_resolvedUnit() {
    _setValueInLibrary(DartEntry.RESOLVED_UNIT, AstFactory.compilationUnit());
  }

  void test_setValue_scanErrors() {
    _setValue(
        DartEntry.SCAN_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(
                null,
                ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT)]);
  }

  void test_setValue_sourceKind() {
    _setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
  }

  void test_setValue_tokenStream() {
    _setValue(DartEntry.TOKEN_STREAM, new Token(TokenType.LT, 5));
  }

  void test_setValue_verificationErrors() {
    _setValueInLibrary(
        DartEntry.VERIFICATION_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(null, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)]);
  }

  DartEntry _entryWithValidState([Source firstLibrary, Source secondLibrary]) {
    DartEntry entry = new DartEntry();
    entry.setValue(SourceEntry.CONTENT, null);
    entry.setValue(SourceEntry.LINE_INFO, null);
    entry.setValue(DartEntry.CONTAINING_LIBRARIES, null);
    entry.setValue(DartEntry.ELEMENT, null);
    entry.setValue(DartEntry.EXPORTED_LIBRARIES, null);
    entry.setValue(DartEntry.IMPORTED_LIBRARIES, null);
    entry.setValue(DartEntry.INCLUDED_PARTS, null);
    entry.setValue(DartEntry.IS_CLIENT, null);
    entry.setValue(DartEntry.IS_LAUNCHABLE, null);
    entry.setValue(DartEntry.PARSE_ERRORS, null);
    entry.setValue(DartEntry.PARSED_UNIT, null);
    entry.setValue(DartEntry.PUBLIC_NAMESPACE, null);
    entry.setValue(DartEntry.SCAN_ERRORS, null);
    entry.setValue(DartEntry.SOURCE_KIND, null);
    entry.setValue(DartEntry.TOKEN_STREAM, null);
    if (firstLibrary != null) {
      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary, null);
      entry.setValueInLibrary(DartEntry.BUILT_UNIT, firstLibrary, null);
      entry.setValueInLibrary(DartEntry.HINTS, firstLibrary, null);
      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary, null);
      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary, null);
      entry.setValueInLibrary(
          DartEntry.VERIFICATION_ERRORS,
          firstLibrary,
          null);
    }
    if (secondLibrary != null) {
      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary, null);
      entry.setValueInLibrary(DartEntry.BUILT_UNIT, secondLibrary, null);
      entry.setValueInLibrary(DartEntry.HINTS, secondLibrary, null);
      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary, null);
      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary, null);
      entry.setValueInLibrary(
          DartEntry.VERIFICATION_ERRORS,
          secondLibrary,
          null);
    }
    //
    // Validate that the state was set correctly.
    //
    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.CONTAINING_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.EXPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(DartEntry.IMPORTED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
    if (firstLibrary != null) {
      expect(
          entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
          same(CacheState.VALID));
    }
    if (secondLibrary != null) {
      expect(
          entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
          same(CacheState.VALID));
      expect(
          entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
          same(CacheState.VALID));
    }
    return entry;
  }

  void _setState(DataDescriptor descriptor) {
    DartEntry entry = new DartEntry();
    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
    entry.setState(descriptor, CacheState.FLUSHED);
    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
  }

  void _setStateInLibrary(DataDescriptor descriptor) {
    Source source = new TestSource();
    DartEntry entry = new DartEntry();
    expect(
        entry.getStateInLibrary(descriptor, source),
        isNot(same(CacheState.FLUSHED)));
    entry.setStateInLibrary(descriptor, source, CacheState.FLUSHED);
    expect(
        entry.getStateInLibrary(descriptor, source),
        same(CacheState.FLUSHED));
  }

  void _setValue(DataDescriptor descriptor, Object newValue) {
    DartEntry entry = new DartEntry();
    Object value = entry.getValue(descriptor);
    expect(newValue, isNot(same(value)));
    entry.setValue(descriptor, newValue);
    expect(entry.getState(descriptor), same(CacheState.VALID));
    expect(entry.getValue(descriptor), same(newValue));
  }

  void _setValueInLibrary(DataDescriptor descriptor, Object newValue) {
    Source source = new TestSource();
    DartEntry entry = new DartEntry();
    Object value = entry.getValueInLibrary(descriptor, source);
    expect(newValue, isNot(same(value)));
    entry.setValueInLibrary(descriptor, source, newValue);
    expect(entry.getStateInLibrary(descriptor, source), same(CacheState.VALID));
    expect(entry.getValueInLibrary(descriptor, source), same(newValue));
  }
}


@reflectiveTest
class GenerateDartErrorsTaskTest extends EngineTestCase {
  void test_accept() {
    GenerateDartErrorsTask task =
        new GenerateDartErrorsTask(null, null, null, null);
    expect(task.accept(new GenerateDartErrorsTaskTestTV_accept()), isTrue);
  }

  void test_getException() {
    GenerateDartErrorsTask task =
        new GenerateDartErrorsTask(null, null, null, null);
    expect(task.exception, isNull);
  }

  void test_getLibraryElement() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    LibraryElement element = ElementFactory.library(context, "lib");
    GenerateDartErrorsTask task =
        new GenerateDartErrorsTask(context, null, null, element);
    expect(task.libraryElement, same(element));
  }

  void test_getSource() {
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    GenerateDartErrorsTask task =
        new GenerateDartErrorsTask(null, source, null, null);
    expect(task.source, same(source));
  }

  void test_perform() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(source);
    context.applyChanges(changeSet);
    context.setContents(source, r'''
library lib;
class A {
  int f = new A();
}''');
    LibraryElement libraryElement = context.computeLibraryElement(source);
    CompilationUnit unit =
        context.getResolvedCompilationUnit(source, libraryElement);
    GenerateDartErrorsTask task =
        new GenerateDartErrorsTask(context, source, unit, libraryElement);
    task.perform(
        new GenerateDartErrorsTaskTestTV_perform(libraryElement, source));
  }

  void test_perform_validateDirectives() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    Source source =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(source);
    context.applyChanges(changeSet);
    // TODO(scheglov) "import" causes second error reported
//    context.setContents(source, EngineTestCase.createSource([
//        "library lib;",
//        "import 'invaliduri^.dart';",
//        "export '\${a}lib3.dart';",
//        "part '/does/not/exist.dart';",
//        "class A {}"]));
    context.setContents(source, r'''
library lib;
part '/does/not/exist.dart';
class A {}''');
    LibraryElement libraryElement = context.computeLibraryElement(source);
    CompilationUnit unit =
        context.getResolvedCompilationUnit(source, libraryElement);
    GenerateDartErrorsTask task =
        new GenerateDartErrorsTask(context, source, unit, libraryElement);
    task.perform(
        new GenerateDartErrorsTaskTestTV_perform_validateDirectives(
            libraryElement,
            source));
  }
}


class GenerateDartErrorsTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => true;
}


class GenerateDartErrorsTaskTestTV_perform extends TestTaskVisitor<bool> {
  LibraryElement libraryElement;
  Source source;
  GenerateDartErrorsTaskTestTV_perform(this.libraryElement, this.source);
  @override
  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.libraryElement, same(libraryElement));
    expect(task.source, same(source));
    List<AnalysisError> errors = task.errors;
    expect(errors, hasLength(1));
    return true;
  }
}


class GenerateDartErrorsTaskTestTV_perform_validateDirectives extends
    TestTaskVisitor<bool> {
  LibraryElement libraryElement;
  Source source;
  GenerateDartErrorsTaskTestTV_perform_validateDirectives(this.libraryElement,
      this.source);
  @override
  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.libraryElement, same(libraryElement));
    expect(task.source, same(source));
    List<AnalysisError> errors = task.errors;
    expect(errors, hasLength(1));
    expect(errors[0].errorCode, same(CompileTimeErrorCode.URI_DOES_NOT_EXIST));
    return true;
  }
}


@reflectiveTest
class GenerateDartHintsTaskTest extends EngineTestCase {
  void test_accept() {
    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
    expect(task.accept(new GenerateDartHintsTaskTestTV_accept()), isTrue);
  }
  void test_getException() {
    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
    expect(task.exception, isNull);
  }
  void test_getHintMap() {
    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
    expect(task.hintMap, isNull);
  }
  void test_getLibraryElement() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    LibraryElement element = ElementFactory.library(context, "lib");
    GenerateDartHintsTask task =
        new GenerateDartHintsTask(context, null, element);
    expect(task.libraryElement, same(element));
  }
  void test_perform() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    ChangeSet changeSet = new ChangeSet();
    Source librarySource =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    changeSet.addedSource(librarySource);
    Source unusedSource =
        new FileBasedSource.con1(FileUtilities2.createFile("/unused.dart"));
    changeSet.addedSource(unusedSource);
    Source partSource =
        new FileBasedSource.con1(FileUtilities2.createFile("/part.dart"));
    changeSet.addedSource(partSource);
    context.applyChanges(changeSet);
    context.setContents(librarySource, r'''
library lib;
import 'unused.dart';
part 'part.dart';''');
    context.setContents(unusedSource, "library unused;");
    context.setContents(partSource, "part of lib;");
    List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(2);
    units[0] = new TimestampedData<CompilationUnit>(
        context.getModificationStamp(librarySource),
        context.resolveCompilationUnit2(librarySource, librarySource));
    units[1] = new TimestampedData<CompilationUnit>(
        context.getModificationStamp(partSource),
        context.resolveCompilationUnit2(partSource, librarySource));
    GenerateDartHintsTask task = new GenerateDartHintsTask(
        context,
        units,
        context.computeLibraryElement(librarySource));
    task.perform(
        new GenerateDartHintsTaskTestTV_perform(librarySource, partSource));
  }
}


class GenerateDartHintsTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitGenerateDartHintsTask(GenerateDartHintsTask task) => true;
}

class GenerateDartHintsTaskTestTV_perform extends TestTaskVisitor<bool> {
  Source librarySource;
  Source partSource;
  GenerateDartHintsTaskTestTV_perform(this.librarySource, this.partSource);
  @override
  bool visitGenerateDartHintsTask(GenerateDartHintsTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.libraryElement, isNotNull);
    HashMap<Source, List<AnalysisError>> hintMap = task.hintMap;
    expect(hintMap, hasLength(2));
    expect(hintMap[librarySource], hasLength(1));
    expect(hintMap[partSource], hasLength(0));
    return true;
  }
}

@reflectiveTest
class GenerateDartLintsTaskTest extends EngineTestCase {
  void test_accept() {
    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
    expect(task.accept(new GenerateDartLintsTaskTestTV_accept()), isTrue);
  }
  void test_exception() {
    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
    expect(task.exception, isNull);
  }
  void test_libraryElement() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    LibraryElement element = ElementFactory.library(context, "lib");
    GenerateDartLintsTask task =
        new GenerateDartLintsTask(context, null, element);
    expect(task.libraryElement, same(element));
  }
  void test_lintMap() {
    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
    expect(task.lintMap, isNull);
  }

  void test_perform() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    ChangeSet changeSet = new ChangeSet();
    Source librarySource =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    changeSet.addedSource(librarySource);
    context.applyChanges(changeSet);
    context.setContents(librarySource, r'''
library lib;
''');
    List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(1);
    units[0] = new TimestampedData<CompilationUnit>(
        context.getModificationStamp(librarySource),
        context.resolveCompilationUnit2(librarySource, librarySource));
    GenerateDartLintsTask task = new GenerateDartLintsTask(
        context,
        units,
        context.computeLibraryElement(librarySource));
    task.perform(new GenerateDartLintsTaskTestTV_perform(librarySource));
  }
}

class GenerateDartLintsTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitGenerateDartLintsTask(GenerateDartLintsTask task) => true;
}

class GenerateDartLintsTaskTestTV_perform extends TestTaskVisitor<bool> {
  Source librarySource;
  GenerateDartLintsTaskTestTV_perform(this.librarySource);
  @override
  bool visitGenerateDartLintsTask(GenerateDartLintsTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.libraryElement, isNotNull);
    return true;
  }
}

@reflectiveTest
class GetContentTaskTest extends EngineTestCase {
  void test_accept() {
    Source source = new TestSource('/test.dart', '');
    GetContentTask task = new GetContentTask(null, source);
    expect(task.accept(new GetContentTaskTestTV_accept()), isTrue);
  }

  void test_getException() {
    Source source = new TestSource('/test.dart', '');
    GetContentTask task = new GetContentTask(null, source);
    expect(task.exception, isNull);
  }

  void test_getModificationTime() {
    Source source = new TestSource('/test.dart', '');
    GetContentTask task = new GetContentTask(null, source);
    expect(task.modificationTime, -1);
  }

  void test_getSource() {
    Source source = new TestSource('/test.dart', '');
    GetContentTask task = new GetContentTask(null, source);
    expect(task.source, same(source));
  }

  void test_perform_exception() {
    TestSource source = new TestSource();
    source.generateExceptionOnRead = true;
    //    final InternalAnalysisContext context = new AnalysisContextImpl();
    //    context.setSourceFactory(new SourceFactory(new FileUriResolver()));
    GetContentTask task = new GetContentTask(null, source);
    task.perform(new GetContentTaskTestTV_perform_exception());
  }

  void test_perform_valid() {
    Source source = new TestSource('/test.dart', 'class A {}');
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    GetContentTask task = new GetContentTask(context, source);
    task.perform(new GetContentTaskTestTV_perform_valid(context, source));
  }
}


class GetContentTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitGetContentTask(GetContentTask task) => true;
}

class GetContentTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
  @override
  bool visitGetContentTask(GetContentTask task) {
    expect(task.exception, isNotNull);
    return true;
  }
}


class GetContentTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
  InternalAnalysisContext context;
  Source source;
  GetContentTaskTestTV_perform_valid(this.context, this.source);
  @override
  bool visitGetContentTask(GetContentTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.modificationTime, context.getModificationStamp(source));
    expect(task.source, same(source));
    return true;
  }
}


@reflectiveTest
class HtmlEntryTest extends EngineTestCase {
  void set state(DataDescriptor descriptor) {
    HtmlEntry entry = new HtmlEntry();
    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
    entry.setState(descriptor, CacheState.FLUSHED);
    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
  }

  void test_creation() {
    HtmlEntry entry = new HtmlEntry();
    expect(entry, isNotNull);
  }

  void test_getAllErrors() {
    Source source = new TestSource();
    HtmlEntry entry = new HtmlEntry();
    expect(entry.allErrors, hasLength(0));
    entry.setValue(
        HtmlEntry.PARSE_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(source, ParserErrorCode.EXPECTED_TOKEN, [";"])]);
    entry.setValue(
        HtmlEntry.RESOLUTION_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(source, HtmlWarningCode.INVALID_URI, ["-"])]);
    entry.setValue(
        HtmlEntry.HINTS,
        <AnalysisError>[new AnalysisError.con1(source, HintCode.DEAD_CODE)]);
    expect(entry.allErrors, hasLength(3));
  }

  void test_invalidateAllResolutionInformation() {
    HtmlEntry entry = _entryWithValidState();
    entry.invalidateAllResolutionInformation(false);
    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(
        entry.getState(HtmlEntry.REFERENCED_LIBRARIES),
        same(CacheState.VALID));
    expect(
        entry.getState(HtmlEntry.RESOLUTION_ERRORS),
        same(CacheState.INVALID));
  }

  void test_invalidateAllResolutionInformation_includingUris() {
    HtmlEntry entry = _entryWithValidState();
    entry.invalidateAllResolutionInformation(true);
    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(
        entry.getState(HtmlEntry.REFERENCED_LIBRARIES),
        same(CacheState.INVALID));
    expect(
        entry.getState(HtmlEntry.RESOLUTION_ERRORS),
        same(CacheState.INVALID));
  }

  void test_setState_element() {
    state = HtmlEntry.ELEMENT;
  }

  void test_setState_hints() {
    state = HtmlEntry.HINTS;
  }

  void test_setState_lineInfo() {
    state = SourceEntry.LINE_INFO;
  }

  void test_setState_parsedUnit() {
    state = HtmlEntry.PARSED_UNIT;
  }

  void test_setState_parseErrors() {
    state = HtmlEntry.PARSE_ERRORS;
  }

  void test_setState_referencedLibraries() {
    state = HtmlEntry.REFERENCED_LIBRARIES;
  }

  void test_setState_resolutionErrors() {
    state = HtmlEntry.RESOLUTION_ERRORS;
  }

  void test_setValue_element() {
    _setValue(HtmlEntry.ELEMENT, new HtmlElementImpl(null, "test.html"));
  }

  void test_setValue_hints() {
    _setValue(
        HtmlEntry.HINTS,
        <AnalysisError>[new AnalysisError.con1(null, HintCode.DEAD_CODE)]);
  }

  void test_setValue_illegal() {
    HtmlEntry entry = new HtmlEntry();
    try {
      entry.setValue(DartEntry.ELEMENT, null);
      fail("Expected IllegalArgumentException for DartEntry.ELEMENT");
    } on ArgumentError catch (exception) {
    }
  }

  void test_setValue_lineInfo() {
    _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
  }

  void test_setValue_parsedUnit() {
    _setValue(HtmlEntry.PARSED_UNIT, new ht.HtmlUnit(null, null, null));
  }

  void test_setValue_parseErrors() {
    _setValue(
        HtmlEntry.PARSE_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(null, HtmlWarningCode.INVALID_URI, ["-"])]);
  }

  void test_setValue_referencedLibraries() {
    _setValue(HtmlEntry.REFERENCED_LIBRARIES, <Source>[new TestSource()]);
  }

  void test_setValue_resolutionErrors() {
    _setValue(
        HtmlEntry.RESOLUTION_ERRORS,
        <AnalysisError>[
            new AnalysisError.con1(null, HtmlWarningCode.INVALID_URI, ["-"])]);
  }

  HtmlEntry _entryWithValidState() {
    HtmlEntry entry = new HtmlEntry();
    entry.setValue(HtmlEntry.ELEMENT, null);
    entry.setValue(HtmlEntry.HINTS, null);
    entry.setValue(SourceEntry.LINE_INFO, null);
    entry.setValue(HtmlEntry.PARSE_ERRORS, null);
    entry.setValue(HtmlEntry.PARSED_UNIT, null);
    entry.setValue(HtmlEntry.REFERENCED_LIBRARIES, null);
    entry.setValue(HtmlEntry.RESOLUTION_ERRORS, null);
    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.VALID));
    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
    expect(
        entry.getState(HtmlEntry.REFERENCED_LIBRARIES),
        same(CacheState.VALID));
    expect(entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.VALID));
    return entry;
  }

  void _setValue(DataDescriptor descriptor, Object newValue) {
    HtmlEntry entry = new HtmlEntry();
    Object value = entry.getValue(descriptor);
    expect(newValue, isNot(same(value)));
    entry.setValue(descriptor, newValue);
    expect(entry.getState(descriptor), same(CacheState.VALID));
    expect(entry.getValue(descriptor), same(newValue));
  }
}


@reflectiveTest
class IncrementalAnalysisCacheTest {
  Source _source = new TestSource();
  DartEntry _entry = new DartEntry();
  CompilationUnit _unit = new CompilationUnitMock();
  IncrementalAnalysisCache _result;
  void setUp() {
    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, _unit);
  }
  void test_cacheResult() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    CompilationUnit newUnit = new CompilationUnitMock();
    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(newUnit));
    expect(_result.oldContents, "hbazlo");
    expect(_result.newContents, "hbazlo");
    expect(_result.offset, 0);
    expect(_result.oldLength, 0);
    expect(_result.newLength, 0);
  }
  void test_cacheResult_noCache() {
    IncrementalAnalysisCache cache = null;
    CompilationUnit newUnit = new CompilationUnitMock();
    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
    expect(_result, isNull);
  }
  void test_cacheResult_noCacheNoResult() {
    IncrementalAnalysisCache cache = null;
    CompilationUnit newUnit = null;
    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
    expect(_result, isNull);
  }
  void test_cacheResult_noResult() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    CompilationUnit newUnit = null;
    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
    expect(_result, isNull);
  }
  void test_clear_differentSource() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    Source otherSource = new TestSource("blat.dart", "blat");
    _result = IncrementalAnalysisCache.clear(cache, otherSource);
    expect(_result, same(cache));
  }
  void test_clear_nullCache() {
    IncrementalAnalysisCache cache = null;
    _result = IncrementalAnalysisCache.clear(cache, _source);
    expect(_result, isNull);
  }
  void test_clear_sameSource() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    _result = IncrementalAnalysisCache.clear(cache, _source);
    expect(_result, isNull);
  }
  void test_update_append() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    DartEntry newEntry = new DartEntry();
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "hbazxlo",
        4,
        0,
        1,
        newEntry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(_unit));
    expect(_result.oldContents, "hello");
    expect(_result.newContents, "hbazxlo");
    expect(_result.offset, 1);
    expect(_result.oldLength, 2);
    expect(_result.newLength, 4);
  }
  void test_update_appendToCachedResult() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    CompilationUnit newUnit = new CompilationUnitMock();
    cache = IncrementalAnalysisCache.cacheResult(cache, newUnit);
    expect(cache, isNotNull);
    DartEntry newEntry = new DartEntry();
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "hbazxlo",
        4,
        0,
        1,
        newEntry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(newUnit));
    expect(_result.oldContents, "hbazlo");
    expect(_result.newContents, "hbazxlo");
    expect(_result.offset, 4);
    expect(_result.oldLength, 0);
    expect(_result.newLength, 1);
  }
  void test_update_appendWithNewResolvedUnit() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    DartEntry newEntry = new DartEntry();
    CompilationUnit newUnit = new CompilationUnitMock();
    newEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, newUnit);
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "hbazxlo",
        4,
        0,
        1,
        newEntry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(newUnit));
    expect(_result.oldContents, "hbazlo");
    expect(_result.newContents, "hbazxlo");
    expect(_result.offset, 4);
    expect(_result.oldLength, 0);
    expect(_result.newLength, 1);
  }
  void test_update_appendWithNoNewResolvedUnit() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    DartEntry newEntry = new DartEntry();
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "hbazxlo",
        4,
        0,
        1,
        newEntry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(_unit));
    expect(_result.oldContents, "hello");
    expect(_result.newContents, "hbazxlo");
    expect(_result.offset, 1);
    expect(_result.oldLength, 2);
    expect(_result.newLength, 4);
  }
  void test_update_delete() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    DartEntry newEntry = new DartEntry();
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "hzlo",
        1,
        2,
        0,
        newEntry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(_unit));
    expect(_result.oldContents, "hello");
    expect(_result.newContents, "hzlo");
    expect(_result.offset, 1);
    expect(_result.oldLength, 2);
    expect(_result.newLength, 1);
  }
  void test_update_insert_nonContiguous_after() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    DartEntry newEntry = new DartEntry();
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "hbazlox",
        6,
        0,
        1,
        newEntry);
    expect(_result, isNull);
  }
  void test_update_insert_nonContiguous_before() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    DartEntry newEntry = new DartEntry();
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "xhbazlo",
        0,
        0,
        1,
        newEntry);
    expect(_result, isNull);
  }
  void test_update_newSource_entry() {
    Source oldSource = new TestSource("blat.dart", "blat");
    DartEntry oldEntry = new DartEntry();
    CompilationUnit oldUnit = new CompilationUnitMock();
    oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        oldSource,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        oldEntry);
    expect(cache.source, same(oldSource));
    expect(cache.resolvedUnit, same(oldUnit));
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "foo",
        "foobz",
        3,
        0,
        2,
        _entry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(_unit));
    expect(_result.oldContents, "foo");
    expect(_result.newContents, "foobz");
    expect(_result.offset, 3);
    expect(_result.oldLength, 0);
    expect(_result.newLength, 2);
  }
  void test_update_newSource_noEntry() {
    Source oldSource = new TestSource("blat.dart", "blat");
    DartEntry oldEntry = new DartEntry();
    CompilationUnit oldUnit = new CompilationUnitMock();
    oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        oldSource,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        oldEntry);
    expect(cache.source, same(oldSource));
    expect(cache.resolvedUnit, same(oldUnit));
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "foo",
        "foobar",
        3,
        0,
        3,
        null);
    expect(_result, isNull);
  }
  void test_update_noCache_entry() {
    _result = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(_unit));
    expect(_result.oldContents, "hello");
    expect(_result.newContents, "hbazlo");
    expect(_result.offset, 1);
    expect(_result.oldLength, 2);
    expect(_result.newLength, 3);
    expect(_result.hasWork, isTrue);
  }
  void test_update_noCache_entry_noOldSource_append() {
    _result = IncrementalAnalysisCache.update(
        null,
        _source,
        null,
        "hellxo",
        4,
        0,
        1,
        _entry);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(_unit));
    expect(_result.oldContents, "hello");
    expect(_result.newContents, "hellxo");
    expect(_result.offset, 4);
    expect(_result.oldLength, 0);
    expect(_result.newLength, 1);
    expect(_result.hasWork, isTrue);
  }
  void test_update_noCache_entry_noOldSource_delete() {
    _result =
        IncrementalAnalysisCache.update(null, _source, null, "helo", 4, 1, 0, _entry);
    expect(_result, isNull);
  }
  void test_update_noCache_entry_noOldSource_replace() {
    _result =
        IncrementalAnalysisCache.update(null, _source, null, "helxo", 4, 1, 1, _entry);
    expect(_result, isNull);
  }
  void test_update_noCache_noEntry() {
    _result = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        null);
    expect(_result, isNull);
  }
  void test_update_replace() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    _result = IncrementalAnalysisCache.update(
        cache,
        _source,
        "hbazlo",
        "hbarrlo",
        3,
        1,
        2,
        null);
    expect(_result, isNotNull);
    expect(_result.source, same(_source));
    expect(_result.resolvedUnit, same(_unit));
    expect(_result.oldContents, "hello");
    expect(_result.newContents, "hbarrlo");
    expect(_result.offset, 1);
    expect(_result.oldLength, 2);
    expect(_result.newLength, 4);
  }
  void test_verifyStructure_invalidUnit() {
    String oldCode = "main() {foo;}";
    String newCode = "main() {boo;}";
    CompilationUnit badUnit = _parse("main() {bad;}");
    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, badUnit);
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        oldCode,
        newCode,
        8,
        1,
        1,
        _entry);
    CompilationUnit newUnit = _parse(newCode);
    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
    expect(_result, isNull);
  }
  void test_verifyStructure_noCache() {
    IncrementalAnalysisCache cache = null;
    CompilationUnit newUnit = new CompilationUnitMock();
    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
    expect(_result, isNull);
  }
  void test_verifyStructure_noCacheNoUnit() {
    IncrementalAnalysisCache cache = null;
    CompilationUnit newUnit = null;
    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
    expect(_result, isNull);
  }
  void test_verifyStructure_noUnit() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    CompilationUnit newUnit = null;
    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
    expect(_result, same(cache));
    expect(_result.resolvedUnit, same(_unit));
  }
  void test_verifyStructure_otherSource() {
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        "hello",
        "hbazlo",
        1,
        2,
        3,
        _entry);
    CompilationUnit newUnit = new CompilationUnitMock();
    Source otherSource = new TestSource("blat.dart", "blat");
    _result =
        IncrementalAnalysisCache.verifyStructure(cache, otherSource, newUnit);
    expect(_result, same(cache));
    expect(_result.resolvedUnit, same(_unit));
  }
  void test_verifyStructure_validUnit() {
    String oldCode = "main() {foo;}";
    String newCode = "main() {boo;}";
    CompilationUnit goodUnit = _parse(newCode);
    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, goodUnit);
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        _source,
        oldCode,
        newCode,
        1,
        2,
        3,
        _entry);
    CompilationUnit newUnit = _parse(newCode);
    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
    expect(_result, same(cache));
    expect(_result.resolvedUnit, same(goodUnit));
  }
  CompilationUnit _parse(String code) {
    Scanner scanner = new Scanner(
        _source,
        new CharSequenceReader(code),
        AnalysisErrorListener.NULL_LISTENER);
    Parser parser = new Parser(_source, AnalysisErrorListener.NULL_LISTENER);
    return parser.parseCompilationUnit(scanner.tokenize());
  }
}


@reflectiveTest
class IncrementalAnalysisTaskTest extends EngineTestCase {
  void test_accept() {
    IncrementalAnalysisTask task = new IncrementalAnalysisTask(null, null);
    expect(task.accept(new IncrementalAnalysisTaskTestTV_accept()), isTrue);
  }

  void test_perform() {
    // main() {} String foo;
    // main() {String} String foo;
    CompilationUnit newUnit =
        _assertTask("main() {", "", "String", "} String foo;");
    NodeList<CompilationUnitMember> declarations = newUnit.declarations;
    FunctionDeclaration main = declarations[0] as FunctionDeclaration;
    expect(main.name.name, "main");
    BlockFunctionBody body = main.functionExpression.body as BlockFunctionBody;
    ExpressionStatement statement =
        body.block.statements[0] as ExpressionStatement;
    expect(statement.toSource(), "String;");
    SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
    expect(identifier.name, "String");
    expect(identifier.staticElement, isNotNull);
    TopLevelVariableDeclaration fooDecl =
        declarations[1] as TopLevelVariableDeclaration;
    SimpleIdentifier fooName = fooDecl.variables.variables[0].name;
    expect(fooName.name, "foo");
    expect(fooName.staticElement, isNotNull);
    // assert element reference is preserved
  }

  CompilationUnit _assertTask(String prefix, String removed, String added,
      String suffix) {
    String oldCode = "$prefix$removed$suffix";
    String newCode = "$prefix$added$suffix";
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    Source source = new TestSource("/test.dart", oldCode);
    DartEntry entry = new DartEntry();
    CompilationUnit oldUnit = context.resolveCompilationUnit2(source, source);
    expect(oldUnit, isNotNull);
    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, source, oldUnit);
    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
        null,
        source,
        oldCode,
        newCode,
        prefix.length,
        removed.length,
        added.length,
        entry);
    expect(cache, isNotNull);
    IncrementalAnalysisTask task = new IncrementalAnalysisTask(context, cache);
    CompilationUnit newUnit =
        task.perform(new IncrementalAnalysisTaskTestTV_assertTask(task));
    expect(newUnit, isNotNull);
    return newUnit;
  }
}


class IncrementalAnalysisTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitIncrementalAnalysisTask(IncrementalAnalysisTask task) => true;
}


class IncrementalAnalysisTaskTestTV_assertTask extends
    TestTaskVisitor<CompilationUnit> {
  IncrementalAnalysisTask task;
  IncrementalAnalysisTaskTestTV_assertTask(this.task);
  @override
  CompilationUnit
      visitIncrementalAnalysisTask(IncrementalAnalysisTask incrementalAnalysisTask) =>
      task.compilationUnit;
}


@reflectiveTest
class LintGeneratorTest extends EngineTestCase {
  void test_generate() {

    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    ChangeSet changeSet = new ChangeSet();
    Source librarySource =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    changeSet.addedSource(librarySource);
    context.applyChanges(changeSet);
    context.setContents(librarySource, r'''
library lib;
''');

    CompilationUnit unit =
        context.resolveCompilationUnit2(librarySource, librarySource);
    List<CompilationUnit> units = <CompilationUnit>[];
    units.add(unit);

    RecordingErrorListener errorListener = new RecordingErrorListener();

    LintGeneratorTest_Linter linter = new LintGeneratorTest_Linter();

    LintGenerator lintGenerator =
        new LintGenerator(units, errorListener, [linter]);
    lintGenerator.generate();

    linter.testExpectations();
  }

  void test_generate_null_visitor() {

    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    ChangeSet changeSet = new ChangeSet();
    Source librarySource =
        new FileBasedSource.con1(FileUtilities2.createFile("/test.dart"));
    changeSet.addedSource(librarySource);
    context.applyChanges(changeSet);
    context.setContents(librarySource, r'''
library lib;
''');

    CompilationUnit unit =
        context.resolveCompilationUnit2(librarySource, librarySource);
    List<CompilationUnit> units = <CompilationUnit>[];
    units.add(unit);

    RecordingErrorListener errorListener = new RecordingErrorListener();

    Linter badLinter = new LintGeneratorTest_Linter_Null_Visitor();
    LintGeneratorTest_Linter goodLinter = new LintGeneratorTest_Linter();

    LintGenerator lintGenerator =
        new LintGenerator(units, errorListener, [badLinter, goodLinter]);
    // Test that generate does not fall down with a null visitor
    lintGenerator.generate();
    // Well-formed linter should still get called
    goodLinter.testExpectations();
  }

}


class LintGeneratorTest_Linter extends Linter with SimpleAstVisitor<Object> {

  bool visited;

  @override
  AstVisitor getVisitor() => this;

  testExpectations() {
    expect(reporter, isNotNull);
    expect(visited, isTrue);
  }

  @override
  Object visitCompilationUnit(CompilationUnit node) {
    visited = true;
    return null;
  }
}

class LintGeneratorTest_Linter_Null_Visitor extends Linter {
  @override
  AstVisitor getVisitor() => null;
}


@reflectiveTest
class ParseDartTaskTest extends EngineTestCase {
  void test_accept() {
    ParseDartTask task = new ParseDartTask(null, null, null, null);
    expect(task.accept(new ParseDartTaskTestTV_accept()), isTrue);
  }

  void test_getCompilationUnit() {
    ParseDartTask task = new ParseDartTask(null, null, null, null);
    expect(task.compilationUnit, isNull);
  }

  void test_getErrors() {
    ParseDartTask task = new ParseDartTask(null, null, null, null);
    expect(task.errors, hasLength(0));
  }

  void test_getException() {
    ParseDartTask task = new ParseDartTask(null, null, null, null);
    expect(task.exception, isNull);
  }

  void test_getSource() {
    Source source = new TestSource('/test.dart');
    ParseDartTask task = new ParseDartTask(null, source, null, null);
    expect(task.source, same(source));
  }

  void test_hasNonPartOfDirective() {
    ParseDartTask task = new ParseDartTask(null, null, null, null);
    expect(task.hasNonPartOfDirective, isFalse);
  }

  void test_hasPartOfDirective() {
    ParseDartTask task = new ParseDartTask(null, null, null, null);
    expect(task.hasPartOfDirective, isFalse);
  }

  void test_perform_exception() {
    TestSource source = new TestSource();
    source.generateExceptionOnRead = true;
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ParseDartTask task = new ParseDartTask(context, source, null, null);
    task.perform(new ParseDartTaskTestTV_perform_exception());
  }

  void test_perform_library() {
    String content = r'''
library lib;
import 'lib2.dart';
export 'lib3.dart';
part 'part.dart';
class A {''';
    Source source = new TestSource('/test.dart', content);
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ParseDartTask task = _createParseTask(context, source, content);
    task.perform(new ParseDartTaskTestTV_perform_library(context, source));
  }

  void test_perform_part() {
    String content = r'''
part of lib;
class B {}''';
    Source source = new TestSource('/test.dart', content);
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ParseDartTask task = _createParseTask(context, source, content);
    task.perform(new ParseDartTaskTestTV_perform_part(context, source));
  }

  void test_perform_validateDirectives() {
    String content = r'''
library lib;
import '/does/not/exist.dart';
import '://invaliduri.dart';
export '${a}lib3.dart';
part 'part.dart';
class A {}''';
    Source source = new TestSource('/test.dart', content);
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ParseDartTask task = _createParseTask(context, source, content);
    task.perform(
        new ParseDartTaskTestTV_perform_validateDirectives(context, source));
  }

  /**
   * Create and return a task that will parse the given content from the given source in the given
   * context.
   *
   * @param context the context to be passed to the task
   * @param source the source to be parsed
   * @param content the content of the source to be parsed
   * @return the task that was created
   * @throws AnalysisException if the task could not be created
   */
  ParseDartTask _createParseTask(InternalAnalysisContext context, Source source,
      String content) {
    ScanDartTask scanTask = new ScanDartTask(context, source, content);
    scanTask.perform(new ParseDartTaskTestTV_createParseTask());
    return new ParseDartTask(
        context,
        source,
        scanTask.tokenStream,
        scanTask.lineInfo);
  }
}


class ParseDartTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitParseDartTask(ParseDartTask task) => true;
}


class ParseDartTaskTestTV_createParseTask extends TestTaskVisitor<Object> {
  @override
  Object visitScanDartTask(ScanDartTask task) => null;
}


class ParseDartTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
  @override
  bool visitParseDartTask(ParseDartTask task) {
    expect(task.exception, isNotNull);
    return true;
  }
}


class ParseDartTaskTestTV_perform_library extends TestTaskVisitor<Object> {
  InternalAnalysisContext context;
  Source source;
  ParseDartTaskTestTV_perform_library(this.context, this.source);
  @override
  Object visitParseDartTask(ParseDartTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.compilationUnit, isNotNull);
    expect(task.errors, hasLength(1));
    expect(task.source, same(source));
    expect(task.hasNonPartOfDirective, isTrue);
    expect(task.hasPartOfDirective, isFalse);
    return null;
  }
}


class ParseDartTaskTestTV_perform_part extends TestTaskVisitor<Object> {
  InternalAnalysisContext context;
  Source source;
  ParseDartTaskTestTV_perform_part(this.context, this.source);
  @override
  Object visitParseDartTask(ParseDartTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.compilationUnit, isNotNull);
    expect(task.errors, hasLength(0));
    expect(task.source, same(source));
    expect(task.hasNonPartOfDirective, isFalse);
    expect(task.hasPartOfDirective, isTrue);
    return null;
  }
}


class ParseDartTaskTestTV_perform_validateDirectives extends
    TestTaskVisitor<Object> {
  InternalAnalysisContext context;
  Source source;
  ParseDartTaskTestTV_perform_validateDirectives(this.context, this.source);
  @override
  Object visitParseDartTask(ParseDartTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.compilationUnit, isNotNull);
    GatheringErrorListener errorListener = new GatheringErrorListener();
    errorListener.addAll(task.errors);
    errorListener.assertErrorsWithCodes(
        [
            CompileTimeErrorCode.URI_WITH_INTERPOLATION,
            CompileTimeErrorCode.INVALID_URI]);
    expect(task.source, same(source));
    expect(task.hasNonPartOfDirective, isTrue);
    expect(task.hasPartOfDirective, isFalse);
    return null;
  }
}


@reflectiveTest
class ParseHtmlTaskTest extends EngineTestCase {
  ParseHtmlTask parseContents(String contents, TestLogger testLogger) {
    return parseSource(
        new TestSource('/test.dart', contents),
        contents,
        testLogger);
  }

  ParseHtmlTask parseSource(Source source, String contents,
      TestLogger testLogger) {
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.setContents(source, contents);
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ParseHtmlTask task = new ParseHtmlTask(context, source, contents);
    Logger oldLogger = AnalysisEngine.instance.logger;
    try {
      AnalysisEngine.instance.logger = testLogger;
      task.perform(new ParseHtmlTaskTestTV_parseSource(context, source));
    } finally {
      AnalysisEngine.instance.logger = oldLogger;
    }
    return task;
  }

  void test_accept() {
    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
    expect(task.accept(new ParseHtmlTaskTestTV_accept()), isTrue);
  }

  void test_getException() {
    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
    expect(task.exception, isNull);
  }

  void test_getHtmlUnit() {
    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
    expect(task.htmlUnit, isNull);
  }

  void test_getLineInfo() {
    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
    expect(task.lineInfo, isNull);
  }

  void test_getReferencedLibraries() {
    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
    expect(task.referencedLibraries, hasLength(0));
  }

  void test_getSource() {
    Source source = new TestSource('/test.dart');
    ParseHtmlTask task = new ParseHtmlTask(null, source, "");
    expect(task.source, same(source));
  }

  void test_perform_embedded_source() {
    String contents = r'''
<html>
<head>
  <script type='application/dart'>
    void buttonPressed() {}
  </script>
</head>
<body>
</body>
</html>''';
    TestLogger testLogger = new TestLogger();
    ParseHtmlTask task = parseContents(contents, testLogger);
    expect(task.referencedLibraries, hasLength(0));
    expect(testLogger.errorCount, 0);
    expect(testLogger.infoCount, 0);
  }

  void test_perform_empty_source_reference() {
    String contents = r'''
<html>
<head>
  <script type='application/dart' src=''/>
</head>
<body>
</body>
</html>''';
    TestLogger testLogger = new TestLogger();
    ParseHtmlTask task = parseContents(contents, testLogger);
    expect(task.referencedLibraries, hasLength(0));
    expect(testLogger.errorCount, 0);
    expect(testLogger.infoCount, 0);
  }

  void test_perform_invalid_source_reference() {
    String contents = r'''
<html>
<head>
  <script type='application/dart' src='an;invalid:[]uri'/>
</head>
<body>
</body>
</html>''';
    TestLogger testLogger = new TestLogger();
    ParseHtmlTask task = parseContents(contents, testLogger);
    expect(task.referencedLibraries, hasLength(0));
    expect(testLogger.errorCount, 0);
    expect(testLogger.infoCount, 0);
  }

  void test_perform_non_existing_source_reference() {
    String contents = r'''
<html>
<head>
  <script type='application/dart' src='does/not/exist.dart'/>
</head>
<body>
</body>
</html>''';
    TestLogger testLogger = new TestLogger();
    ParseHtmlTask task = parseSource(
        new ParseHtmlTaskTest_non_existing_source(contents),
        contents,
        testLogger);
    expect(task.referencedLibraries, hasLength(0));
    expect(testLogger.errorCount, 0);
    expect(testLogger.infoCount, 0);
  }

  void test_perform_referenced_source() {
    // TODO(scheglov) this test fails because we put into cache TestSource
    // test.dart (and actually should test.html), but resolve
    // src='test.dart' as a FileBasedSource
    // We need to switch to a virtual file system and use it everywhere.
//    String contents = EngineTestCase.createSource([
//        "<html>",
//        "<head>",
//        "  <script type='application/dart' src='test.dart'/>",
//        "</head>",
//        "<body>",
//        "</body>",
//        "</html>"]);
//    TestLogger testLogger = new TestLogger();
//    ParseHtmlTask task = parseContents(contents, testLogger);
//    EngineTestCase.assertLength(1, task.referencedLibraries);
//    JUnitTestCase.assertEquals(0, testLogger.errorCount);
//    JUnitTestCase.assertEquals(0, testLogger.errorCount);
  }
}


class ParseHtmlTaskTest_non_existing_source extends TestSource {
  ParseHtmlTaskTest_non_existing_source(String arg0) : super(arg0);
  @override
  Uri resolveRelativeUri(Uri containedUri) {
    try {
      return parseUriWithException("file:/does/not/exist.dart");
    } on URISyntaxException catch (exception) {
      return null;
    }
  }
}


class ParseHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitParseHtmlTask(ParseHtmlTask task) => true;
}


class ParseHtmlTaskTestTV_parseSource extends TestTaskVisitor<bool> {
  InternalAnalysisContext context;
  Source source;
  ParseHtmlTaskTestTV_parseSource(this.context, this.source);
  @override
  bool visitParseHtmlTask(ParseHtmlTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.htmlUnit, isNotNull);
    expect(task.lineInfo, isNotNull);
    expect(task.source, same(source));
    return true;
  }
}


@reflectiveTest
class PartitionManagerTest extends EngineTestCase {
  void test_clearCache() {
    PartitionManager manager = new PartitionManager();
    DartSdk sdk = new MockDartSdk();
    SdkCachePartition oldPartition = manager.forSdk(sdk);
    manager.clearCache();
    SdkCachePartition newPartition = manager.forSdk(sdk);
    expect(newPartition, isNot(same(oldPartition)));
  }

  void test_creation() {
    expect(new PartitionManager(), isNotNull);
  }

  void test_forSdk() {
    PartitionManager manager = new PartitionManager();
    DartSdk sdk1 = new MockDartSdk();
    SdkCachePartition partition1 = manager.forSdk(sdk1);
    expect(partition1, isNotNull);
    expect(manager.forSdk(sdk1), same(partition1));
    DartSdk sdk2 = new MockDartSdk();
    SdkCachePartition partition2 = manager.forSdk(sdk2);
    expect(partition2, isNotNull);
    expect(manager.forSdk(sdk2), same(partition2));
    expect(partition2, isNot(same(partition1)));
  }
}


@reflectiveTest
class ResolveDartLibraryTaskTest extends EngineTestCase {
  void test_accept() {
    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
    expect(task.accept(new ResolveDartLibraryTaskTestTV_accept()), isTrue);
  }
  void test_getException() {
    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
    expect(task.exception, isNull);
  }
  void test_getLibraryResolver() {
    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
    expect(task.libraryResolver, isNull);
  }
  void test_getLibrarySource() {
    Source source = new TestSource('/test.dart');
    ResolveDartLibraryTask task =
        new ResolveDartLibraryTask(null, null, source);
    expect(task.librarySource, same(source));
  }
  void test_getUnitSource() {
    Source source = new TestSource('/test.dart');
    ResolveDartLibraryTask task =
        new ResolveDartLibraryTask(null, source, null);
    expect(task.unitSource, same(source));
  }
  void test_perform_exception() {
    TestSource source = new TestSource();
    source.generateExceptionOnRead = true;
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ResolveDartLibraryTask task =
        new ResolveDartLibraryTask(context, source, source);
    task.perform(new ResolveDartLibraryTaskTestTV_perform_exception());
  }
  void test_perform_library() {
    Source source = new TestSource('/test.dart', r'''
library lib;
class A {}''');
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    ResolveDartLibraryTask task =
        new ResolveDartLibraryTask(context, source, source);
    task.perform(new ResolveDartLibraryTaskTestTV_perform_library(source));
  }
}


class ResolveDartLibraryTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) => true;
}


class ResolveDartLibraryTaskTestTV_perform_exception extends
    TestTaskVisitor<bool> {
  @override
  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
    expect(task.exception, isNotNull);
    return true;
  }
}


class ResolveDartLibraryTaskTestTV_perform_library extends TestTaskVisitor<bool>
    {
  Source source;
  ResolveDartLibraryTaskTestTV_perform_library(this.source);
  @override
  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.libraryResolver, isNotNull);
    expect(task.librarySource, same(source));
    expect(task.unitSource, same(source));
    return true;
  }
}


@reflectiveTest
class ResolveDartUnitTaskTest extends EngineTestCase {
  void test_accept() {
    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
    expect(task.accept(new ResolveDartUnitTaskTestTV_accept()), isTrue);
  }

  void test_getException() {
    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
    expect(task.exception, isNull);
  }

  void test_getLibrarySource() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    LibraryElementImpl element = ElementFactory.library(context, "lib");
    Source source = element.source;
    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, element);
    expect(task.librarySource, same(source));
  }

  void test_getResolvedUnit() {
    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
    expect(task.resolvedUnit, isNull);
  }

  void test_getSource() {
    Source source = new TestSource('/test.dart');
    ResolveDartUnitTask task = new ResolveDartUnitTask(null, source, null);
    expect(task.source, same(source));
  }

  void test_perform_exception() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    LibraryElementImpl element = ElementFactory.library(context, "lib");
    TestSource source = new TestSource();
    source.generateExceptionOnRead = true;
    (element.definingCompilationUnit as CompilationUnitElementImpl).source =
        source;
    ResolveDartUnitTask task =
        new ResolveDartUnitTask(context, source, element);
    task.perform(new ResolveDartUnitTaskTestTV_perform_exception());
  }

  void test_perform_library() {
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    LibraryElementImpl libraryElement = ElementFactory.library(context, "lib");
    CompilationUnitElementImpl unitElement =
        libraryElement.definingCompilationUnit as CompilationUnitElementImpl;
    ClassElementImpl classElement = ElementFactory.classElement2("A");
    classElement.nameOffset = 19;
    ConstructorElementImpl constructorElement =
        ElementFactory.constructorElement2(classElement, null);
    constructorElement.synthetic = true;
    classElement.constructors = <ConstructorElement>[constructorElement];
    unitElement.types = <ClassElement>[classElement];
    Source source = unitElement.source;
    context.setContents(source, r'''
library lib;
class A {}''');
    ResolveDartUnitTask task =
        new ResolveDartUnitTask(context, source, libraryElement);
    task.perform(
        new ResolveDartUnitTaskTestTV_perform_library(source, context));
  }
}


class ResolveDartUnitTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitResolveDartUnitTask(ResolveDartUnitTask task) => true;
}


class ResolveDartUnitTaskTestTV_perform_exception extends TestTaskVisitor<bool>
    {
  @override
  bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
    expect(task.exception, isNotNull);
    return true;
  }
}


class ResolveDartUnitTaskTestTV_perform_library extends TestTaskVisitor<bool> {
  Source source;
  InternalAnalysisContext context;
  ResolveDartUnitTaskTestTV_perform_library(this.source, this.context);
  @override
  bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.librarySource, same(source));
    expect(task.resolvedUnit, isNotNull);
    expect(task.source, same(source));
    return true;
  }
}


@reflectiveTest
class ResolveHtmlTaskTest extends EngineTestCase {
  void test_accept() {
    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
    expect(task.accept(new ResolveHtmlTaskTestTV_accept()), isTrue);
  }

  void test_getElement() {
    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
    expect(task.element, isNull);
  }

  void test_getException() {
    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
    expect(task.exception, isNull);
  }

  void test_getResolutionErrors() {
    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
    expect(task.resolutionErrors, hasLength(0));
  }

  void test_getSource() {
    Source source = new TestSource('test.dart', '');
    ResolveHtmlTask task = new ResolveHtmlTask(null, source, 0, null);
    expect(task.source, same(source));
  }

  void test_perform_exception() {
    Source source = new TestSource();
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ResolveHtmlTask task = new ResolveHtmlTask(context, source, 0, null);
    task.perform(new ResolveHtmlTaskTestTV_perform_exception());
  }

  void test_perform_valid() {
    int modificationStamp = 73;
    String content = r'''
<html>
<head>
  <script type='application/dart'>
    void f() { x = 0; }
  </script>
</head>
<body>
</body>
</html>''';
    Source source = new TestSource("/test.html", content);
    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
    ParseHtmlTask parseTask = new ParseHtmlTask(context, source, content);
    parseTask.perform(new ResolveHtmlTaskTestTV_perform_valid_2());
    ResolveHtmlTask task =
        new ResolveHtmlTask(context, source, modificationStamp, parseTask.htmlUnit);
    task.perform(
        new ResolveHtmlTaskTestTV_perform_valid(modificationStamp, source));
  }
}


class ResolveHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitResolveHtmlTask(ResolveHtmlTask task) => true;
}


class ResolveHtmlTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
  @override
  bool visitResolveHtmlTask(ResolveHtmlTask task) {
    expect(task.exception, isNotNull);
    return true;
  }
}


class ResolveHtmlTaskTestTV_perform_valid extends TestTaskVisitor<Object> {
  int modificationStamp;
  Source source;
  ResolveHtmlTaskTestTV_perform_valid(this.modificationStamp, this.source);
  @override
  Object visitResolveHtmlTask(ResolveHtmlTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.element, isNotNull);
    expect(task.resolutionErrors, hasLength(1));
    expect(task.source, same(source));
    return null;
  }
}


class ResolveHtmlTaskTestTV_perform_valid_2 extends TestTaskVisitor<Object> {
  @override
  Object visitParseHtmlTask(ParseHtmlTask task) => null;
}


@reflectiveTest
class ScanDartTaskTest extends EngineTestCase {
  void test_accept() {
    ScanDartTask task = new ScanDartTask(null, null, null);
    expect(task.accept(new ScanDartTaskTestTV_accept()), isTrue);
  }

  void test_getErrors() {
    ScanDartTask task = new ScanDartTask(null, null, null);
    expect(task.errors, hasLength(0));
  }

  void test_getException() {
    ScanDartTask task = new ScanDartTask(null, null, null);
    expect(task.exception, isNull);
  }

  void test_getLineInfo() {
    ScanDartTask task = new ScanDartTask(null, null, null);
    expect(task.lineInfo, isNull);
  }

  void test_getSource() {
    Source source = new TestSource('test.dart', '');
    ScanDartTask task = new ScanDartTask(null, source, null);
    expect(task.source, same(source));
  }

  void test_perform_valid() {
    String content = 'class A {}';
    Source source = new TestSource('test.dart', content);
    InternalAnalysisContext context = new AnalysisContextImpl();
    context.sourceFactory = new SourceFactory([new FileUriResolver()]);
    ScanDartTask task = new ScanDartTask(context, source, content);
    task.perform(new ScanDartTaskTestTV_perform_valid(context, source));
  }
}


class ScanDartTaskTestTV_accept extends TestTaskVisitor<bool> {
  @override
  bool visitScanDartTask(ScanDartTask task) => true;
}


class ScanDartTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
  InternalAnalysisContext context;
  Source source;
  ScanDartTaskTestTV_perform_valid(this.context, this.source);
  @override
  bool visitScanDartTask(ScanDartTask task) {
    CaughtException exception = task.exception;
    if (exception != null) {
      throw exception;
    }
    expect(task.tokenStream, isNotNull);
    expect(task.errors, hasLength(0));
    expect(task.lineInfo, isNotNull);
    expect(task.source, same(source));
    return true;
  }
}


@reflectiveTest
class SdkCachePartitionTest extends EngineTestCase {
  void test_contains_false() {
    SdkCachePartition partition = new SdkCachePartition(null, 8);
    Source source = new TestSource();
    expect(partition.contains(source), isFalse);
  }

  void test_contains_true() {
    SdkCachePartition partition = new SdkCachePartition(null, 8);
    SourceFactory factory =
        new SourceFactory([new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]);
    Source source = factory.forUri("dart:core");
    expect(partition.contains(source), isTrue);
  }

  void test_creation() {
    expect(new SdkCachePartition(null, 8), isNotNull);
  }
}


@reflectiveTest
class SourcesChangedEventTest {

  void test_added() {
    var source = new StringSource('', '/test.dart');
    var changeSet = new ChangeSet();
    changeSet.addedSource(source);
    var event = new SourcesChangedEvent(changeSet);
    assertEvent(event, wereSourcesAdded: true);
  }

  void test_changedContent() {
    var source = new StringSource('', '/test.dart');
    var changeSet = new ChangeSet();
    changeSet.changedContent(source, 'library A;');
    var event = new SourcesChangedEvent(changeSet);
    assertEvent(event, changedSources: [source]);
  }

  void test_changedContent2() {
    var source = new StringSource('', '/test.dart');
    var event = new SourcesChangedEvent.changedContent(source, 'library A;');
    assertEvent(event, changedSources: [source]);
  }

  void test_changedRange() {
    var source = new StringSource('', '/test.dart');
    var changeSet = new ChangeSet();
    changeSet.changedRange(source, 'library A;', 0, 0, 13);
    var event = new SourcesChangedEvent(changeSet);
    assertEvent(event, changedSources: [source]);
  }

  void test_changedRange2() {
    var source = new StringSource('', '/test.dart');
    var event =
        new SourcesChangedEvent.changedRange(source, 'library A;', 0, 0, 13);
    assertEvent(event, changedSources: [source]);
  }

  void test_changedSources() {
    var source = new StringSource('', '/test.dart');
    var changeSet = new ChangeSet();
    changeSet.changedSource(source);
    var event = new SourcesChangedEvent(changeSet);
    assertEvent(event, changedSources: [source]);
  }

  void test_deleted() {
    var source = new StringSource('', '/test.dart');
    var changeSet = new ChangeSet();
    changeSet.deletedSource(source);
    var event = new SourcesChangedEvent(changeSet);
    assertEvent(event, wereSourcesRemovedOrDeleted: true);
  }

  void test_empty() {
    var changeSet = new ChangeSet();
    var event = new SourcesChangedEvent(changeSet);
    assertEvent(event);
  }

  void test_removed() {
    var source = new StringSource('', '/test.dart');
    var changeSet = new ChangeSet();
    changeSet.removedSource(source);
    var event = new SourcesChangedEvent(changeSet);
    assertEvent(event, wereSourcesRemovedOrDeleted: true);
  }

  static void assertEvent(SourcesChangedEvent event, {bool wereSourcesAdded:
      false, List<Source> changedSources: Source.EMPTY_ARRAY,
      bool wereSourcesRemovedOrDeleted: false}) {
    expect(event.wereSourcesAdded, wereSourcesAdded);
    expect(event.changedSources, changedSources);
    expect(event.wereSourcesRemovedOrDeleted, wereSourcesRemovedOrDeleted);
  }
}


class SourcesChangedListener {
  List<SourcesChangedEvent> actualEvents = [];

  void assertEvent({bool wereSourcesAdded: false, List<Source> changedSources:
      Source.EMPTY_ARRAY, bool wereSourcesRemovedOrDeleted: false}) {
    if (actualEvents.isEmpty) {
      fail('Expected event but found none');
    }
    SourcesChangedEvent actual = actualEvents.removeAt(0);
    SourcesChangedEventTest.assertEvent(
        actual,
        wereSourcesAdded: wereSourcesAdded,
        changedSources: changedSources,
        wereSourcesRemovedOrDeleted: wereSourcesRemovedOrDeleted);
  }

  void assertNoMoreEvents() {
    expect(actualEvents, []);
  }

  void onData(SourcesChangedEvent event) {
    actualEvents.add(event);
  }
}


/**
 * Instances of the class `TestAnalysisContext` implement an analysis context in which every
 * method will cause a test to fail when invoked.
 */
class TestAnalysisContext implements InternalAnalysisContext {
  @override
  AnalysisOptions get analysisOptions {
    fail("Unexpected invocation of getAnalysisOptions");
    return null;
  }
  @override
  void set analysisOptions(AnalysisOptions options) {
    fail("Unexpected invocation of setAnalysisOptions");
  }
  @override
  void set analysisPriorityOrder(List<Source> sources) {
    fail("Unexpected invocation of setAnalysisPriorityOrder");
  }
  @override
  set contentCache(ContentCache value) {
    fail("Unexpected invocation of setContentCache");
  }
  @override
  DeclaredVariables get declaredVariables {
    fail("Unexpected invocation of getDeclaredVariables");
    return null;
  }
  @override
  List<Source> get htmlSources {
    fail("Unexpected invocation of getHtmlSources");
    return null;
  }
  @override
  bool get isDisposed {
    fail("Unexpected invocation of isDisposed");
    return false;
  }
  @override
  List<Source> get launchableClientLibrarySources {
    fail("Unexpected invocation of getLaunchableClientLibrarySources");
    return null;
  }
  @override
  List<Source> get launchableServerLibrarySources {
    fail("Unexpected invocation of getLaunchableServerLibrarySources");
    return null;
  }
  @override
  List<Source> get librarySources {
    fail("Unexpected invocation of getLibrarySources");
    return null;
  }
  @override
  Stream<SourcesChangedEvent> get onSourcesChanged {
    fail("Unexpected invocation of onSourcesChanged");
    return null;
  }
  @override
  List<Source> get prioritySources {
    fail("Unexpected invocation of getPrioritySources");
    return null;
  }
  @override
  List<Source> get refactoringUnsafeSources {
    fail("Unexpected invocation of getRefactoringUnsafeSources");
    return null;
  }
  @override
  SourceFactory get sourceFactory {
    fail("Unexpected invocation of getSourceFactory");
    return null;
  }
  @override
  void set sourceFactory(SourceFactory factory) {
    fail("Unexpected invocation of setSourceFactory");
  }
  @override
  AnalysisContextStatistics get statistics {
    fail("Unexpected invocation of getStatistics");
    return null;
  }
  @override
  TypeProvider get typeProvider {
    fail("Unexpected invocation of getTypeProvider");
    return null;
  }
  @override
  void addListener(AnalysisListener listener) {
    fail("Unexpected invocation of addListener");
  }
  @override
  void addSourceInfo(Source source, SourceEntry info) {
    fail("Unexpected invocation of addSourceInfo");
  }
  @override
  void applyAnalysisDelta(AnalysisDelta delta) {
    fail("Unexpected invocation of applyAnalysisDelta");
  }
  @override
  void applyChanges(ChangeSet changeSet) {
    fail("Unexpected invocation of applyChanges");
  }
  @override
  String computeDocumentationComment(Element element) {
    fail("Unexpected invocation of computeDocumentationComment");
    return null;
  }
  @override
  List<AnalysisError> computeErrors(Source source) {
    fail("Unexpected invocation of computeErrors");
    return null;
  }
  @override
  List<Source> computeExportedLibraries(Source source) {
    fail("Unexpected invocation of computeExportedLibraries");
    return null;
  }
  @override
  HtmlElement computeHtmlElement(Source source) {
    fail("Unexpected invocation of computeHtmlElement");
    return null;
  }
  @override
  List<Source> computeImportedLibraries(Source source) {
    fail("Unexpected invocation of computeImportedLibraries");
    return null;
  }
  @override
  SourceKind computeKindOf(Source source) {
    fail("Unexpected invocation of computeKindOf");
    return null;
  }
  @override
  LibraryElement computeLibraryElement(Source source) {
    fail("Unexpected invocation of computeLibraryElement");
    return null;
  }
  @override
  LineInfo computeLineInfo(Source source) {
    fail("Unexpected invocation of computeLineInfo");
    return null;
  }
  @override
  CompilationUnit computeResolvableCompilationUnit(Source source) {
    fail("Unexpected invocation of computeResolvableCompilationUnit");
    return null;
  }
  @override
  Future<CompilationUnit> computeResolvedCompilationUnitAsync(Source source,
      Source librarySource) {
    fail("Unexpected invocation of getResolvedCompilationUnitFuture");
    return null;
  }
  @override
  void dispose() {
    fail("Unexpected invocation of dispose");
  }
  @override
  bool exists(Source source) {
    fail("Unexpected invocation of exists");
    return false;
  }
  @override
  CompilationUnitElement getCompilationUnitElement(Source unitSource,
      Source librarySource) {
    fail("Unexpected invocation of getCompilationUnitElement");
    return null;
  }
  @override
  TimestampedData<String> getContents(Source source) {
    fail("Unexpected invocation of getContents");
    return null;
  }
  @override
  InternalAnalysisContext getContextFor(Source source) {
    fail("Unexpected invocation of getContextFor");
    return null;
  }
  @override
  Element getElement(ElementLocation location) {
    fail("Unexpected invocation of getElement");
    return null;
  }
  @override
  AnalysisErrorInfo getErrors(Source source) {
    fail("Unexpected invocation of getErrors");
    return null;
  }
  @override
  HtmlElement getHtmlElement(Source source) {
    fail("Unexpected invocation of getHtmlElement");
    return null;
  }
  @override
  List<Source> getHtmlFilesReferencing(Source source) {
    fail("Unexpected invocation of getHtmlFilesReferencing");
    return null;
  }
  @override
  SourceKind getKindOf(Source source) {
    fail("Unexpected invocation of getKindOf");
    return null;
  }
  @override
  List<Source> getLibrariesContaining(Source source) {
    fail("Unexpected invocation of getLibrariesContaining");
    return null;
  }
  @override
  List<Source> getLibrariesDependingOn(Source librarySource) {
    fail("Unexpected invocation of getLibrariesDependingOn");
    return null;
  }
  @override
  List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
    fail("Unexpected invocation of getLibrariesReferencedFromHtml");
    return null;
  }
  @override
  LibraryElement getLibraryElement(Source source) {
    fail("Unexpected invocation of getLibraryElement");
    return null;
  }
  @override
  LineInfo getLineInfo(Source source) {
    fail("Unexpected invocation of getLineInfo");
    return null;
  }
  @override
  int getModificationStamp(Source source) {
    fail("Unexpected invocation of getModificationStamp");
    return 0;
  }
  @override
  Namespace getPublicNamespace(LibraryElement library) {
    fail("Unexpected invocation of getPublicNamespace");
    return null;
  }
  @override
  CompilationUnit getResolvedCompilationUnit(Source unitSource,
      LibraryElement library) {
    fail("Unexpected invocation of getResolvedCompilationUnit");
    return null;
  }
  @override
  CompilationUnit getResolvedCompilationUnit2(Source unitSource,
      Source librarySource) {
    fail("Unexpected invocation of getResolvedCompilationUnit");
    return null;
  }
  @override
  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
    fail("Unexpected invocation of getResolvedHtmlUnit");
    return null;
  }
  @override
  bool handleContentsChanged(Source source, String originalContents,
      String newContents, bool notify) {
    fail("Unexpected invocation of handleContentsChanged");
    return false;
  }
  @override
  bool isClientLibrary(Source librarySource) {
    fail("Unexpected invocation of isClientLibrary");
    return false;
  }
  @override
  bool isServerLibrary(Source librarySource) {
    fail("Unexpected invocation of isServerLibrary");
    return false;
  }
  @override
  CompilationUnit parseCompilationUnit(Source source) {
    fail("Unexpected invocation of parseCompilationUnit");
    return null;
  }
  @override
  ht.HtmlUnit parseHtmlUnit(Source source) {
    fail("Unexpected invocation of parseHtmlUnit");
    return null;
  }
  @override
  AnalysisResult performAnalysisTask() {
    fail("Unexpected invocation of performAnalysisTask");
    return null;
  }
  @override
  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
    fail("Unexpected invocation of recordLibraryElements");
  }
  @override
  void removeListener(AnalysisListener listener) {
    fail("Unexpected invocation of removeListener");
  }
  @override
  CompilationUnit resolveCompilationUnit(Source unitSource,
      LibraryElement library) {
    fail("Unexpected invocation of resolveCompilationUnit");
    return null;
  }
  @override
  CompilationUnit resolveCompilationUnit2(Source unitSource,
      Source librarySource) {
    fail("Unexpected invocation of resolveCompilationUnit");
    return null;
  }
  @override
  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
    fail("Unexpected invocation of resolveHtmlUnit");
    return null;
  }
  @override
  void setChangedContents(Source source, String contents, int offset,
      int oldLength, int newLength) {
    fail("Unexpected invocation of setChangedContents");
  }
  @override
  void setContents(Source source, String contents) {
    fail("Unexpected invocation of setContents");
  }
  @override
  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
      DataDescriptor rowDesc, CacheState state)) {
    fail("Unexpected invocation of visitCacheItems");
  }
}


class TestAnalysisContext_test_addSourceInfo extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_addSourceInfo();
  @override
  void addSourceInfo(Source source, SourceEntry info) {
    invoked = true;
  }
}


class TestAnalysisContext_test_applyChanges extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_applyChanges();
  @override
  void applyChanges(ChangeSet changeSet) {
    invoked = true;
  }
}


class TestAnalysisContext_test_computeDocumentationComment extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeDocumentationComment();
  @override
  String computeDocumentationComment(Element element) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_computeErrors extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeErrors();
  @override
  List<AnalysisError> computeErrors(Source source) {
    invoked = true;
    return AnalysisError.NO_ERRORS;
  }
}


class TestAnalysisContext_test_computeExportedLibraries extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeExportedLibraries();
  @override
  List<Source> computeExportedLibraries(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_computeHtmlElement extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeHtmlElement();
  @override
  HtmlElement computeHtmlElement(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_computeImportedLibraries extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeImportedLibraries();
  @override
  List<Source> computeImportedLibraries(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_computeKindOf extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeKindOf();
  @override
  SourceKind computeKindOf(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_computeLibraryElement extends TestAnalysisContext
    {
  bool invoked = false;
  TestAnalysisContext_test_computeLibraryElement();
  @override
  LibraryElement computeLibraryElement(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_computeLineInfo extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeLineInfo();
  @override
  LineInfo computeLineInfo(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_computeResolvableCompilationUnit extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_computeResolvableCompilationUnit();
  @override
  CompilationUnit computeResolvableCompilationUnit(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_dispose extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_dispose();
  @override
  void dispose() {
    invoked = true;
  }
}


class TestAnalysisContext_test_exists extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_exists();
  @override
  bool exists(Source source) {
    invoked = true;
    return false;
  }
}


class TestAnalysisContext_test_getAnalysisOptions extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getAnalysisOptions();
  @override
  AnalysisOptions get analysisOptions {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getCompilationUnitElement extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getCompilationUnitElement();
  @override
  CompilationUnitElement getCompilationUnitElement(Source unitSource,
      Source librarySource) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getContents extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getContents();
  @override
  TimestampedData<String> getContents(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getElement extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getElement();
  @override
  Element getElement(ElementLocation location) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getErrors extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getErrors();
  @override
  AnalysisErrorInfo getErrors(Source source) {
    invoked = true;
    return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
  }
}


class TestAnalysisContext_test_getHtmlElement extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getHtmlElement();
  @override
  HtmlElement getHtmlElement(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getHtmlFilesReferencing extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getHtmlFilesReferencing();
  @override
  List<Source> getHtmlFilesReferencing(Source source) {
    invoked = true;
    return Source.EMPTY_ARRAY;
  }
}


class TestAnalysisContext_test_getHtmlSources extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getHtmlSources();
  @override
  List<Source> get htmlSources {
    invoked = true;
    return Source.EMPTY_ARRAY;
  }
}


class TestAnalysisContext_test_getKindOf extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getKindOf();
  @override
  SourceKind getKindOf(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getLaunchableClientLibrarySources extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLaunchableClientLibrarySources();
  @override
  List<Source> get launchableClientLibrarySources {
    invoked = true;
    return Source.EMPTY_ARRAY;
  }
}


class TestAnalysisContext_test_getLaunchableServerLibrarySources extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLaunchableServerLibrarySources();
  @override
  List<Source> get launchableServerLibrarySources {
    invoked = true;
    return Source.EMPTY_ARRAY;
  }
}


class TestAnalysisContext_test_getLibrariesContaining extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLibrariesContaining();
  @override
  List<Source> getLibrariesContaining(Source source) {
    invoked = true;
    return Source.EMPTY_ARRAY;
  }
}


class TestAnalysisContext_test_getLibrariesDependingOn extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLibrariesDependingOn();
  @override
  List<Source> getLibrariesDependingOn(Source librarySource) {
    invoked = true;
    return Source.EMPTY_ARRAY;
  }
}


class TestAnalysisContext_test_getLibrariesReferencedFromHtml extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLibrariesReferencedFromHtml();
  @override
  List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getLibraryElement extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLibraryElement();
  @override
  LibraryElement getLibraryElement(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getLibrarySources extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLibrarySources();
  @override
  List<Source> get librarySources {
    invoked = true;
    return Source.EMPTY_ARRAY;
  }
}


class TestAnalysisContext_test_getLineInfo extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getLineInfo();
  @override
  LineInfo getLineInfo(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getModificationStamp extends TestAnalysisContext
    {
  bool invoked = false;
  TestAnalysisContext_test_getModificationStamp();
  @override
  int getModificationStamp(Source source) {
    invoked = true;
    return 0;
  }
}


class TestAnalysisContext_test_getPublicNamespace extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getPublicNamespace();
  @override
  Namespace getPublicNamespace(LibraryElement library) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getRefactoringUnsafeSources extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getRefactoringUnsafeSources();
  @override
  List<Source> get refactoringUnsafeSources {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getResolvedCompilationUnit_element extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getResolvedCompilationUnit_element();
  @override
  CompilationUnit getResolvedCompilationUnit(Source unitSource,
      LibraryElement library) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getResolvedCompilationUnit_source extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getResolvedCompilationUnit_source();
  @override
  CompilationUnit getResolvedCompilationUnit2(Source unitSource,
      Source librarySource) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getResolvedHtmlUnit extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getResolvedHtmlUnit();
  @override
  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getSourceFactory extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getSourceFactory();
  @override
  SourceFactory get sourceFactory {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getStatistics extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getStatistics();
  @override
  AnalysisContextStatistics get statistics {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_getTypeProvider extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_getTypeProvider();
  @override
  TypeProvider get typeProvider {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_isClientLibrary extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_isClientLibrary();
  @override
  bool isClientLibrary(Source librarySource) {
    invoked = true;
    return false;
  }
}


class TestAnalysisContext_test_isDisposed extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_isDisposed();
  @override
  bool get isDisposed {
    invoked = true;
    return false;
  }
}


class TestAnalysisContext_test_isServerLibrary extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_isServerLibrary();
  @override
  bool isServerLibrary(Source librarySource) {
    invoked = true;
    return false;
  }
}


class TestAnalysisContext_test_parseCompilationUnit extends TestAnalysisContext
    {
  bool invoked = false;
  TestAnalysisContext_test_parseCompilationUnit();
  @override
  CompilationUnit parseCompilationUnit(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_parseHtmlUnit extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_parseHtmlUnit();
  @override
  ht.HtmlUnit parseHtmlUnit(Source source) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_performAnalysisTask extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_performAnalysisTask();
  @override
  AnalysisResult performAnalysisTask() {
    invoked = true;
    return new AnalysisResult(new List<ChangeNotice>(0), 0, null, 0);
  }
}


class TestAnalysisContext_test_recordLibraryElements extends TestAnalysisContext
    {
  bool invoked = false;
  TestAnalysisContext_test_recordLibraryElements();
  @override
  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
    invoked = true;
  }
}


class TestAnalysisContext_test_resolveCompilationUnit extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_resolveCompilationUnit();
  @override
  CompilationUnit resolveCompilationUnit2(Source unitSource,
      Source librarySource) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_resolveCompilationUnit_element extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_resolveCompilationUnit_element();
  @override
  CompilationUnit resolveCompilationUnit(Source unitSource,
      LibraryElement library) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_resolveHtmlUnit extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_resolveHtmlUnit();
  @override
  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
    invoked = true;
    return null;
  }
}


class TestAnalysisContext_test_setAnalysisOptions extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_setAnalysisOptions();
  @override
  void set analysisOptions(AnalysisOptions options) {
    invoked = true;
  }
}


class TestAnalysisContext_test_setAnalysisPriorityOrder extends
    TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_setAnalysisPriorityOrder();
  @override
  void set analysisPriorityOrder(List<Source> sources) {
    invoked = true;
  }
}


class TestAnalysisContext_test_setChangedContents extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_setChangedContents();
  @override
  void setChangedContents(Source source, String contents, int offset,
      int oldLength, int newLength) {
    invoked = true;
  }
}


class TestAnalysisContext_test_setContents extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_setContents();
  @override
  void setContents(Source source, String contents) {
    invoked = true;
  }
}


class TestAnalysisContext_test_setSourceFactory extends TestAnalysisContext {
  bool invoked = false;
  TestAnalysisContext_test_setSourceFactory();
  @override
  void set sourceFactory(SourceFactory factory) {
    invoked = true;
  }
}


/**
 * Instances of the class `TestTaskVisitor` implement a task visitor that fails if any of its
 * methods are invoked. Subclasses typically override the expected methods to not cause a test
 * failure.
 */
class TestTaskVisitor<E> implements AnalysisTaskVisitor<E> {
  @override
  E visitBuildUnitElementTask(BuildUnitElementTask task) {
    fail("Unexpectedly invoked visitGenerateDartErrorsTask");
    return null;
  }

  @override
  E visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
    fail("Unexpectedly invoked visitGenerateDartErrorsTask");
    return null;
  }
  @override
  E visitGenerateDartHintsTask(GenerateDartHintsTask task) {
    fail("Unexpectedly invoked visitGenerateDartHintsTask");
    return null;
  }
  @override
  E visitGenerateDartLintsTask(GenerateDartLintsTask task) {
    fail("Unexpectedly invoked visitGenerateDartLintsTask");
    return null;
  }
  @override
  E visitGetContentTask(GetContentTask task) {
    fail("Unexpectedly invoked visitGetContentsTask");
    return null;
  }
  @override
  E
      visitIncrementalAnalysisTask(IncrementalAnalysisTask incrementalAnalysisTask) {
    fail("Unexpectedly invoked visitIncrementalAnalysisTask");
    return null;
  }
  @override
  E visitParseDartTask(ParseDartTask task) {
    fail("Unexpectedly invoked visitParseDartTask");
    return null;
  }
  @override
  E visitParseHtmlTask(ParseHtmlTask task) {
    fail("Unexpectedly invoked visitParseHtmlTask");
    return null;
  }
  @override
  E visitResolveDartLibraryCycleTask(ResolveDartLibraryCycleTask task) {
    fail("Unexpectedly invoked visitResolveDartLibraryCycleTask");
    return null;
  }
  @override
  E visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
    fail("Unexpectedly invoked visitResolveDartLibraryTask");
    return null;
  }
  @override
  E visitResolveDartUnitTask(ResolveDartUnitTask task) {
    fail("Unexpectedly invoked visitResolveDartUnitTask");
    return null;
  }
  @override
  E visitResolveHtmlTask(ResolveHtmlTask task) {
    fail("Unexpectedly invoked visitResolveHtmlTask");
    return null;
  }

  @override
  E visitScanDartTask(ScanDartTask task) {
    fail("Unexpectedly invoked visitScanDartTask");
    return null;
  }
}


@reflectiveTest
class UniversalCachePartitionTest extends EngineTestCase {
  void test_contains() {
    UniversalCachePartition partition =
        new UniversalCachePartition(null, 8, null);
    TestSource source = new TestSource();
    expect(partition.contains(source), isTrue);
  }
  void test_creation() {
    expect(new UniversalCachePartition(null, 8, null), isNotNull);
  }
  void test_entrySet() {
    UniversalCachePartition partition =
        new UniversalCachePartition(null, 8, null);
    TestSource source = new TestSource();
    DartEntry entry = new DartEntry();
    partition.put(source, entry);
    Map<Source, SourceEntry> entryMap = partition.map;
    expect(entryMap.length, 1);
    Source entryKey = entryMap.keys.first;
    expect(entryKey, same(source));
    expect(entryMap[entryKey], same(entry));
  }
  void test_get() {
    UniversalCachePartition partition =
        new UniversalCachePartition(null, 8, null);
    TestSource source = new TestSource();
    expect(partition.get(source), isNull);
  }
  void test_put_noFlush() {
    UniversalCachePartition partition =
        new UniversalCachePartition(null, 8, null);
    TestSource source = new TestSource();
    DartEntry entry = new DartEntry();
    partition.put(source, entry);
    expect(partition.get(source), same(entry));
  }
  void test_remove() {
    UniversalCachePartition partition =
        new UniversalCachePartition(null, 8, null);
    TestSource source = new TestSource();
    DartEntry entry = new DartEntry();
    partition.put(source, entry);
    expect(partition.get(source), same(entry));
    partition.remove(source);
    expect(partition.get(source), isNull);
  }
  void test_setMaxCacheSize() {
    UniversalCachePartition partition = new UniversalCachePartition(
        null,
        8,
        new _UniversalCachePartitionTest_test_setMaxCacheSize());
    int size = 6;
    for (int i = 0; i < size; i++) {
      Source source = new TestSource("/test$i.dart");
      DartEntry entry = new DartEntry();
      entry.setValue(DartEntry.PARSED_UNIT, null);
      partition.put(source, entry);
      partition.accessedAst(source);
    }
    _assertNonFlushedCount(size, partition);
    int newSize = size - 2;
    partition.maxCacheSize = newSize;
    _assertNonFlushedCount(newSize, partition);
  }
  void test_size() {
    UniversalCachePartition partition =
        new UniversalCachePartition(null, 8, null);
    int size = 4;
    for (int i = 0; i < size; i++) {
      Source source = new TestSource("/test$i.dart");
      partition.put(source, new DartEntry());
      partition.accessedAst(source);
    }
    expect(partition.size(), size);
  }
  void _assertNonFlushedCount(int expectedCount,
      UniversalCachePartition partition) {
    int nonFlushedCount = 0;
    Map<Source, SourceEntry> entryMap = partition.map;
    entryMap.values.forEach((SourceEntry value) {
      if (value.getState(DartEntry.PARSED_UNIT) != CacheState.FLUSHED) {
        nonFlushedCount++;
      }
    });
    expect(nonFlushedCount, expectedCount);
  }
}


@reflectiveTest
class WorkManagerTest extends EngineTestCase {
  void test_addFirst() {
    TestSource source1 = new TestSource("/f1.dart");
    TestSource source2 = new TestSource("/f2.dart");
    WorkManager manager = new WorkManager();
    manager.add(source1, SourcePriority.UNKNOWN);
    manager.addFirst(source2, SourcePriority.UNKNOWN);
    WorkManager_WorkIterator iterator = manager.iterator();
    expect(iterator.next(), same(source2));
    expect(iterator.next(), same(source1));
  }
  void test_creation() {
    expect(new WorkManager(), isNotNull);
  }
  void test_iterator_empty() {
    WorkManager manager = new WorkManager();
    WorkManager_WorkIterator iterator = manager.iterator();
    expect(iterator.hasNext, isFalse);
    try {
      iterator.next();
      fail("Expected NoSuchElementException");
    } on NoSuchElementException catch (exception) {
    }
  }
  void test_iterator_nonEmpty() {
    TestSource source = new TestSource();
    WorkManager manager = new WorkManager();
    manager.add(source, SourcePriority.UNKNOWN);
    WorkManager_WorkIterator iterator = manager.iterator();
    expect(iterator.hasNext, isTrue);
    expect(iterator.next(), same(source));
  }
  void test_remove() {
    TestSource source1 = new TestSource("/f1.dart");
    TestSource source2 = new TestSource("/f2.dart");
    TestSource source3 = new TestSource("/f3.dart");
    WorkManager manager = new WorkManager();
    manager.add(source1, SourcePriority.UNKNOWN);
    manager.add(source2, SourcePriority.UNKNOWN);
    manager.add(source3, SourcePriority.UNKNOWN);
    manager.remove(source2);
    WorkManager_WorkIterator iterator = manager.iterator();
    expect(iterator.next(), same(source1));
    expect(iterator.next(), same(source3));
  }
  void test_toString_empty() {
    WorkManager manager = new WorkManager();
    expect(manager.toString(), isNotNull);
  }
  void test_toString_nonEmpty() {
    WorkManager manager = new WorkManager();
    manager.add(new TestSource(), SourcePriority.HTML);
    manager.add(new TestSource(), SourcePriority.LIBRARY);
    manager.add(new TestSource(), SourcePriority.NORMAL_PART);
    manager.add(new TestSource(), SourcePriority.PRIORITY_PART);
    manager.add(new TestSource(), SourcePriority.UNKNOWN);
    expect(manager.toString(), isNotNull);
  }
}


class _AnalysisCacheTest_test_setMaxCacheSize implements CacheRetentionPolicy {
  @override
  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
      RetentionPriority.LOW;
}


class _AnalysisContext_sourceChangeDuringResolution extends
    AnalysisContextForTests {
  @override
  DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
    ChangeSet changeSet = new ChangeSet();
    changeSet.changedSource(task.librarySource);
    applyChanges(changeSet);
    return super.recordResolveDartLibraryTaskResults(task);
  }
}


class _AnalysisContextImplTest_test_applyChanges_removeContainer implements
    SourceContainer {
  Source libB;
  _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB);
  @override
  bool contains(Source source) => source == libB;
}


class _UniversalCachePartitionTest_test_setMaxCacheSize implements
    CacheRetentionPolicy {
  @override
  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
      RetentionPriority.LOW;
}
