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

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

import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/standard_resolution_map.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/visitor.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/cancelable_future.dart';
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/source/package_map_resolver.dart';
import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:html/dom.dart' show Document;
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';

import '../../generated/engine_test.dart';
import '../../generated/test_support.dart';
import 'abstract_context.dart';

main() {
  defineReflectiveSuite(() {
    defineReflectiveTests(AnalysisContextImplTest);
  });
}

@reflectiveTest
class AnalysisContextImplTest extends AbstractContextTest {
  void fail_getErrors_html_some() {
    Source source = addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.dart'/>
</head></html>''');
    AnalysisErrorInfo errorInfo = context.getErrors(source);
    expect(errorInfo, isNotNull);
    List<AnalysisError> errors = errorInfo.errors;
    expect(errors, hasLength(0));
    errors = context.computeErrors(source);
    expect(errors, hasLength(2));
  }

  Future fail_implicitAnalysisEvents_removed() 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 = newSource('/a.dart', "library a; import 'b.dart';");
    Source sourceB = newSource('/b.dart', "library b;");
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(sourceA);
    context.applyChanges(changeSet);
    context.computeErrors(sourceA);
    await pumpEventQueue();
    listener.expectAnalyzed(sourceB);
    //
    // Remove the reference and ensure that the listener is told that we're no
    // longer implicitly analyzing the file.
    //
    context.setContents(sourceA, "library a;");
    context.computeErrors(sourceA);
    await pumpEventQueue();
    listener.expectNotAnalyzed(sourceB);
  }

  void fail_performAnalysisTask_importedLibraryDelete_html() {
    // NOTE: This was failing before converting to the new task model.
    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();
    context.computeErrors(htmlSource);
    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();
    context.computeErrors(htmlSource);
    AnalysisErrorInfo errors = context.getErrors(htmlSource);
    expect(_hasAnalysisErrorWithErrorSeverity(errors), isTrue,
        reason: "htmlSource has an error");
  }

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

  @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);
    Source source = newSource('/test.dart');
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(source);
    context.applyChanges(changeSet);
    expect(context.sourcesNeedingProcessing, contains(source));
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertNoMoreEvents();
    });
  }

  void test_applyChanges_add_makesExplicit() {
    Source source = newSource('/test.dart');
    // get the entry, it's not explicit
    CacheEntry entry = context.getCacheEntry(source);
    expect(entry.explicitlyAdded, isFalse);
    // add the source
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(source);
    context.applyChanges(changeSet);
    // now the entry is explicit
    expect(entry.explicitlyAdded, isTrue);
  }

  void test_applyChanges_addNewImport_invalidateLibraryCycle() {
    context.analysisOptions =
        new AnalysisOptionsImpl.from(context.analysisOptions);
    Source embedder = addSource('/a.dart', r'''
library a;
import 'b.dart';
//import 'c.dart';
''');
    addSource('/b.dart', r'''
library b;
import 'a.dart';
''');
    addSource('/c.dart', r'''
library c;
import 'b.dart';
''');
    _performPendingAnalysisTasks();
    // Add a new import into a.dart, this should invalidate its library cycle.
    // If it doesn't, we will get a task cycle exception.
    context.setContents(embedder, r'''
library a;
import 'b.dart';
import 'c.dart';
''');
    _performPendingAnalysisTasks();
    expect(context.getCacheEntry(embedder).exception, isNull);
  }

  Future test_applyChanges_change() {
    SourcesChangedListener listener = new SourcesChangedListener();
    context.onSourcesChanged.listen(listener.onData);
    expect(context.sourcesNeedingProcessing, isEmpty);
    Source source = newSource('/test.dart');
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    context.applyChanges(changeSet1);
    expect(context.sourcesNeedingProcessing, contains(source));
    Source source2 = newSource('/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);
    Source source = newSource('/test.dart');
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    context.applyChanges(changeSet1);
    expect(context.sourcesNeedingProcessing, contains(source));
    Source source2 = newSource('/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() {
    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() {
    SourcesChangedListener listener = new SourcesChangedListener();
    context.onSourcesChanged.listen(listener.onData);
    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);
    expect(libraryUnit, isNotNull);
    CompilationUnit partUnit =
        context.resolveCompilationUnit2(partSource, librarySource);
    expect(partUnit, isNotNull);
    TopLevelVariableDeclaration declaration =
        libraryUnit.declarations[0] as TopLevelVariableDeclaration;
    Element declarationElement =
        declaration.variables.variables[0].declaredElement;
    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(wereSourcesAdded: true);
      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);
    Source source = newSource('/test.dart');
    ChangeSet changeSet1 = new ChangeSet();
    changeSet1.addedSource(source);
    context.applyChanges(changeSet1);
    expect(context.sourcesNeedingProcessing, contains(source));
    Source source2 = newSource('/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_changedSource_updateModificationTime() {
    String path = resourceProvider.convertPath('/test.dart');
    File file = resourceProvider.newFile(path, 'var V = 1;');
    Source source = file.createSource();
    context.applyChanges(new ChangeSet()..addedSource(source));
    // Analyze all.
    _analyzeAll_assertFinished();
    expect(context.analysisCache.getState(source, RESOLVED_UNIT),
        CacheState.INVALID);
    // Update the file and notify the context about the change.
    resourceProvider.updateFile(path, 'var V = 2;');
    context.applyChanges(new ChangeSet()..changedSource(source));
    // The analysis results are invalidated.
    // We have seen the new contents, so 'modificationTime' is also updated.
    expect(context.analysisCache.getState(source, RESOLVED_UNIT),
        CacheState.INVALID);
    expect(
        context.getCacheEntry(source).modificationTime, file.modificationStamp);
  }

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

  void test_applyChanges_incremental_resetDriver() {
    // AnalysisContext incremental analysis has been removed
    if (context != null) return;
    throw 'is this test used by the new analysis driver?';

//    context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
//    Source source = addSource(
//        "/test.dart",
//        r'''
//main() {
//  print(42);
//}
//''');
//    _performPendingAnalysisTasks();
//    expect(context.getErrors(source).errors, hasLength(0));
//    // Update the source to have a parse error.
//    // This is an incremental change, but we always invalidate DART_ERRORS.
//    context.setContents(
//        source,
//        r'''
//main() {
//  print(42)
//}
//''');
//    AnalysisCache cache = context.analysisCache;
//    expect(cache.getValue(source, PARSE_ERRORS), hasLength(1));
//    expect(cache.getState(source, DART_ERRORS), CacheState.INVALID);
//    // Perform enough analysis to prepare inputs (is not actually tested) for
//    // the DART_ERRORS computing task, but don't compute it yet.
//    context.performAnalysisTask();
//    context.performAnalysisTask();
//    expect(cache.getState(source, DART_ERRORS), CacheState.INVALID);
//    // Update the source so that PARSE_ERRORS is empty.
//    context.setContents(
//        source,
//        r'''
//main() {
//  print(42);
//}
//''');
//    expect(cache.getValue(source, PARSE_ERRORS), hasLength(0));
//    // After full analysis DART_ERRORS should also be empty.
//    _performPendingAnalysisTasks();
//    expect(cache.getValue(source, DART_ERRORS), hasLength(0));
//    expect(context.getErrors(source).errors, hasLength(0));
  }

