// 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.

library engine.engine_test;

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

import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/context/cache.dart' show CacheEntry;
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/java_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/task/model.dart' hide AnalysisTask, WorkManager;
import 'package:html/dom.dart' show Document;
import 'package:path/path.dart' as pathos;
import 'package:typed_mock/typed_mock.dart';
import 'package:unittest/unittest.dart';
import 'package:watcher/src/utils.dart';

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

main() {
  initializeTestEnvironment();
  // Tests for the classes used in both old and new analysis implementations.
  runReflectiveTests(SourcesChangedEventTest);
  // Tests for the classes used in the old analysis implementation.
  if (!AnalysisEngine.instance.useTaskModel) {
    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(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);
  }

  /**
   * Verify that if multiple Source objects refer to the same file via
   * different URIs, they are treated as separate entries in the cache.
   */
  void test_lookup_distinguishes_uris() {
    CachePartition partition =
        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
    JavaFile file = new JavaFile('baz.dart');
    Source source1 = new FileBasedSource(file);
    Source source2 =
        new FileBasedSource(file, Uri.parse('package:foo/baz.dart'));
    Source source3 =
        new FileBasedSource(file, Uri.parse('package:bar/baz.dart'));
    DartEntry entry1 = new DartEntry();
    DartEntry entry2 = new DartEntry();
    DartEntry entry3 = new DartEntry();
    cache.put(source1, entry1);
    cache.put(source2, entry2);
    cache.put(source3, entry3);
    expect(cache.get(source1), same(entry1));
    expect(cache.get(source2), same(entry2));
    expect(cache.get(source3), same(entry3));
  }

  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_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.from(_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(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(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    _context.applyChanges(changeSet1);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    Source source2 =
        new FileBasedSource(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(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    _context.applyChanges(changeSet1);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    Source source2 =
        new FileBasedSource(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.oldContextWithCore();
    _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.oldContextWithCore();
    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(FileUtilities2.createFile("/test.dart"));
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    _context.applyChanges(changeSet1);
    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
    Source source2 =
        new FileBasedSource(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.oldContextWithCore();
    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();
    });
  }

  /**
   * IDEA uses the following scenario:
   * 1. Add overlay.
   * 2. Change overlay.
   * 3. If the contents of the document buffer is the same as the contents
   *    of the file, remove overlay.
   * So, we need to try to use incremental resolution for removing overlays too.
   */
  void test_applyChanges_remove_incremental() {
    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
    Source source = resourceProvider
        .newFile(
            '/test.dart',
            r'''
main() {
  print(1);
}
''')
        .createSource();
    _context = AnalysisContextFactory.oldContextWithCore();
    _context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
    _context.applyChanges(new ChangeSet()..addedSource(source));
    // remember compilation unit
    _analyzeAll_assertFinished();
    CompilationUnit unit = _context.getResolvedCompilationUnit2(source, source);
    // add overlay
    _context.setContents(
        source,
        r'''
main() {
  print(12);
}
''');
    _analyzeAll_assertFinished();
    expect(_context.getResolvedCompilationUnit2(source, source), unit);
    // remove overlay
    _context.setContents(source, null);
    _context.validateCacheConsistency();
    _analyzeAll_assertFinished();
    expect(_context.getResolvedCompilationUnit2(source, source), unit);
  }

  Future test_applyChanges_removeContainer() {
    _context = AnalysisContextFactory.oldContextWithCore();
    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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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 {
      // Expected
    }
  }

  void test_computeResolvableCompilationUnit_html_exception() {
    Source source = _addSource("/lib.html", "<html></html>");
    try {
      _context.computeResolvableCompilationUnit(source);
      fail("Expected AnalysisException");
    } on AnalysisException {
      // 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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    expect(_context.declaredVariables, isNotNull);
  }

  void test_getElement() {
    _context = AnalysisContextFactory.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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_getResolvedCompilationUnit_library() {
    _context = AnalysisContextFactory.oldContextWithCore();
    _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.oldContextWithCore();
    _sourceFactory = _context.sourceFactory;
    Source source = _addSource("/lib.dart", "library lib;");
    expect(_context.getResolvedCompilationUnit(source, null), isNull);
  }

  void test_getResolvedCompilationUnit_source_dart() {
    _context = AnalysisContextFactory.oldContextWithCore();
    _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.oldContextWithCore();
    _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.oldContextWithCore();
    _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_getSourcesWithFullName() {
    String filePath = '/foo/lib/file.dart';
    List<Source> expected = <Source>[];
    ChangeSet changeSet = new ChangeSet();

    TestSourceWithUri source1 =
        new TestSourceWithUri(filePath, Uri.parse('file://$filePath'));
    expected.add(source1);
    changeSet.addedSource(source1);

    TestSourceWithUri source2 =
        new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart'));
    expected.add(source2);
    changeSet.addedSource(source2);

    _context.applyChanges(changeSet);
    expect(
        _context.getSourcesWithFullName(filePath), unorderedEquals(expected));
  }

  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());
  }

  Future test_implicitAnalysisEvents_added() async {
    AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
    _context.implicitAnalysisEvents.listen(listener.onData);
    //
    // Create a file that references an file that is not explicitly being
    // analyzed and fully analyze it. Ensure that the listener is told about
    // the implicitly analyzed file.
    //
    Source sourceA = _addSource('/a.dart', "library a; import 'b.dart';");
    Source sourceB = _createSource('/b.dart', "library b;");
    _context.computeErrors(sourceA);
    await pumpEventQueue();
    listener.expectAnalyzed(sourceB);
  }

  void test_isClientLibrary_dart() {
    _context = AnalysisContextFactory.oldContextWithCore();
    _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.oldContextWithCore();
    _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 {
      // 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(FileUtilities2.createFile("/test.dart"));
    try {
      _context.parseCompilationUnit(source);
      fail("Expected AnalysisException because file does not exist");
    } on AnalysisException {
      // 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_getContentException_dart() {
    // add source that throw an exception on "get content"
    Source source = new _Source_getContent_throwException('test.dart');
    {
      ChangeSet changeSet = new ChangeSet();
      changeSet.addedSource(source);
      _context.applyChanges(changeSet);
    }
    // prepare errors
    _analyzeAll_assertFinished();
    List<AnalysisError> errors = _context.getErrors(source).errors;
    // validate errors
    expect(errors, hasLength(1));
    AnalysisError error = errors[0];
    expect(error.source, same(source));
    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
  }

  void test_performAnalysisTask_getContentException_html() {
    // add source that throw an exception on "get content"
    Source source = new _Source_getContent_throwException('test.html');
    {
      ChangeSet changeSet = new ChangeSet();
      changeSet.addedSource(source);
      _context.applyChanges(changeSet);
    }
    // prepare errors
    _analyzeAll_assertFinished();
    List<AnalysisError> errors = _context.getErrors(source).errors;
    // validate errors
    expect(errors, hasLength(1));
    AnalysisError error = errors[0];
    expect(error.source, same(source));
    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
  }

  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");
    // TODO (danrubel) commented out to fix red bots
//    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
//    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.oldContextWithCore();
    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.oldContextWithCore();
    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.oldContextWithCore();
    _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.oldContextWithCore();
    _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.from(_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.oldContextWithCoreAndOptions(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.oldContextWithCore();
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.from(_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.oldContextWithCore();
    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.oldContextWithCore();
    _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.oldContextWithCore();
    _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(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.from(_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(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);
  }

  Source _createSource(String fileName, String contents) {
    Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
    _context.setContents(source, contents);
    return source;
  }

  /**
   * 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.enableStrictCallChecks = booleanValue;
      options.enableSuperMixins = booleanValue;
      options.generateImplicitErrors = booleanValue;
      options.generateSdkErrors = booleanValue;
      options.hint = booleanValue;
      options.incremental = booleanValue;
      options.preserveComments = booleanValue;
      options.strongMode = booleanValue;
      AnalysisOptionsImpl copy = new AnalysisOptionsImpl.from(options);
      expect(copy.analyzeFunctionBodies, options.analyzeFunctionBodies);
      expect(copy.cacheSize, options.cacheSize);
      expect(copy.dart2jsHint, options.dart2jsHint);
      expect(copy.enableStrictCallChecks, options.enableStrictCallChecks);
      expect(copy.enableSuperMixins, options.enableSuperMixins);
      expect(copy.generateImplicitErrors, options.generateImplicitErrors);
      expect(copy.generateSdkErrors, options.generateSdkErrors);
      expect(copy.hint, options.hint);
      expect(copy.incremental, options.incremental);
      expect(copy.preserveComments, options.preserveComments);
      expect(copy.strongMode, options.strongMode);
    }
  }

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

  void test_cacheSize() {
    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_dart2jsHint() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.dart2jsHint;
    options.dart2jsHint = value;
    expect(options.dart2jsHint, value);
  }

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

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

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

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

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

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

  void test_strongMode() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    bool value = !options.strongMode;
    options.strongMode = value;
    expect(options.strongMode, 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 = AnalysisContextFactory.contextWithCore();
    AnalysisTask task = new AnalysisTask_test_perform_exception(context);
    task.perform(new TestTaskVisitor<Object>());
  }
}

/**
 * A listener used to gather the [ImplicitAnalysisEvent]s that are produced
 * during analysis.
 */
class AnalyzedSourcesListener {
  /**
   * The events that have been gathered.
   */
  List<ImplicitAnalysisEvent> actualEvents = <ImplicitAnalysisEvent>[];

  /**
   * The sources that are being implicitly analyzed.
   */
  List<Source> analyzedSources = <Source>[];

  /**
   * Assert that the given source is currently being implicitly analyzed.
   */
  void expectAnalyzed(Source source) {
    expect(analyzedSources, contains(source));
  }

  /**
   * Assert that the given source is not currently being implicitly analyzed.
   */
  void expectNotAnalyzed(Source source) {
    expect(analyzedSources, isNot(contains(source)));
  }

  /**
   * Record that the given event was produced.
   */
  void onData(ImplicitAnalysisEvent event) {
    actualEvents.add(event);
    if (event.isAnalyzed) {
      analyzedSources.add(event.source);
    } else {
      analyzedSources.remove(event.source);
    }
  }
}

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(SourceEntry.CONTENT_ERRORS, <AnalysisError>[
      new AnalysisError(source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT,
          ['exception details'])
    ]);
    entry.setValue(DartEntry.SCAN_ERRORS, <AnalysisError>[
      new AnalysisError(
          source, 0, 0, ScannerErrorCode.UNTERMINATED_STRING_LITERAL)
    ]);
    entry.setValue(DartEntry.PARSE_ERRORS, <AnalysisError>[
      new AnalysisError(source, 0, 0, ParserErrorCode.ABSTRACT_CLASS_MEMBER)
    ]);
    entry.setValueInLibrary(
        DartEntry.RESOLUTION_ERRORS, source, <AnalysisError>[
      new AnalysisError(
          source, 0, 0, CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)
    ]);
    entry.setValueInLibrary(
        DartEntry.VERIFICATION_ERRORS, source, <AnalysisError>[
      new AnalysisError(
          source, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
    ]);
    entry.setValueInLibrary(DartEntry.HINTS, source,
        <AnalysisError>[new AnalysisError(source, 0, 0, HintCode.DEAD_CODE)]);
    expect(entry.allErrors, hasLength(6));
  }

  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 ArgumentError for RESOLUTION_ERRORS");
    } on ArgumentError {
      // Expected
    }
  }

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

  void test_getStateInLibrary_invalid_element() {
    DartEntry entry = new DartEntry();
    try {
      entry.getStateInLibrary(DartEntry.ELEMENT, new TestSource());
      fail("Expected ArgumentError for ELEMENT");
    } on ArgumentError {
      // 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 ArgumentError for RESOLUTION_ERRORS");
    } on ArgumentError {}
  }

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

  void test_getValueInLibrary_invalid_element() {
    DartEntry entry = new DartEntry();
    try {
      entry.getValueInLibrary(DartEntry.ELEMENT, new TestSource());
      fail("Expected ArgumentError for ELEMENT");
    } on ArgumentError {
      // 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 ArgumentError for ELEMENT");
    } on ArgumentError {
      // 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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_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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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.CONTENT_ERRORS), 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 ArgumentError for ELEMENT");
    } on ArgumentError {
      // Expected
    }
  }

  void test_setState_invalid_resolutionErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.setState(DartEntry.RESOLUTION_ERRORS, CacheState.FLUSHED);
      fail("Expected ArgumentError for RESOLUTION_ERRORS");
    } on ArgumentError {
      // 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 {}
  }

  void test_setState_invalid_verificationErrors() {
    DartEntry entry = new DartEntry();
    try {
      entry.setState(DartEntry.VERIFICATION_ERRORS, CacheState.FLUSHED);
      fail("Expected ArgumentError for VERIFICATION_ERRORS");
    } on ArgumentError {
      // 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(null, 0, 0, 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(null, 0, 0, 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(
          null, 0, 0, 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(
          null, 0, 0, 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(null, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
    ]);
  }

  DartEntry _entryWithValidState([Source firstLibrary, Source secondLibrary]) {
    DartEntry entry = new DartEntry();
    entry.setValue(SourceEntry.CONTENT, null);
    entry.setValue(SourceEntry.CONTENT_ERRORS, 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.CONTENT_ERRORS), 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(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(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(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(FileUtilities2.createFile("/test.dart"));
    changeSet.addedSource(librarySource);
    Source unusedSource =
        new FileBasedSource(FileUtilities2.createFile("/unused.dart"));
    changeSet.addedSource(unusedSource);
    Source partSource =
        new FileBasedSource(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(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 = AnalysisContextFactory.contextWithCore();
    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(source, 0, 0, ParserErrorCode.EXPECTED_TOKEN, [";"])
    ]);
    entry.setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
      new AnalysisError(source, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
    ]);
    entry.setValue(HtmlEntry.HINTS,
        <AnalysisError>[new AnalysisError(source, 0, 0, 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(null, 0, 0, HintCode.DEAD_CODE)]);
  }

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

  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(null, 0, 0, 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(null, 0, 0, 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(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(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;
}

class MockSourceFactory extends SourceFactory {
  MockSourceFactory() : super([]);
  Source resolveUri(Source containingSource, String containedUri) {
    throw new JavaIOException();
  }
}

@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 = AnalysisContextFactory.contextWithCore();
    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 = AnalysisContextFactory.contextWithCore();
    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 = AnalysisContextFactory.contextWithCore();
    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 = AnalysisContextFactory.contextWithCore();
    ParseDartTask task = _createParseTask(context, source, content);
    task.perform(
        new ParseDartTaskTestTV_perform_validateDirectives(context, source));
  }

  void test_resolveDirective_dartUri() {
    GatheringErrorListener listener = new GatheringErrorListener();
    ImportDirective directive = AstFactory.importDirective3('dart:core', null);
    AnalysisContext context = AnalysisContextFactory.contextWithCore();
    Source source =
        ParseDartTask.resolveDirective(context, null, directive, listener);
    expect(source, isNotNull);
  }

  void test_resolveDirective_exception() {
    GatheringErrorListener listener = new GatheringErrorListener();
    ImportDirective directive = AstFactory.importDirective3('dart:core', null);
    AnalysisContext context = AnalysisContextFactory.contextWithCore();
    context.sourceFactory = new MockSourceFactory();
    Source source =
        ParseDartTask.resolveDirective(context, null, directive, listener);
    expect(source, isNull);
    expect(listener.errors, hasLength(1));
  }

  /**
   * 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 = AnalysisContextFactory.contextWithCore();
    context.setContents(source, contents);
    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 {
      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 = AnalysisContextFactory.contextWithCore();
    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 = AnalysisContextFactory.contextWithCore();
    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 = AnalysisContextFactory.contextWithCore();
    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_LIST,
      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_LIST,
      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
  AnalysisCache get analysisCache {
    fail("Unexpected invocation of analysisCache");
    return null;
  }

  @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<AnalysisTarget> get explicitTargets {
    fail("Unexpected invocation of visitCacheItems");
    return null;
  }

  @override
  List<Source> get htmlSources {
    fail("Unexpected invocation of getHtmlSources");
    return null;
  }

  @override
  Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents {
    fail("Unexpected invocation of analyzedSources");
    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
  LibraryResolverFactory get libraryResolverFactory {
    fail("Unexpected invocation of getLibraryResolverFactory");
    return null;
  }

  @override
  List<Source> get librarySources {
    fail("Unexpected invocation of getLibrarySources");
    return null;
  }

  @override
  String get name {
    fail("Unexpected invocation of name");
    return null;
  }

  @override
  set name(String value) {
    fail("Unexpected invocation of name");
  }

  @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<AnalysisTarget> get priorityTargets {
    fail("Unexpected invocation of visitCacheItems");
    return null;
  }

  @override
  CachePartition get privateAnalysisCachePartition {
    fail("Unexpected invocation of privateAnalysisCachePartition");
    return null;
  }

  @override
  ResolverVisitorFactory get resolverVisitorFactory {
    fail("Unexpected invocation of getResolverVisitorFactory");
    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
  List<Source> get sources {
    fail("Unexpected invocation of sources");
    return null;
  }

  @override
  AnalysisContextStatistics get statistics {
    fail("Unexpected invocation of getStatistics");
    return null;
  }

  @override
  TypeProvider get typeProvider {
    fail("Unexpected invocation of getTypeProvider");
    return null;
  }

  @override
  void set typeProvider(TypeProvider typeProvider) {
    fail("Unexpected invocation of set typeProvider");
  }

  @override
  TypeSystem get typeSystem {
    fail("Unexpected invocation of getTypeSystem");
    return null;
  }

  @override
  TypeResolverVisitorFactory get typeResolverVisitorFactory {
    fail("Unexpected invocation of getTypeResolverVisitorFactory");
    return null;
  }

  @override
  void addListener(AnalysisListener listener) {
    fail("Unexpected invocation of addListener");
  }

  @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
  @deprecated
  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
  Object computeResult(AnalysisTarget target, ResultDescriptor result) {
    fail("Unexpected invocation of computeResult");
    return null;
  }

  @override
  void dispose() {
    fail("Unexpected invocation of dispose");
  }

  @override
  List<CompilationUnit> ensureResolvedDartUnits(Source source) {
    fail("Unexpected invocation of ensureResolvedDartUnits");
    return null;
  }

  @override
  bool exists(Source source) {
    fail("Unexpected invocation of exists");
    return false;
  }

  @override
  CacheEntry getCacheEntry(AnalysisTarget target) {
    fail("Unexpected invocation of visitCacheItems");
    return null;
  }

  @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
  @deprecated
  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
  ChangeNoticeImpl getNotice(Source source) {
    fail("Unexpected invocation of getNotice");
    return null;
  }

  @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
  @deprecated
  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
    fail("Unexpected invocation of getResolvedHtmlUnit");
    return null;
  }

  @override
  Object getResult(AnalysisTarget target, ResultDescriptor result) {
    fail("Unexpected invocation of getResult");
    return null;
  }

  @override
  List<Source> getSourcesWithFullName(String path) {
    fail("Unexpected invocation of getSourcesWithFullName");
    return null;
  }

  @override
  bool handleContentsChanged(
      Source source, String originalContents, String newContents, bool notify) {
    fail("Unexpected invocation of handleContentsChanged");
    return false;
  }

  @override
  void invalidateLibraryHints(Source librarySource) {
    fail("Unexpected invocation of invalidateLibraryHints");
  }

  @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
  Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
    fail("Unexpected invocation of onResultComputed");
    return null;
  }

  @override
  CompilationUnit parseCompilationUnit(Source source) {
    fail("Unexpected invocation of parseCompilationUnit");
    return null;
  }

  @override
  Document parseHtmlDocument(Source source) {
    fail("Unexpected invocation of parseHtmlDocument");
    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
  @deprecated
  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
  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
    fail("Unexpected invocation of shouldErrorsBeAnalyzed");
    return false;
  }

  @override
  void test_flushAstStructures(Source source) {
    fail("Unexpected invocation of test_flushAstStructures");
  }

  @override
  bool validateCacheConsistency() {
    fail("Unexpected invocation of validateCacheConsistency");
    return false;
  }

  @deprecated
  @override
  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
      DataDescriptor rowDesc, CacheState state)) {
    fail("Unexpected invocation of visitCacheItems");
  }

  @override
  void visitContentCache(ContentCacheVisitor visitor) {
    fail("Unexpected invocation of visitContentCache");
  }
}

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
  @deprecated
  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
  @deprecated
  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_LIST;
  }
}

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

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_LIST;
  }
}

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

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

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

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_LIST;
  }
}

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_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
  @deprecated
  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
  @deprecated
  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 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 {}
  }

  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 _Source_getContent_throwException extends NonExistingSource {
  _Source_getContent_throwException(String name)
      : super(name, pathos.toUri(name), UriKind.FILE_URI);

  @override
  TimestampedData<String> get contents {
    throw 'Read error';
  }

  @override
  bool exists() => true;
}

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