  void test_applyChanges_overriddenSource() {
    String content = "library test;";
    Source source = addSource("/test.dart", content);
    context.setContents(source, content);
    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));
  }

  void test_applyChanges_recompute_exportNamespace() {
    Source libSource = addSource("/lib.dart", r'''
class A {}
''');
    Source exporterSource = addSource("/exporter.dart", r'''
export 'lib.dart';
''');
    _performPendingAnalysisTasks();
    // initially: A
    {
      LibraryElement libraryElement =
          context.getResult(exporterSource, LIBRARY_ELEMENT1);
      expect(libraryElement.exportNamespace.definedNames.keys,
          unorderedEquals(['A']));
    }
    // after update: B
    context.setContents(libSource, r'''
class B {}''');
    _performPendingAnalysisTasks();
    {
      LibraryElement libraryElement =
          context.getResult(exporterSource, LIBRARY_ELEMENT1);
      expect(libraryElement.exportNamespace.definedNames.keys,
          unorderedEquals(['B']));
    }
  }

  Future test_applyChanges_remove() {
    SourcesChangedListener listener = new SourcesChangedListener();
    context.onSourcesChanged.listen(listener.onData);
    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);
    expect(libAElement, isNotNull);
    List<LibraryElement> importedLibraries = libAElement.importedLibraries;
    expect(importedLibraries, hasLength(2));
    context.computeErrors(libA);
    context.computeErrors(libB);
    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(2));
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(wereSourcesAdded: true);
      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() {
    // AnalysisContext incremental analysis has been removed
    if (context != null) return;
    throw 'is this test used by the new analysis driver?';

//    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
//    Source source = resourceProvider
//        .newFile(
//            '/test.dart',
//            r'''
//main() {
//  print(1);
//}
//''')
//        .createSource();
//    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);
//    _analyzeAll_assertFinished();
//    expect(context.getResolvedCompilationUnit2(source, source), unit);
  }

  Future test_applyChanges_removeContainer() {
    SourcesChangedListener listener = new SourcesChangedListener();
    context.onSourcesChanged.listen(listener.onData);
    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);
    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(wereSourcesAdded: true);
      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
      listener.assertNoMoreEvents();
    });
  }

  void test_applyChanges_removeUsedLibrary_addAgain() {
    String codeA = r'''
import 'b.dart';
B b = null;
''';
    String codeB = r'''
class B {}
''';
    Source a = addSource('/a.dart', codeA);
    Source b = addSource('/b.dart', codeB);
    CacheState getErrorsState(Source source) =>
        context.analysisCache.getState(source, LIBRARY_ERRORS_READY);
    _performPendingAnalysisTasks();
    expect(context.getErrors(a).errors, hasLength(0));
    // Remove b.dart - errors in a.dart are invalidated and recomputed.
    // Now a.dart has an error.
    _removeSource(b);
    expect(getErrorsState(a), CacheState.INVALID);
    _performPendingAnalysisTasks();
    expect(getErrorsState(a), CacheState.VALID);
    expect(context.getErrors(a).errors, hasLength(isPositive));
    // Add b.dart - errors in a.dart are invalidated and recomputed.
    // The reason is that a.dart adds dependencies on (not existing) b.dart
    // results in cache.
    // Now a.dart does not have errors.
    addSource('/b.dart', codeB);
    expect(getErrorsState(a), CacheState.INVALID);
    _performPendingAnalysisTasks();
    expect(getErrorsState(a), CacheState.VALID);
    expect(context.getErrors(a).errors, hasLength(0));
  }

  void test_cacheConsistencyValidator_computed_deleted() {
    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
    var stat = PerformanceStatistics.cacheConsistencyValidationStatistics;
    stat.reset();
    // Add sources.
    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
    String path1 = '/test1.dart';
    String path2 = '/test2.dart';
    Source source1 = resourceProvider.newFile(path1, '// 1-1').createSource();
    Source source2 = resourceProvider.newFile(path2, '// 2-1').createSource();
    context.applyChanges(
        new ChangeSet()..addedSource(source1)..addedSource(source2));
    // Same modification times.
    expect(
        validator.sourceModificationTimesComputed([source1, source2],
            [source1.modificationStamp, source2.modificationStamp]),
        isFalse);
    expect(stat.numOfChanged, 0);
    expect(stat.numOfRemoved, 0);
    // Add overlay
    context.setContents(source1, '// 1-2');
    expect(
        validator.sourceModificationTimesComputed(
            [source1, source2], [-1, source2.modificationStamp]),
        isFalse);
    context.setContents(source1, null);
    expect(stat.numOfChanged, 0);
    expect(stat.numOfRemoved, 0);
    // Different modification times.
    expect(
        validator.sourceModificationTimesComputed(
            [source1, source2], [-1, source2.modificationStamp]),
        isTrue);
    expect(stat.numOfChanged, 0);
    expect(stat.numOfRemoved, 1);
  }

  void test_cacheConsistencyValidator_computed_modified() {
    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
    var stat = PerformanceStatistics.cacheConsistencyValidationStatistics;
    stat.reset();
    // Add sources.
    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
    String path1 = '/test1.dart';
    String path2 = '/test2.dart';
    Source source1 = resourceProvider.newFile(path1, '// 1-1').createSource();
    Source source2 = resourceProvider.newFile(path2, '// 2-1').createSource();
    context.applyChanges(
        new ChangeSet()..addedSource(source1)..addedSource(source2));
    // Same modification times.
    expect(
        validator.sourceModificationTimesComputed([source1, source2],
            [source1.modificationStamp, source2.modificationStamp]),
        isFalse);
    expect(stat.numOfChanged, 0);
    expect(stat.numOfRemoved, 0);
    // Add overlay
    context.setContents(source1, '// 1-2');
    expect(
        validator.sourceModificationTimesComputed([source1, source2],
            [source1.modificationStamp + 1, source2.modificationStamp]),
        isFalse);
    context.setContents(source1, null);
    expect(stat.numOfChanged, 0);
    expect(stat.numOfRemoved, 0);
    // Different modification times.
    expect(
        validator.sourceModificationTimesComputed([source1, source2],
            [source1.modificationStamp + 1, source2.modificationStamp]),
        isTrue);
    expect(stat.numOfChanged, 1);
    expect(stat.numOfRemoved, 0);
  }

  void test_cacheConsistencyValidator_getSources() {
    CacheConsistencyValidator validator = context.cacheConsistencyValidator;
    // Add sources.
    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
    String path1 = '/test1.dart';
    String path2 = '/test2.dart';
    Source source1 = resourceProvider.newFile(path1, '// 1-1').createSource();
    Source source2 = resourceProvider.newFile(path2, '// 2-1').createSource();
    context.applyChanges(
        new ChangeSet()..addedSource(source1)..addedSource(source2));
    // Verify.
    expect(validator.getSourcesToComputeModificationTimes(),
        unorderedEquals([source1, source2]));
  }

  void test_computeDocumentationComment_class_block() {
    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_class_none() {
    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_class_singleLine_multiple_EOL_n() {
    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_class_singleLine_multiple_EOL_rn() {
    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_computeDocumentationComment_exportDirective_block() {
    String comment = '/** Comment */';
    Source source = addSource("/test.dart", '''
$comment
export 'dart:async';
''');
    LibraryElement libraryElement = context.computeLibraryElement(source);
    expect(libraryElement, isNotNull);
    ExportElement exportElement = libraryElement.exports[0];
    expect(context.computeDocumentationComment(exportElement), comment);
  }

  void test_computeDocumentationComment_importDirective_block() {
    String comment = '/** Comment */';
    Source source = addSource("/test.dart", '''
$comment
import 'dart:async';
''');
    LibraryElement libraryElement = context.computeLibraryElement(source);
    expect(libraryElement, isNotNull);
    ImportElement importElement = libraryElement.imports[0];
    expect(context.computeDocumentationComment(importElement), comment);
  }

  void test_computeDocumentationComment_libraryDirective_block() {
    String comment = '/** Comment */';
    Source source = addSource("/test.dart", '''
$comment
library lib;
''');
    LibraryElement libraryElement = context.computeLibraryElement(source);
    expect(libraryElement, isNotNull);
    expect(context.computeDocumentationComment(libraryElement), comment);
  }

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

  void test_computeErrors_dart_malformedCode() {
    Source source = addSource("/lib.dart", "final int , = 42;");
    List<AnalysisError> errors = context.computeErrors(source);
    expect(errors, isNotNull);
    expect(errors.length > 0, isTrue);
  }

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

  @failingTest
  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);
    // TODO(28522)
    fail("Should report that 'lib' isn't the correct URI.");
  }

  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", "<!DOCTYPE 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_computeImportedLibraries_none() {
    Source source = addSource("/test.dart", "library test;");
    expect(context.computeImportedLibraries(source), hasLength(0));
  }

  void test_computeImportedLibraries_some() {
    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() {
    Source source = addSource("/test.dart", "library lib;");
    LibraryElement element = context.computeLibraryElement(source);
    expect(element, isNotNull);
  }

  void test_computeLibraryElement_unresolvedUris() {
    Source source = addSource("/lib.dart", r'''
import 'package:foo/bar.dart';
export 'package:foo/baz.dart';
''');
    var libraryElement = context.computeLibraryElement(source);
    expect(libraryElement.imports, hasLength(2));
    expect(libraryElement.exports, hasLength(1));
    expect(libraryElement.imports[0].uri, 'package:foo/bar.dart');
    expect(libraryElement.imports[0].importedLibrary, isNull);
    expect(libraryElement.exports[0].uri, 'package:foo/baz.dart');
    expect(libraryElement.exports[0].exportedLibrary, isNull);
  }

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

  Future test_computeResolvedCompilationUnitAsync() {
    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();
    _flushAst(source);
    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() {
    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();
    _flushAst(source);
    // 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 TypeMatcher<AnalysisNotScheduledError>());
      completed = true;
    });
    return pumpEventQueue().then((_) {
      expect(completed, isTrue);
    });
  }

  Future test_computeResolvedCompilationUnitAsync_cancel() {
    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();
    _flushAst(source);
    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 TypeMatcher<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() {
    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();
    _flushAst(source);
    bool completed = false;
    CancelableFuture<CompilationUnit> future =
        context.computeResolvedCompilationUnitAsync(source, source);
    future.then((CompilationUnit unit) {
      fail('Future should have completed with error');
    }, onError: (error) {
      expect(error, new TypeMatcher<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_noCacheEntry() {
    Source librarySource = addSource("/lib.dart", "library lib;");
    Source partSource = addSource("/part.dart", "part of foo;");
    bool completed = false;
    context
        .computeResolvedCompilationUnitAsync(partSource, librarySource)
        .then((CompilationUnit unit) {
      expect(unit, isNotNull);
      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_ensureResolvedDartUnits_definingUnit_hasResolved() {
    Source source = addSource('/test.dart', '');
    LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source);
    analysisDriver.computeResult(libTarget, RESOLVED_UNIT);
    CompilationUnit unit =
        context.getCacheEntry(libTarget).getValue(RESOLVED_UNIT);
    List<CompilationUnit> units = context.ensureResolvedDartUnits(source);
    expect(units, unorderedEquals([unit]));
  }

  void test_ensureResolvedDartUnits_definingUnit_notResolved() {
    Source source = addSource('/test.dart', '');
    LibrarySpecificUnit libTarget = new LibrarySpecificUnit(source, source);
    analysisDriver.computeResult(libTarget, RESOLVED_UNIT);
    // flush
    context
        .getCacheEntry(libTarget)
        .setState(RESOLVED_UNIT, CacheState.FLUSHED);
    // schedule recomputing
    List<CompilationUnit> units = context.ensureResolvedDartUnits(source);
    expect(units, isNull);
    // should be the next result to compute
    TargetedResult nextResult = context.dartWorkManager.getNextResult();
    expect(nextResult.target, libTarget);
    expect(nextResult.result, RESOLVED_UNIT);
  }

  void test_ensureResolvedDartUnits_partUnit_hasResolved() {
    Source libSource1 = addSource('/lib1.dart', r'''
library lib;
part 'part.dart';
''');
    Source libSource2 = addSource('/lib2.dart', r'''
library lib;
part 'part.dart';
''');
    Source partSource = addSource('/part.dart', r'''
part of lib;
''');
    LibrarySpecificUnit partTarget1 =
        new LibrarySpecificUnit(libSource1, partSource);
    LibrarySpecificUnit partTarget2 =
        new LibrarySpecificUnit(libSource2, partSource);
    analysisDriver.computeResult(partTarget1, RESOLVED_UNIT);
    analysisDriver.computeResult(partTarget2, RESOLVED_UNIT);
    CompilationUnit unit1 =
        context.getCacheEntry(partTarget1).getValue(RESOLVED_UNIT);
    CompilationUnit unit2 =
        context.getCacheEntry(partTarget2).getValue(RESOLVED_UNIT);
    List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource);
    expect(units, unorderedEquals([unit1, unit2]));
  }

  void test_ensureResolvedDartUnits_partUnit_notResolved() {
    Source libSource1 = addSource('/lib1.dart', r'''
library lib;
part 'part.dart';
''');
    Source libSource2 = addSource('/lib2.dart', r'''
library lib;
part 'part.dart';
''');
    Source partSource = addSource('/part.dart', r'''
part of lib;
''');
    LibrarySpecificUnit partTarget1 =
        new LibrarySpecificUnit(libSource1, partSource);
    LibrarySpecificUnit partTarget2 =
        new LibrarySpecificUnit(libSource2, partSource);
    analysisDriver.computeResult(partTarget1, RESOLVED_UNIT);
    analysisDriver.computeResult(partTarget2, RESOLVED_UNIT);
    // flush
    context
        .getCacheEntry(partTarget1)
        .setState(RESOLVED_UNIT, CacheState.FLUSHED);
    context
        .getCacheEntry(partTarget2)
        .setState(RESOLVED_UNIT, CacheState.FLUSHED);
    // schedule recomputing
    List<CompilationUnit> units = context.ensureResolvedDartUnits(partSource);
    expect(units, isNull);
    // should be the next result to compute
    TargetedResult nextResult = context.dartWorkManager.getNextResult();
    expect(nextResult.target, anyOf(partTarget1, partTarget2));
    expect(nextResult.result, RESOLVED_UNIT);
  }

  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_flushResolvedUnit_updateFile_dontNotify() {
    String oldCode = '';
    String newCode = r'''
import 'dart:async';
''';
    String path = resourceProvider.convertPath('/test.dart');
    Source source = resourceProvider.newFile(path, oldCode).createSource();
    context.applyChanges(new ChangeSet()..addedSource(source));
    context.resolveCompilationUnit2(source, source);
    // Flush all results units.
    context.analysisCache.flush((target, result) {
      if (target.source == source) {
        return RESOLVED_UNIT_RESULTS.contains(result);
      }
      return false;
    });
    // Update the file, but don't notify the context.
    resourceProvider.updateFile(path, newCode);
    // Driver must detect that the file was changed and recover.
    CompilationUnit unit = context.resolveCompilationUnit2(source, source);
    expect(unit, isNotNull);
  }

  void test_flushResolvedUnit_updateFile_dontNotify2() {
    String oldCode = r'''
main() {}
''';
    String newCode = r'''
import 'dart:async';
main() {}
''';
    String path = resourceProvider.convertPath('/test.dart');
    Source source = resourceProvider.newFile(path, oldCode).createSource();
    context.applyChanges(new ChangeSet()..addedSource(source));
    context.resolveCompilationUnit2(source, source);
    // Flush all results units.
    context.analysisCache.flush((target, result) {
      if (target.source == source) {
        if (target.source == source) {
          return RESOLVED_UNIT_RESULTS.contains(result);
        }
      }
      return false;
    });
    // Update the file, but don't notify the context.
    resourceProvider.updateFile(path, newCode);
    // Driver must detect that the file was changed and recover.
    CompilationUnit unit = context.resolveCompilationUnit2(source, source);
    expect(unit, isNotNull);
  }

  void test_flushSingleResolvedUnit_instanceField() {
    _checkFlushSingleResolvedUnit('class C { var x = 0; }',
        (CompilationUnitElement unitElement, String reason) {
      expect(unitElement.types, hasLength(1), reason: reason);
      ClassElement cls = unitElement.types[0];
      expect(cls.fields, hasLength(1), reason: reason);
      expect(cls.fields[0].type.toString(), 'int', reason: reason);
      expect(cls.accessors, hasLength(2), reason: reason);
      expect(cls.accessors[0].isGetter, isTrue, reason: reason);
      expect(cls.accessors[0].returnType.toString(), 'int', reason: reason);
      expect(cls.accessors[1].isSetter, isTrue, reason: reason);
      expect(cls.accessors[1].returnType.toString(), 'void', reason: reason);
      expect(cls.accessors[1].parameters, hasLength(1), reason: reason);
      expect(cls.accessors[1].parameters[0].type.toString(), 'int',
          reason: reason);
    });
  }

  void test_flushSingleResolvedUnit_instanceGetter() {
    _checkFlushSingleResolvedUnit('''
abstract class B {
  int get x;
}
class C extends B {
  get x => null;
}
''', (CompilationUnitElement unitElement, String reason) {
      expect(unitElement.types, hasLength(2), reason: reason);
      ClassElement cls = unitElement.types[1];
      expect(cls.name, 'C', reason: reason);
      expect(cls.accessors, hasLength(1), reason: reason);
      expect(cls.accessors[0].returnType.toString(), 'int', reason: reason);
      expect(cls.fields, hasLength(1), reason: reason);
      expect(cls.fields[0].type.toString(), 'int', reason: reason);
    });
  }

  void test_flushSingleResolvedUnit_instanceMethod() {
    _checkFlushSingleResolvedUnit('''
abstract class B {
  int f(String s);
}
class C extends B {
  f(s) => null;
}
''', (CompilationUnitElement unitElement, String reason) {
      expect(unitElement.types, hasLength(2), reason: reason);
      ClassElement cls = unitElement.types[1];
      expect(cls.name, 'C', reason: reason);
      expect(cls.methods, hasLength(1), reason: reason);
      expect(cls.methods[0].returnType.toString(), 'int', reason: reason);
      expect(cls.methods[0].parameters, hasLength(1), reason: reason);
      expect(cls.methods[0].parameters[0].type.toString(), 'String',
          reason: reason);
    });
  }

  void test_flushSingleResolvedUnit_instanceSetter() {
    _checkFlushSingleResolvedUnit('''
abstract class B {
  set x(int value);
}
class C extends B {
  set x(value) {}
}
''', (CompilationUnitElement unitElement, String reason) {
      expect(unitElement.types, hasLength(2), reason: reason);
      ClassElement cls = unitElement.types[1];
      expect(cls.name, 'C', reason: reason);
      expect(cls.accessors, hasLength(1), reason: reason);
      expect(cls.accessors[0].returnType.toString(), 'void', reason: reason);
      expect(cls.accessors[0].parameters, hasLength(1), reason: reason);
      expect(cls.accessors[0].parameters[0].type.toString(), 'int',
          reason: reason);
      expect(cls.fields, hasLength(1), reason: reason);
      expect(cls.fields[0].type.toString(), 'int', reason: reason);
    });
  }

  void test_flushSingleResolvedUnit_staticField() {
    _checkFlushSingleResolvedUnit('class C { static var x = 0; }',
        (CompilationUnitElement unitElement, String reason) {
      expect(unitElement.types, hasLength(1), reason: reason);
      ClassElement cls = unitElement.types[0];
      expect(cls.fields, hasLength(1), reason: reason);
      expect(cls.fields[0].type.toString(), 'int', reason: reason);
      expect(cls.accessors, hasLength(2), reason: reason);
      expect(cls.accessors[0].isGetter, isTrue, reason: reason);
      expect(cls.accessors[0].returnType.toString(), 'int', reason: reason);
      expect(cls.accessors[1].isSetter, isTrue, reason: reason);
      expect(cls.accessors[1].returnType.toString(), 'void', reason: reason);
      expect(cls.accessors[1].parameters, hasLength(1), reason: reason);
      expect(cls.accessors[1].parameters[0].type.toString(), 'int',
          reason: reason);
    });
  }

  void test_flushSingleResolvedUnit_topLevelVariable() {
    _checkFlushSingleResolvedUnit('var x = 0;',
        (CompilationUnitElement unitElement, String reason) {
      expect(unitElement.topLevelVariables, hasLength(1), reason: reason);
      expect(unitElement.topLevelVariables[0].type.toString(), 'int',
          reason: reason);
      expect(unitElement.accessors, hasLength(2), reason: reason);
      expect(unitElement.accessors[0].isGetter, isTrue, reason: reason);
      expect(unitElement.accessors[0].returnType.toString(), 'int',
          reason: reason);
      expect(unitElement.accessors[1].isSetter, isTrue, reason: reason);
      expect(unitElement.accessors[1].returnType.toString(), 'void',
          reason: reason);
      expect(unitElement.accessors[1].parameters, hasLength(1), reason: reason);
      expect(unitElement.accessors[1].parameters[0].type.toString(), 'int',
          reason: reason);
    });
  }

  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_notOverridden() {
    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_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_getDeclaredVariables() {
    expect(context.declaredVariables, isNotNull);
  }

  void test_getElement() {
    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;");
    var errorInfo = context.getErrors(source);
    expect(errorInfo, isNotNull);
    List<AnalysisError> errors = errorInfo.errors;
    expect(errors, hasLength(0));
    context.computeErrors(source);
    errors = errorInfo.errors;
    expect(errors, hasLength(0));
  }

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

  void test_getErrors_html_none() {
    Source source = addSource("/test.html", "<html></html>");
    AnalysisErrorInfo errorInfo = context.getErrors(source);
    expect(errorInfo, isNotNull);
    List<AnalysisError> errors = errorInfo.errors;
    expect(errors, hasLength(0));
    context.computeErrors(source);
    errors = errorInfo.errors;
    expect(errors, hasLength(0));
  }

  void test_getHtmlFilesReferencing_html() {
    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.parseHtmlDocument(htmlSource);
    result = context.getHtmlFilesReferencing(secondHtmlSource);
    expect(result, hasLength(0));
  }

  void test_getHtmlFilesReferencing_library() {
    Source htmlSource = addSource("/test.html", r'''
<!DOCTYPE html>
<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);
    List<Source> result = context.getHtmlFilesReferencing(librarySource);
    expect(result, hasLength(0));
    // Indirectly force the data to be computed.
    context.computeErrors(htmlSource);
    result = context.getHtmlFilesReferencing(librarySource);
    expect(result, hasLength(1));
    expect(result[0], htmlSource);
  }

  void test_getHtmlFilesReferencing_part() {
    Source htmlSource = addSource("/test.html", r'''
<!DOCTYPE html>
<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));
    // Indirectly force the data to be computed.
    context.computeErrors(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", "");
    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_doesNotImportHtml() {
    Source source = addSource("/test.dart", r'''
main() {}''');
    context.computeLibraryElement(source);
    List<Source> sources = context.launchableClientLibrarySources;
    expect(sources, isEmpty);
  }

  void test_getLaunchableClientLibrarySources_importsHtml_explicitly() {
    List<Source> sources = context.launchableClientLibrarySources;
    expect(sources, isEmpty);
    Source source = addSource("/test.dart", r'''
import 'dart:html';
main() {}''');
    context.computeLibraryElement(source);
    sources = context.launchableClientLibrarySources;
    expect(sources, unorderedEquals([source]));
  }

  void test_getLaunchableClientLibrarySources_importsHtml_implicitly() {
    List<Source> sources = context.launchableClientLibrarySources;
    expect(sources, isEmpty);
    addSource('/a.dart', r'''
import 'dart:html';
''');
    Source source = addSource("/test.dart", r'''
import 'a.dart';
main() {}''');
    _analyzeAll_assertFinished();
    sources = context.launchableClientLibrarySources;
    expect(sources, unorderedEquals([source]));
  }

  void test_getLaunchableClientLibrarySources_importsHtml_implicitly2() {
    List<Source> sources = context.launchableClientLibrarySources;
    expect(sources, isEmpty);
    addSource('/a.dart', r'''
export 'dart:html';
''');
    Source source = addSource("/test.dart", r'''
import 'a.dart';
main() {}''');
    _analyzeAll_assertFinished();
    sources = context.launchableClientLibrarySources;
    expect(sources, unorderedEquals([source]));
  }

  void test_getLaunchableServerLibrarySources() {
    expect(context.launchableServerLibrarySources, isEmpty);
    Source source = addSource("/test.dart", "main() {}");
    context.computeLibraryElement(source);
    expect(context.launchableServerLibrarySources, unorderedEquals([source]));
  }

  void test_getLaunchableServerLibrarySources_importsHtml_explicitly() {
    Source source = addSource("/test.dart", r'''
import 'dart:html';
main() {}
''');
    context.computeLibraryElement(source);
    expect(context.launchableServerLibrarySources, isEmpty);
  }

  void test_getLaunchableServerLibrarySources_importsHtml_implicitly() {
    addSource("/imports_html.dart", r'''
import 'dart:html';
''');
    addSource("/test.dart", r'''
import 'imports_html.dart';
main() {}''');
    _analyzeAll_assertFinished();
    expect(context.launchableServerLibrarySources, isEmpty);
  }

  void test_getLaunchableServerLibrarySources_noMain() {
    Source source = addSource("/test.dart", '');
    context.computeLibraryElement(source);
    expect(context.launchableServerLibrarySources, isEmpty);
  }

  void test_getLibrariesContaining() {
    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() {
    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() {
    Source htmlSource = addSource("/test.html", r'''
<!DOCTYPE html>
<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);
    // Indirectly force the data to be computed.
    context.computeErrors(htmlSource);
    List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource);
    expect(result, hasLength(1));
    expect(result[0], librarySource);
  }

  void test_getLibrariesReferencedFromHtml_none() {
    Source htmlSource = addSource("/test.html", r'''
<html><head>
<script type='application/dart' src='test.js'/>
</head></html>''');
    addSource("/test.dart", "library lib;");
    context.parseHtmlDocument(htmlSource);
    List<Source> result = context.getLibrariesReferencedFromHtml(htmlSource);
    expect(result, hasLength(0));
  }

  void test_getLibraryElement() {
    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_getLibrarySources_inSDK() {
    Source source = addSource('/test.dart', r'''
import 'dart:async';
Stream S = null;
''');
    LibraryElement testLibrary = context.computeLibraryElement(source);
    // prepare "Stream" ClassElement
    ClassElement streamElement;
    {
      CompilationUnitElement testUnit = testLibrary.definingCompilationUnit;
      InterfaceType streamType = testUnit.topLevelVariables[0].type;
      streamElement = streamType.element;
    }
    // must be from SDK context
    AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
    expect(sdkContext, streamElement.context);
    Source intSource = streamElement.source;
    // must be in the "async" library - SDK context
    {
      List<Source> coreLibraries = sdkContext.getLibrariesContaining(intSource);
      expect(coreLibraries, hasLength(1));
      Source coreSource = coreLibraries[0];
      expect(coreSource.isInSystemLibrary, isTrue);
      expect(coreSource.shortName, 'async.dart');
    }
    // must be in the "async" library - main context
    {
      List<Source> coreLibraries = context.getLibrariesContaining(intSource);
      expect(coreLibraries, hasLength(1));
      Source coreSource = coreLibraries[0];
      expect(coreSource.isInSystemLibrary, isTrue);
      expect(coreSource.shortName, 'async.dart');
    }
  }

  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() {
    Source source = addSource("/test.dart", "class A {}");
    LibraryElement library = context.computeLibraryElement(source);
    expect(library, isNotNull);
    Namespace namespace = context.getPublicNamespace(library);
    expect(namespace, isNotNull);
    EngineTestCase.assertInstanceOf(
        (obj) => obj is ClassElement, ClassElement, namespace.get("A"));
  }

  void test_getResolvedCompilationUnit_library() {
    Source source = addSource("/lib.dart", "library libb;");
    LibraryElement library = context.computeLibraryElement(source);
    context.computeErrors(source); // Force the resolved unit to be built.
    expect(context.getResolvedCompilationUnit(source, library), isNotNull);
    context.setContents(source, "library lib;");
    expect(context.getResolvedCompilationUnit(source, library), isNull);
  }

  void test_getResolvedCompilationUnit_library_null() {
    Source source = addSource("/lib.dart", "library lib;");
    expect(context.getResolvedCompilationUnit(source, null), isNull);
  }

  void test_getResolvedCompilationUnit_source_dart() {
    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_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_handleContentsChanged() {
    ContentCache contentCache = new ContentCache();
    context.contentCache = contentCache;
    String oldContents = 'foo() {}';
    String newContents = 'bar() {}';
    // old contents
    Source source = addSource("/test.dart", oldContents);
    _analyzeAll_assertFinished();
    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
    // new contents
    contentCache.setContents(source, newContents);
    context.handleContentsChanged(source, oldContents, newContents, true);
    // there is some work to do
    AnalysisResult analysisResult = context.performAnalysisTask();
    expect(analysisResult.changeNotices, isNotNull);
  }

  void test_handleContentsChanged_noOriginal_sameAsFile() {
    ContentCache contentCache = new ContentCache();
    context.contentCache = contentCache;
    // Add the source.
    String code = 'foo() {}';
    Source source = addSource("/test.dart", code);
    _analyzeAll_assertFinished();
    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
    // Update the content cache, and notify that we updated the source.
    // We pass "null" as "originalContents" because the was no one.
    contentCache.setContents(source, code);
    context.handleContentsChanged(source, null, code, true);
    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
  }

  void test_handleContentsChanged_noOriginal_sameAsFile_butFileUpdated() {
    ContentCache contentCache = new ContentCache();
    context.contentCache = contentCache;
    // Add the source.
    String oldCode = 'foo() {}';
    String newCode = 'bar() {}';
    var file = resourceProvider.newFile('/test.dart', oldCode);
    Source source = file.createSource();
    context.applyChanges(new ChangeSet()..addedSource(source));
    _analyzeAll_assertFinished();
    expect(context.getResolvedCompilationUnit2(source, source), isNotNull);
    // Test for the race condition.
    // 1. Update the file.
    // 2. Update the content cache.
    // 3. Notify the context, and because this is the first time when we
    //    update the content cache, we don't know "originalContents".
    // The source must be invalidated, because it has different contents now.
    resourceProvider.updateFile(
        resourceProvider.convertPath('/test.dart'), newCode);
    contentCache.setContents(source, newCode);
    context.handleContentsChanged(source, null, newCode, true);
    expect(context.getResolvedCompilationUnit2(source, source), isNull);
  }

  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 = newSource('/a.dart', "library a; import 'b.dart';");
    Source sourceB = newSource('/b.dart', "library b;");
    ChangeSet changeSet = new ChangeSet();
    changeSet.addedSource(sourceA);
    context.applyChanges(changeSet);
    context.computeErrors(sourceA);
    await pumpEventQueue();
    listener.expectAnalyzed(sourceB);
  }

  void test_isClientLibrary_dart() {
    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_isClientLibrary_unknown() {
    Source source = newSource("/test.dart");
    expect(context.isClientLibrary(source), isFalse);
  }

  void test_isServerLibrary_dart() {
    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_isServerLibrary_unknown() {
    Source source = newSource("/test.dart");
    expect(context.isServerLibrary(source), isFalse);
  }

  void test_onResultInvalidated_removeSource() {
    Source source = addSource('/test.dart', 'main() {}');
    _analyzeAll_assertFinished();
    // listen for changes
    bool listenerInvoked = false;
    context.onResultChanged(RESOLVED_UNIT).listen((ResultChangedEvent event) {
      Source eventSource = event.target.source;
      expect(event.wasComputed, isFalse);
      expect(event.wasInvalidated, isTrue);
      expect(event.descriptor, RESOLVED_UNIT);
      expect(eventSource, source);
      listenerInvoked = true;
    });
    // apply changes
    expect(listenerInvoked, false);
    context.applyChanges(new ChangeSet()..removedSource(source));
    // verify
    expect(listenerInvoked, isTrue);
  }

  void test_onResultInvalidated_setContents() {
    Source source = addSource('/test.dart', 'main() {}');
    _analyzeAll_assertFinished();
    // listen for changes
    bool listenerInvoked = false;
    context.onResultChanged(RESOLVED_UNIT).listen((ResultChangedEvent event) {
      Source eventSource = event.target.source;
      expect(event.wasComputed, isFalse);
      expect(event.wasInvalidated, isTrue);
      expect(event.descriptor, RESOLVED_UNIT);
      expect(eventSource, source);
      listenerInvoked = true;
    });
    // apply changes
    expect(listenerInvoked, false);
    context.setContents(source, 'class B {}');
    // verify
    expect(listenerInvoked, isTrue);
  }

  void test_parseCompilationUnit_errors() {
    Source source = addSource("/lib.dart", "library {");
    CompilationUnit compilationUnit = context.parseCompilationUnit(source);
    expect(compilationUnit, isNotNull);
    var errorInfo = context.getErrors(source);
    expect(errorInfo, isNotNull);
    List<AnalysisError> errors = errorInfo.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);
    AnalysisErrorInfo errorInfo = context.getErrors(source);
    expect(errorInfo, isNotNull);
    expect(errorInfo.errors, hasLength(0));
  }

  void test_parseCompilationUnit_nonExistentSource() {
    Source source = newSource('/test.dart');
    resourceProvider.deleteFile(resourceProvider.convertPath('/test.dart'));
    try {
      context.parseCompilationUnit(source);
      fail("Expected AnalysisException because file does not exist");
    } on AnalysisException {
      // Expected result
    }
  }

  void test_parseHtmlDocument() {
    Source source = addSource("/lib.html", "<!DOCTYPE html><html></html>");
    Document document = context.parseHtmlDocument(source);
    expect(document, isNotNull);
  }

  void test_parseHtmlUnit_resolveDirectives() {
    Source libSource = addSource("/lib.dart", r'''
library lib;
class ClassA {}''');
    Source source = addSource("/lib.html", r'''
<!DOCTYPE html>
<html>
<head>
  <script type='application/dart'>
    import 'lib.dart';
    ClassA v = null;
  </script>
</head>
<body>
</body>
</html>''');
    Document document = context.parseHtmlDocument(source);
    expect(document, isNotNull);
    List<DartScript> scripts = context.computeResult(source, DART_SCRIPTS);
    expect(scripts, hasLength(1));
    CompilationUnit unit = context.computeResult(scripts[0], PARSED_UNIT);
    ImportDirective importNode = unit.directives[0] as ImportDirective;
    expect(importNode.uriContent, isNotNull);
    expect(importNode.uriSource, libSource);
  }

  void test_performAnalysisTask_addPart() {
    Source libSource = addSource("/lib.dart", r'''
library lib;
part 'part.dart';''');
    // run all tasks without part
    _analyzeAll_assertFinished();
    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)),
        isTrue,
        reason: "lib has errors");
    // 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]));
    expect(_hasAnalysisErrorWithErrorSeverity(context.getErrors(libSource)),
        isFalse,
        reason: "lib doesn't have errors");
    expect(
        context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
        reason: "part resolved");
  }

  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 3");
    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, partSource), 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, partSource), 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() {
    Source source = _addSourceWithException('test.dart');
    // 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() {
    Source source = _addSourceWithException('test.html');
    // 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)),
        isFalse,
        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();
    context.computeErrors(htmlSource);
//    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.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
        reason: "libB resolved 2");
    // TODO (danrubel) commented out to fix red bots
//    context.computeErrors(htmlSource);
//    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 and analyze
    _removeSource(libBSource);
    _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_interruptBy_setContents() {
    Source sourceA = addSource('/a.dart', r'''
library expectedToFindSemicolon
''');
    // Analyze to the point where some of the results stop depending on
    // the source content.
    LibrarySpecificUnit unitA = new LibrarySpecificUnit(sourceA, sourceA);
    for (int i = 0; i < 10000; i++) {
      context.performAnalysisTask();
      if (context.getResult(unitA, RESOLVED_UNIT3) != null) {
        break;
      }
    }
    // Update the source.
    // This should invalidate all the results and also reset the driver.
    context.setContents(sourceA, "library semicolonWasAdded;");
    expect(context.getResult(unitA, RESOLVED_UNIT3), isNull);
    expect(analysisDriver.currentWorkOrder, isNull);
    // Continue analysis.
    _analyzeAll_assertFinished();
    expect(context.getErrors(sourceA).errors, isEmpty);
  }

  void test_performAnalysisTask_IOException() {
    TestSource source = _addSourceWithException2("/test.dart", "library test;");
    source.generateExceptionOnRead = false;
    _analyzeAll_assertFinished();
    expect(source.readCount, 2);
    _changeSource(source, "");
    source.generateExceptionOnRead = true;
    _analyzeAll_assertFinished();
    expect(source.readCount, 5);
  }

  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 = <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_performAnalysisTask_onResultChanged() {
    Set<String> libraryElementUris = new Set<String>();
    Set<String> parsedUnitUris = new Set<String>();
    Set<String> resolvedUnitUris = new Set<String>();
    // listen
    context.onResultChanged(LIBRARY_ELEMENT).listen((event) {
      expect(event.wasComputed, isTrue);
      expect(event.wasInvalidated, isFalse);
      Source librarySource = event.target;
      libraryElementUris.add(librarySource.uri.toString());
    });
    context.onResultChanged(PARSED_UNIT).listen((event) {
      expect(event.wasComputed, isTrue);
      expect(event.wasInvalidated, isFalse);
      Source source = event.target;
      parsedUnitUris.add(source.uri.toString());
    });
    context.onResultChanged(RESOLVED_UNIT).listen((event) {
      expect(event.wasComputed, isTrue);
      expect(event.wasInvalidated, isFalse);
      LibrarySpecificUnit target = event.target;
      Source librarySource = target.library;
      resolvedUnitUris.add(librarySource.uri.toString());
    });
    // analyze
    addSource('/test.dart', 'main() {}');
    _analyzeAll_assertFinished();
    // verify
    String testUri = resourceProvider
        .getFile(resourceProvider.convertPath('/test.dart'))
        .toUri()
        .toString();
    expect(libraryElementUris, contains(testUri));
    expect(parsedUnitUris, contains(testUri));
    expect(resolvedUnitUris, contains(testUri));
  }

  void test_performAnalysisTask_switchPackageVersion() {
    // version 1
    resourceProvider.newFile('/pkgs/crypto-1/lib/crypto.dart', r'''
library crypto;
part 'src/hash_utils.dart';
''');
    resourceProvider.newFile('/pkgs/crypto-1/lib/src/hash_utils.dart', r'''
part of crypto;
const _MASK_8 = 0xff;
''');
    // version 2
    resourceProvider.newFile('/pkgs/crypto-2/lib/crypto.dart', r'''
library crypto;
part 'src/hash_utils.dart';
''');
    resourceProvider.newFile('/pkgs/crypto-2/lib/src/hash_utils.dart', r'''
part of crypto;
const _MASK_8 = 0xff;
''');
    // use version 1
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'crypto': [resourceProvider.getFolder('/pkgs/crypto-1/lib')]
      })
    ]);
    // analyze
    addSource("/test.dart", r'''
import 'package:crypto/crypto.dart';
''');
    _analyzeAll_assertFinished();
    // use version 2
    context.sourceFactory = new SourceFactory(<UriResolver>[
      sdkResolver,
      resourceResolver,
      new PackageMapUriResolver(resourceProvider, {
        'crypto': [resourceProvider.getFolder('/pkgs/crypto-2/lib')]
      })
    ]);
    _analyzeAll_assertFinished();
    _assertNoExceptions();
  }

  @failingTest // TODO(paulberry): Remove the annotation when dartbug.com/28515 is fixed.
  void test_resolveCompilationUnit_existingElementModel() {
    prepareAnalysisContext(new AnalysisOptionsImpl());
    Source source = addSource('/test.dart', r'''
library test;

String topLevelVariable;
int get topLevelGetter => 0;
void set topLevelSetter(int value) {}
String topLevelFunction(int i) => '';

typedef String FunctionTypeAlias(int i);

enum EnumeratedType {Invalid, Valid}

class A {
  const A(x);
}

@A(const [(_) => null])
class ClassOne {
  int instanceField;
  static int staticField;

  ClassOne();
  ClassOne.named();

  int get instanceGetter => 0;
  static String get staticGetter => '';

  void set instanceSetter(int value) {}
  static void set staticSetter(int value) {}

  int instanceMethod(int first, [int second = 0]) {
    int localVariable;
    int localFunction(String s) {}
  }
  static String staticMethod(int first, {int second: 0}) => '';
}

class ClassTwo {
  // Implicit no-argument constructor
}

void topLevelFunctionWithLocalFunction() {
  void localFunction({bool b: false}) {}
}

void functionWithGenericFunctionTypedParam/*<S>*/(/*=T*/ pf/*<T>*/(/*=T*/ e)) {}
void functionWithClosureAsDefaultParam([x = () => null]) {}
''');
    context.resolveCompilationUnit2(source, source);
    LibraryElement firstElement = context.computeLibraryElement(source);
    _ElementGatherer gatherer = new _ElementGatherer();
    firstElement.accept(gatherer);

    CacheEntry entry =
        context.analysisCache.get(new LibrarySpecificUnit(source, source));
    entry.setState(RESOLVED_UNIT1, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT2, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT3, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT4, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT5, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT6, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT7, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT8, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT9, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
    entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);

    context.resolveCompilationUnit2(source, source);
    LibraryElement secondElement = context.computeLibraryElement(source);
    _ElementComparer comparer = new _ElementComparer(gatherer.elements);
    secondElement.accept(comparer);
    comparer.expectNoDifferences();
  }

  void test_resolveCompilationUnit_import_relative() {
    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);
    expect(compilationUnit, isNotNull);
    LibraryElement library =
        resolutionMap.elementDeclaredByCompilationUnit(compilationUnit).library;
    List<LibraryElement> importedLibraries = library.importedLibraries;
    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
  }

  void test_resolveCompilationUnit_import_relative_cyclic() {
    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);
    expect(compilationUnit, isNotNull);
    LibraryElement library =
        resolutionMap.elementDeclaredByCompilationUnit(compilationUnit).library;
    List<LibraryElement> importedLibraries = library.importedLibraries;
    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
  }

//  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_resolveCompilationUnit_library() {
    Source source = addSource("/lib.dart", "library lib;");
    LibraryElement library = context.computeLibraryElement(source);
    CompilationUnit compilationUnit =
        context.resolveCompilationUnit(source, library);
    expect(compilationUnit, isNotNull);
    expect(compilationUnit.declaredElement, isNotNull);
  }

  void test_resolveCompilationUnit_source() {
    Source source = addSource("/lib.dart", "library lib;");
    CompilationUnit compilationUnit =
        context.resolveCompilationUnit2(source, source);
    expect(compilationUnit, isNotNull);
  }

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

  void test_setAnalysisPriorityOrder() {
    int priorityCount = 4;
    List<Source> sources = <Source>[];
    for (int index = 0; index < priorityCount; index++) {
      sources.add(addSource("/lib.dart$index", ""));
    }
    context.analysisPriorityOrder = sources;
    expect(_getPriorityOrder(context).length, priorityCount);
  }

  void test_setAnalysisPriorityOrder_empty() {
    context.analysisPriorityOrder = <Source>[];
  }

  void test_setAnalysisPriorityOrder_nonEmpty() {
    List<Source> sources = <Source>[];
    sources.add(addSource("/lib.dart", "library lib;"));
    context.analysisPriorityOrder = sources;
  }

  void test_setAnalysisPriorityOrder_resetAnalysisDriver() {
    Source source = addSource('/lib.dart', 'library lib;');
    // start analysis
    context.performAnalysisTask();
    expect(context.driver.currentWorkOrder, isNotNull);
    // set priority sources, AnalysisDriver is reset
    context.analysisPriorityOrder = <Source>[source];
    expect(context.driver.currentWorkOrder, isNull);
    // analysis continues
    context.performAnalysisTask();
    expect(context.driver.currentWorkOrder, isNotNull);
  }

  Future test_setChangedContents_libraryWithPart() {
    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
    context.analysisOptions = options;
    SourcesChangedListener listener = new SourcesChangedListener();
    context.onSourcesChanged.listen(listener.onData);
    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.resolveCompilationUnit(librarySource, element);
    expect(unit, isNotNull);
    int offset = oldCode.indexOf("int a") + 4;
    String newCode = r'''
library lib;
part 'part.dart';
int ya = 0;''';
    context.setChangedContents(librarySource, newCode, offset, 0, 1);
    expect(context.getContents(librarySource).data, newCode);
    expect(
        context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertNoMoreEvents();
    });
  }

  void test_setChangedContents_notResolved() {
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.from(context.analysisOptions);
    context.analysisOptions = options;
    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);
  }

  Future test_setContents_libraryWithPart() {
    SourcesChangedListener listener = new SourcesChangedListener();
    context.onSourcesChanged.listen(listener.onData);
    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);
    expect(
        context.getResolvedCompilationUnit2(partSource, librarySource), isNull);
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(changedSources: [librarySource]);
      listener.assertNoMoreEvents();
    });
  }

  void test_setContents_null() {
    // AnalysisContext incremental analysis has been removed
    if (context != null) return;
    throw 'is this test used by the new analysis driver?';

//    Source librarySource = addSource(
//        "/lib.dart",
//        r'''
//library lib;
//int a = 0;''');
//    context.setContents(librarySource, '// different');
//    context.computeLibraryElement(librarySource);
//    context.setContents(librarySource, null);
//    expect(context.getResolvedCompilationUnit2(librarySource, librarySource),
//        isNull);
  }

  void test_setContents_unchanged_consistentModificationTime() {
    String contents = "// foo";
    Source source = addSource("/test.dart", contents);
    context.setContents(source, 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_updateAnalysis() {
    expect(context.sourcesNeedingProcessing, isEmpty);
    Source source = newSource('/test.dart');
    AnalysisDelta delta = new AnalysisDelta();
    delta.setAnalysisLevel(source, AnalysisLevel.ALL);
    context.applyAnalysisDelta(delta);
    expect(context.sourcesNeedingProcessing, contains(source));
    delta = new AnalysisDelta();
    delta.setAnalysisLevel(source, AnalysisLevel.NONE);
    context.applyAnalysisDelta(delta);
    expect(context.sourcesNeedingProcessing.contains(source), isFalse);
  }

  void test_validateCacheConsistency_deletedFile() {
    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
    String pathA = resourceProvider.convertPath('/a.dart');
    String pathB = resourceProvider.convertPath('/b.dart');
    var fileA = resourceProvider.newFile(pathA, "");
    var fileB = resourceProvider.newFile(pathB, "import 'a.dart';");
    Source sourceA = fileA.createSource();
    Source sourceB = fileB.createSource();
    context.applyChanges(
        new ChangeSet()..addedSource(sourceA)..addedSource(sourceB));
    // analyze everything
    _analyzeAll_assertFinished();
    // delete a.dart
    resourceProvider.deleteFile(pathA);
    // analysis should eventually stop
    _analyzeAll_assertFinished();
  }

  void xtest_performAnalysisTask_stress() {
    int maxCacheSize = 4;
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.from(context.analysisOptions);
    context.analysisOptions = options;
    int sourceCount = maxCacheSize + 2;
    List<Source> sources = <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");
    }
  }

  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 assert that it was enough.
   */
  void _analyzeAll_assertFinished([int maxIterations = 512]) {
    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 _assertNoExceptions() {
    MapIterator<AnalysisTarget, CacheEntry> iterator = analysisCache.iterator();
    String exceptionsStr = '';
    while (iterator.moveNext()) {
      CaughtException exception = iterator.value.exception;
      if (exception != null) {
        AnalysisTarget target = iterator.key;
        exceptionsStr +=
            '============= key: $target   source: ${target.source}\n';
        exceptionsStr += exception.toString();
        exceptionsStr += '\n';
      }
    }
    if (exceptionsStr.isNotEmpty) {
      fail(exceptionsStr);
    }
  }

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

  void _checkFlushSingleResolvedUnit(String code,
      void validate(CompilationUnitElement unitElement, String reason)) {
    prepareAnalysisContext(new AnalysisOptionsImpl());
    String path = resourceProvider.convertPath('/test.dart');
    Source source = resourceProvider.newFile(path, code).createSource();
    context.applyChanges(new ChangeSet()..addedSource(source));
    CompilationUnitElement unitElement =
        context.resolveCompilationUnit2(source, source).declaredElement;
    validate(unitElement, 'initial state');
    for (ResultDescriptor<CompilationUnit> descriptor
        in RESOLVED_UNIT_RESULTS) {
      context.analysisCache.flush(
          (target, result) => target.source == source && result == descriptor);
      context.computeResult(
          new LibrarySpecificUnit(source, source), descriptor);
      validate(unitElement, 'after flushing $descriptor');
    }
  }

  /**
   * 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;
  }

  void _flushAst(Source source) {
    CacheEntry entry =
        context.getCacheEntry(new LibrarySpecificUnit(source, source));
    entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
  }

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

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

  void _removeSource(Source source) {
    resourceProvider.deleteFile(source.fullName);
    ChangeSet changeSet = new ChangeSet();
    changeSet.removedSource(source);
    context.applyChanges(changeSet);
  }

  /**
   * 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;
}

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

/**
 * A visitor that can be used to compare all of the elements in an element model
 * with a previously created map of elements. The class [ElementGatherer] can be
 * used to create the map of elements.
 */
class _ElementComparer extends GeneralizingElementVisitor {
  /**
   * The previously created map of elements.
   */
  final Map<Element, Element> previousElements;

  /**
   * The number of elements that were found to have been overwritten.
   */
  int overwrittenCount = 0;

  /**
   * A buffer to which a description of the overwritten elements will be written.
   */
  final StringBuffer buffer = new StringBuffer();

  /**
   * Initialize a newly created visitor.
   */
  _ElementComparer(this.previousElements);

  /**
   * Expect that no differences were found, causing the test to fail if that
   * wasn't the case.
   */
  void expectNoDifferences() {
    if (overwrittenCount > 0) {
      fail('Found $overwrittenCount overwritten elements.$buffer');
    }
  }

  @override
  void visitElement(Element element) {
    Element previousElement = previousElements[element];
    bool ok = _expectedIdentical(element)
        ? identical(previousElement, element)
        : previousElement == element;
    if (!ok) {
      if (overwrittenCount == 0) {
        buffer.writeln();
      }
      overwrittenCount++;
      buffer.writeln('Overwritten element:');
      Element currentElement = element;
      while (currentElement != null) {
        buffer.write('  ');
        buffer.writeln(currentElement.toString());
        currentElement = currentElement.enclosingElement;
      }
    }
    super.visitElement(element);
  }

  /**
   * Return `true` if the given [element] should be the same as the previous
   * element at the same position in the element model.
   */
  static bool _expectedIdentical(Element element) {
    while (element != null) {
      if (element is ConstructorElement ||
          element is MethodElement ||
          element is FunctionElement &&
              element.enclosingElement is CompilationUnitElement) {
        return false;
      }
      element = element.enclosingElement;
    }
    return true;
  }
}

/**
 * A visitor that can be used to collect all of the elements in an element
 * model.
 */
class _ElementGatherer extends GeneralizingElementVisitor {
  /**
   * The map in which the elements are collected. The value of each key is the
   * key itself.
   */
  Map<Element, Element> elements = new HashMap<Element, Element>();

  /**
   * Initialize the visitor.
   */
  _ElementGatherer();

  @override
  void visitElement(Element element) {
    elements[element] = element;
    super.visitElement(element);
  }
}
