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

library analyzer.test.src.context.context_test;

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

import 'package:analyzer/dart/ast/ast.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/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/package_map_resolver.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/element/element.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_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/task/dart.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
import 'package:unittest/unittest.dart';
import 'package:watcher/src/utils.dart';

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

main() {
  initializeTestEnvironment();
  runReflectiveTests(AnalysisContextImplTest);
  runReflectiveTests(LimitedInvalidateTest);
}

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

  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].element;
    TopLevelVariableDeclaration use =
        partUnit.declarations[0] as TopLevelVariableDeclaration;
    Element useElement =
        (use.variables.variables[0].initializer as SimpleIdentifier)
            .staticElement;
    expect((useElement as PropertyAccessorElement).variable,
        same(declarationElement));
    return pumpEventQueue().then((_) {
      listener.assertEvent(wereSourcesAdded: true);
      listener.assertEvent(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 = '/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_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);
    ApplyChangesStatus changesStatus = context.applyChanges(changeSet);
    expect(changesStatus.hasChanges, isFalse);
    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) as LibraryElement;
      expect(libraryElement.exportNamespace.definedNames.keys,
          unorderedEquals(['A']));
    }
    // after update: B
    context.setContents(
        libSource,
        r'''
class B {}''');
    _performPendingAnalysisTasks();
    {
      LibraryElement libraryElement =
          context.getResult(exporterSource, LIBRARY_ELEMENT1) as LibraryElement;
      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(1));
    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() {
    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_cacheConsistencyValidator_computed() {
    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));
    // Same modification times.
    expect(
        validator.sourceModificationTimesComputed([source1, source2],
            [source1.modificationStamp, source2.modificationStamp]),
        isFalse);
    // Add overlay
    context.setContents(source1, '// 1-2');
    expect(
        validator.sourceModificationTimesComputed([source1, source2],
            [source1.modificationStamp + 1, source2.modificationStamp]),
        isFalse);
    context.setContents(source1, null);
    // Different modification times.
    expect(
        validator.sourceModificationTimesComputed([source1, source2],
            [source1.modificationStamp + 1, source2.modificationStamp]),
        isTrue);
  }

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

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

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

  void test_computeErrors_html_none() {
    Source source = addSource("/test.html", "<!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_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 isInstanceOf<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 isInstanceOf<FutureCanceledError>());
      completed = true;
    });
    expect(completed, isFalse);
    expect(context.pendingFutureSources_forTesting, isNotEmpty);
    future.cancel();
    expect(context.pendingFutureSources_forTesting, isEmpty);
    return pumpEventQueue().then((_) {
      expect(completed, isTrue);
      expect(context.pendingFutureSources_forTesting, isEmpty);
    });
  }

  Future test_computeResolvedCompilationUnitAsync_dispose() {
    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 isInstanceOf<AnalysisNotScheduledError>());
      completed = true;
    });
    expect(completed, isFalse);
    expect(context.pendingFutureSources_forTesting, isNotEmpty);
    // Disposing of the context should cause all pending futures to complete
    // with AnalysisNotScheduled, so that no clients are left hanging.
    context.dispose();
    expect(context.pendingFutureSources_forTesting, isEmpty);
    return pumpEventQueue().then((_) {
      expect(completed, isTrue);
      expect(context.pendingFutureSources_forTesting, isEmpty);
    });
  }

  Future test_computeResolvedCompilationUnitAsync_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_configurationData() {
    var key = new ResultDescriptor('test_key', 'TEST_DEFAULT');
    var testData = ['test', 'data'];
    context.setConfigurationData(key, testData);
    expect(context.getConfigurationData(key), testData);
    var unusedKey = new ResultDescriptor('unused_key', 'UNUSED_DEFAULT');
    expect(context.getConfigurationData(unusedKey), 'UNUSED_DEFAULT');
  }

  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 = '/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 = '/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_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_incremental_newContentsNull() {
    context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
    ContentCache contentCache = new ContentCache();
    context.contentCache = contentCache;
    // old contents
    String oldContents = 'foo() {}';
    Source source = resourceProvider.getFile('/test.dart').createSource();
    contentCache.setContents(source, oldContents);
    expect(context.computeLibraryElement(source), isNotNull);
    // new contents
    String newContents = null;
    contentCache.setContents(source, newContents);
    context.handleContentsChanged(source, oldContents, newContents, true);
    expect(context.getLibraryElement(source), isNull);
  }

  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('/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('/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.source, 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");
    if (context.analysisOptions.finerGrainedInvalidation) {
      expect(
          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
          reason: "library changed 2");
      expect(
          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
          reason: "part changed 2");
    } else {
      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");
    if (context.analysisOptions.finerGrainedInvalidation) {
      expect(
          context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
          reason: "library changed 3");
      expect(
          context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
          reason: "part changed 3");
    } else {
      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();
    if (context.analysisOptions.finerGrainedInvalidation) {
      expect(source.readCount, 7);
    } else {
      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
    expect(libraryElementUris, contains('file:///test.dart'));
    expect(parsedUnitUris, contains('file:///test.dart'));
    expect(resolvedUnitUris, contains('file:///test.dart'));
  }

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

  void test_resolveCompilationUnit_existingElementModel() {
    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 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
}
''');
    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_UNIT13, 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 = compilationUnit.element.library;
    List<LibraryElement> importedLibraries = library.importedLibraries;
    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
    List<LibraryElement> visibleLibraries = library.visibleLibraries;
    assertNamedElements(visibleLibraries,
        ["dart.core", "dart.async", "dart.math", "libA", "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 = compilationUnit.element.library;
    List<LibraryElement> importedLibraries = library.importedLibraries;
    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
    List<LibraryElement> visibleLibraries = library.visibleLibraries;
    assertNamedElements(visibleLibraries,
        ["dart.core", "dart.async", "dart.math", "libA", "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.element, 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.cacheSize = 42;
    options.dart2jsHint = false;
    options.hint = false;
    context.analysisOptions = options;
    AnalysisOptions result = context.analysisOptions;
    expect(result.cacheSize, options.cacheSize);
    expect(result.dart2jsHint, options.dart2jsHint);
    expect(result.hint, options.hint);
  }

  void test_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();
    options.incremental = true;
    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);
    options.incremental = true;
    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() {
    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_deletedSource() {
    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
    var fileA = resourceProvider.newFile('/a.dart', "");
    var fileB = resourceProvider.newFile('/b.dart', "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('/a.dart');
    // analysis should eventually stop
    _analyzeAll_assertFinished();
  }

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

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

@reflectiveTest
class LimitedInvalidateTest extends AbstractContextTest {
  @override
  void setUp() {
    super.setUp();
    AnalysisOptionsImpl options =
        new AnalysisOptionsImpl.from(context.analysisOptions);
    options.incremental = true;
    options.finerGrainedInvalidation = true;
    context.analysisOptions = options;
  }

  void test_class_addMethod_useAsHole_inTopLevelVariable() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
var B = A.foo;
''');
    Source c = addSource(
        '/c.dart',
        r'''
import 'b.dart';
var C = B;
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(1));
    // Update a.dart: add A.foo.
    //   'B' in b.dart is invalid, because 'B' references 'foo'
    //   c.dart is invalid, because 'C' references 'B'
    context.setContents(
        a,
        r'''
class A {
  static void foo(int p) {}
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);

    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);

    _assertValidForDependentLibrary(c);
    _assertInvalid(c, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(c, RESOLVED_UNIT4);
  }

  void test_class_addMethod_useClass() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
class B extends A {
  foo() {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
B b = null;
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove add A.bar.
    //   b.dart is valid, because though it uses A, it has the same element.
    context.setContents(
        a,
        r'''
class A {}
class B extends A {
  foo() {}
  bar() {}
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_class_constructor_named_changeName() {
    // Update a.dart: change A.named() to A.named2().
    //   b.dart is invalid, because it references A.named().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A.named();
}
''',
        r'''
class A {
  A.named2();
}
''',
        r'''
import 'a.dart';
main() {
  new A.named();
}
''');
  }

  void test_class_constructor_named_parameters_add() {
    // Update a.dart: add a new parameter to A.named().
    //   b.dart is invalid, because it references A.named().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A.named();
}
''',
        r'''
class A {
  A.named(int p);
}
''',
        r'''
import 'a.dart';
main() {
  new A.named();
}
''');
  }

  void test_class_constructor_named_parameters_change_usedSuper() {
    // Update a.dart: change A.named().
    //   b.dart is invalid, because it references A.named().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A.named(int a);
}
''',
        r'''
class A {
  A.named(String a);
}
''',
        r'''
import 'a.dart';
class B extends A {
  B() : super.named(42);
}
''');
  }

  void test_class_constructor_named_parameters_remove() {
    // Update a.dart: remove a new parameter of A.named().
    //   b.dart is invalid, because it references A.named().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A.named(int p);
}
''',
        r'''
class A {
  A.named();
}
''',
        r'''
import 'a.dart';
main() {
  new A.named();
}
''');
  }

  void test_class_constructor_named_remove_notUsed() {
    // Update a.dart: remove A.foo().
    //   b.dart is valid, because it does not reference A.foo().
    _verifyTwoLibrariesAllValid(
        r'''
class A {
  A.foo();
  A.bar();
}
''',
        r'''
class A {
  A.bar();
}
''',
        r'''
import 'a.dart';
main() {
  new A.bar();
}
''');
  }

  void test_class_constructor_named_remove_used() {
    // Update a.dart: remove A.named().
    //   b.dart is invalid, because it references A.named().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A.named();
}
''',
        r'''
class A {
}
''',
        r'''
import 'a.dart';
main() {
  new A.named();
}
''');
  }

  void test_class_constructor_unnamed_parameters_change_notUsedSuper() {
    // Update a.dart: change A().
    //   Resolution of b.dart is valid, because it does not reference A().
    //   Hints and verify errors are invalid, because it extends A.
    // TODO(scheglov) we could keep valid hints and verify errors,
    // because only constructor is changed - this cannot add/remove
    // inherited unimplemented members.
    _verifyTwoLibrariesInvalidHintsVerifyErrors(
        r'''
class A {
  A(int a);
  A.named(int a);
}
''',
        r'''
class A {
  A(String a);
  A.named(int a);
}
''',
        r'''
import 'a.dart';
class B extends A {
  B() : super.named(42);
}
''');
  }

  void test_class_constructor_unnamed_parameters_change_usedSuper() {
    // Update a.dart: change A().
    //   b.dart is invalid, because it references A().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A(int a);
}
''',
        r'''
class A {
  A(String a);
}
''',
        r'''
import 'a.dart';
class B extends A {
  B() : super(42);
}
''');
  }

  void test_class_constructor_unnamed_parameters_remove() {
    // Update a.dart: change A().
    //   b.dart is invalid, because it references A().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A(int a, int b);
}
''',
        r'''
class A {
  A(int a);
}
''',
        r'''
import 'a.dart';
main() {
  new A(1, 2);
}
''');
  }

  void test_class_constructor_unnamed_remove_notUsed() {
    // Update a.dart: remove A().
    //   b.dart is invalid, because it instantiates A.
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A();
  A.named();
}
''',
        r'''
class A {
  A.named();
}
''',
        r'''
import 'a.dart';
main() {
  new A.named();
}
''');
  }

  void test_class_constructor_unnamed_remove_used() {
    // Update a.dart: remove A().
    //   b.dart is invalid, because it references A().
    _verifyTwoLibrariesInvalidatesResolution(
        r'''
class A {
  A();
}
''',
        r'''
class A {
}
''',
        r'''
import 'a.dart';
main() {
  new A();
}
''');
  }

  void test_class_method_change_notUsed() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  foo() {}
  bar() {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main(A a) {
  a.foo();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A.bar, add A.bar2.
    //   b.dart is valid, because it doesn't references 'bar' or 'bar2'.
    context.setContents(
        a,
        r'''
class A {
  foo() {}
  bar2() {}
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_class_method_change_notUsed_throughSubclass_extends() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  foo() {}
  bar() {}
}
class B extends A {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main(B b) {
  a.foo();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A.bar, add A.bar2.
    //   b.dart is valid, because it doesn't references 'bar' or 'bar2'.
    context.setContents(
        a,
        r'''
class A {
  foo() {}
  bar2() {}
}
class B extends A {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_class_method_definedInSuper_sameLibrary() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  m() {}
}
class B extends A {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main(B b) {
  b.m();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: change A.m
    //   This makes B changed.
    //   b.dart is invalid, because it references B.
    context.setContents(
        a,
        r'''
class A {
  m2() {}
}
class B extends A {}
''');
    _assertValidForChangedLibrary(a);
    _assertValidForDependentLibrary(b);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
  }

  void test_class_method_remove_notUsed_instantiated() {
    Source a = addSource(
        '/a.dart',
        r'''
abstract class I {
 void foo();
}
class A implements I {
 void foo() {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove 'A.foo'.
    //   b.dart is valid because it does not reference 'foo'.
    //     The class 'A' has a warning, but it is still not abstract.
    context.setContents(
        a,
        r'''
abstract class I {
 void fo();
}
class A implements I {
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);

    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValidAllResolution(b);
    _assertValidAllErrors(b);
  }

  void test_class_method_remove_subclass() {
    Source a = addSource(
        '/a.dart',
        r'''
abstract class I {
 void foo();
}
class A implements I {
 void foo() {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
class B extends A {}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A.bar, add A.bar2.
    //   b.dart
    //     Resolution is valid because 'foo' is not referenced.
    //     HINTS are invalid because 'B' might have invalid @override.
    //     VERIFY_ERRORS are invalid because 'B' might not implement something.
    //     Other errors are also invalid.
    context.setContents(
        a,
        r'''
abstract class I {
 void foo();
}
class A implements I {
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);

    _assertValidForDependentLibrary(b);
    _assertValidAllResolution(b);
    _assertInvalidHintsVerifyErrors(b);
  }

  void test_class_private_member() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  A();
  A._privateConstructor();

  foo() {}

  int _privateField;
  _privateMethod() {}
  int get _privateGetter => null;
  void set _privateSetter(_) {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main(A a) {
  a.foo();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: rename private members of A
    //   b.dart is valid, it cannot see these private members.
    context.setContents(
        a,
        r'''
class A {
  A();
  A._privateConstructor2();

  foo() {}

  int _privateField2;
  _privateMethod2() {}
  int get _privateGetter2 => null;
  void set _privateSetter2(_) {}
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_enum_add() {
    Source a = addSource(
        '/a.dart',
        r'''
main() {
  print(MyEnum.A);
}
''');
    _performPendingAnalysisTasks();
    // Insert a new enum declaration.
    // No errors expected.
    context.setContents(
        a,
        r'''
main() {
  print(MyEnum.A);
}
enum MyEnum { A, B, C }
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(a).errors, isEmpty);
  }

  void test_private_class() {
    Source a = addSource(
        '/a.dart',
        r'''
class _A {}
class _B2 {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new _A();
  new _B();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: change _A and _B2
    //   b.dart is valid, because _A, _B, _A2 and _B2 are all private,
    //   so b.dart cannot see them.
    context.setContents(
        a,
        r'''
class _A2 {}
class _B {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_private_topLevelVariable() {
    Source a = addSource(
        '/a.dart',
        r'''
int _V = 1;
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  print(_A);
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: change _V
    //   b.dart is valid, because _V is private and b.dart cannot see it.
    context.setContents(
        a,
        r'''
int _V = 2;
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_private_topLevelVariable_throughPublic() {
    Source a = addSource(
        '/a.dart',
        r'''
int _A = 1;
int B = _A + 1;
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  print(B);
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: change _A
    //   b.dart is invalid, because it uses B, which uses _A.
    context.setContents(
        a,
        r'''
int _A = 2;
int B = _A + 1;
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
  }

  void test_sequence_add_annotation() {
    Source a = addSource(
        '/a.dart',
        r'''
const myAnnotation = const Object();
class A {}
''');
    _performPendingAnalysisTasks();
    // Add a new annotation.
    context.setContents(
        a,
        r'''
const myAnnotation = const Object();
@myAnnotation
class A {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    // Analysis is done successfully.
    _performPendingAnalysisTasks();
    _assertValid(a, LIBRARY_ERRORS_READY);
    _assertValid(a, READY_RESOLVED_UNIT);
  }

  void test_sequence_applyChanges_changedSource() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
class B {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
  new B();
}
''');
    _performPendingAnalysisTasks();
    resourceProvider.updateFile(
        '/a.dart',
        r'''
class A2 {}
class B {}
''');
    // Update a.dart: remove A, add A2.
    //   b.dart is invalid, because it references A.
    var changeSet = new ChangeSet()..changedSource(a);
    context.applyChanges(changeSet);
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
    // Analyze.
    _performPendingAnalysisTasks();
    expect(context.getErrors(a).errors, hasLength(0));
    expect(context.getErrors(b).errors, hasLength(1));
    _assertValid(a, READY_RESOLVED_UNIT);
    _assertValid(b, READY_RESOLVED_UNIT);
    _assertValidAllLibraryUnitResults(a);
    _assertValidAllLibraryUnitResults(b);
  }

  void test_sequence_class_give_take() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
class B {}
class C {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
  new C2();
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(1));
    // Update a.dart: remove C, add C2.
    //   b.dart is invalid, because it references C2.
    context.setContents(
        a,
        r'''
class A {}
class B {}
class C2 {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
    // Now b.dart is analyzed and the error is fixed.
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(0));
    // Update a.dart: remove C2, add C.
    //   b.dart is invalid, because it references C2.
    context.setContents(
        a,
        r'''
class A {}
class B {}
class C {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
    // Now b.dart is analyzed and it again has the error.
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(1));
  }

  void test_sequence_class_removeMethod_overridden() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  void foo() {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
class B extends A {
  @override
  void foo() {}
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(0));
    // Update a.dart: remove add A.foo.
    //   b.dart has a new hint, because B.foo does not override anything
    context.setContents(
        a,
        r'''
class A {
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllResolution(b);
    _assertInvalidHintsVerifyErrors(b);

    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(1));
  }

  void test_sequence_clearParameterElements() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  foo(int p) {}
}
final a = new A();
main() {
  a.foo(42);
}
''');
    _performPendingAnalysisTasks();
    Expression find42() {
      CompilationUnit unit =
          context.getResult(new LibrarySpecificUnit(a, a), RESOLVED_UNIT);
      ExpressionStatement statement =
          AstFinder.getStatementsInTopLevelFunction(unit, 'main').single;
      MethodInvocation invocation = statement.expression;
      return invocation.argumentList.arguments[0];
    }
    {
      Expression argument = find42();
      expect(argument.staticParameterElement, isNull);
      expect(argument.propagatedParameterElement, isNotNull);
    }
    // Update a.dart: add type annotation for 'a'.
    // '42' has 'staticParameterElement', but not 'propagatedParameterElement'.
    context.setContents(
        a,
        r'''
class A {
  foo(int p) {}
}
final A a = new A();
main() {
  a.foo(42);
}
''');
    _performPendingAnalysisTasks();
    {
      Expression argument = find42();
      expect(argument.staticParameterElement, isNotNull);
      expect(argument.propagatedParameterElement, isNull);
    }
    // Update a.dart: remove type annotation for 'a'.
    // '42' has 'propagatedParameterElement', but not 'staticParameterElement'.
    context.setContents(
        a,
        r'''
class A {
  foo(int p) {}
}
final a = new A();
main() {
  a.foo(42);
}
''');
    _performPendingAnalysisTasks();
    {
      Expression argument = find42();
      expect(argument.staticParameterElement, isNull);
      expect(argument.propagatedParameterElement, isNotNull);
    }
  }

  void test_sequence_closureParameterTypesPropagation() {
    Source a = addSource(
        '/a.dart',
        r'''
main() {
  f((p) => 4.2);
}
f(c(int p)) {}
''');
    _performPendingAnalysisTasks();
    LibrarySpecificUnit targetA = new LibrarySpecificUnit(a, a);
    // Update and analyze.
    String newCode = r'''
newFunction() {}
main() {
  f((p) => 4.2);
}
f(c(int p)) {}
''';
    context.setContents(a, newCode);
    _performPendingAnalysisTasks();
    // Validate "(p) => 4.2" types.
    CompilationUnit unit = context.getResult(targetA, RESOLVED_UNIT2);
    SimpleIdentifier parameterName =
        EngineTestCase.findSimpleIdentifier(unit, newCode, 'p) => 4.2);');
    expect(parameterName.staticType, context.typeProvider.dynamicType);
    expect(parameterName.propagatedType, context.typeProvider.intType);
  }

  void test_sequence_compoundingResults_exportNamespace() {
    Source a = addSource(
        '/a.dart',
        r'''
class A<T> {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
export 'a.dart';
''');
    Source c = addSource(
        '/c.dart',
        r'''
import 'b.dart';
main() {
  new A<int>();
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(c).errors, isEmpty);
    // Update a.dart, so that `A<T>` has a type bound.
    //   This should invalidate export namespace for b.dart.
    //   Currently we invalidate the whole LIBRARY_ELEMENT4.
    //   So, c.dart will see the new `A<T extends B>` and report an error.
    context.setContents(
        a,
        r'''
class A<T extends B> {}
class B {}
''');
    _assertInvalid(b, LIBRARY_ELEMENT4);
    // Analyze and validate that a new error is reported.
    _performPendingAnalysisTasks();
    expect(context.getErrors(c).errors, hasLength(1));
    _assertValid(a, LIBRARY_ERRORS_READY);
    _assertValid(b, LIBRARY_ERRORS_READY);
    _assertValid(c, LIBRARY_ERRORS_READY);
  }

  void test_sequence_compoundingResults_invalidateButKeepDependency() {
    Source a = addSource(
        '/a.dart',
        r'''
import 'b.dart';
class A {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
import 'c.dart';
class B {}
''');
    Source c = addSource(
        '/c.dart',
        r'''
class C {}
''');
    Source d = addSource(
        '/d.dart',
        r'''
export 'b.dart';
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(c).errors, isEmpty);
    // Update: a.dart (limited) and b.dart (limited).
    //   This should invalidate LIBRARY_ELEMENT4 in d.dart, but it should be
    //   done in a way that keep dependency of other results od d.dart on
    //   LIBRARY_ELEMENT4 of d.dart, so that when we perform unlimited
    //   invalidation of c.dart, this makes d.dart invalid.
    context.setContents(
        a,
        r'''
import 'b.dart';
class A2 {}
''');
    context.setContents(
        b,
        r'''
import 'a.dart';
import 'c.dart';
class B2 {}
''');
    context.setContents(
        c,
        r'''
import 'dart:async';
class C {}
''');
    _assertInvalid(d, LIBRARY_ELEMENT4);
    _assertInvalid(d, LIBRARY_ERRORS_READY);
    // Analyze and validate that a new error is reported.
    _performPendingAnalysisTasks();
    _assertValid(a, EXPORT_SOURCE_CLOSURE);
    _assertValid(b, EXPORT_SOURCE_CLOSURE);
    _assertValid(c, EXPORT_SOURCE_CLOSURE);
    _assertValid(d, EXPORT_SOURCE_CLOSURE);
    _assertValid(a, LIBRARY_ERRORS_READY);
    _assertValid(b, LIBRARY_ERRORS_READY);
    _assertValid(c, LIBRARY_ERRORS_READY);
    _assertValid(d, LIBRARY_ERRORS_READY);
  }

  void test_sequence_compoundingResults_resolvedTypeNames() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
class B<T> {
  B(p);
}
''');
    Source c = addSource(
        '/c.dart',
        r'''
export 'a.dart';
export 'b.dart';
''');
    Source d = addSource(
        '/d.dart',
        r'''
import 'c.dart';
main() {
  new B<int>(null);
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart and b.dart
    //   This should invalidate most results in a.dart and b.dart
    //
    //   This should also invalidate "compounding" results in c.dart, such as
    //   READY_LIBRARY_ELEMENT6, which represent a state of the whole source
    //   closure, not a result of this single unit or a library.
    //
    //   The reason is that although type names (RESOLVED_UNIT5) b.dart will be
    //   eventually resolved and set into b.dart elements, it may happen
    //   after we attempted to re-resolve c.dart, which created Member(s), and
    //   attempts to use elements without types set.
    context.setContents(
        a,
        r'''
class A2 {}
''');
    context.setContents(
        b,
        r'''
class B<T> {
  B(T p);
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForChangedLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalid(c, READY_LIBRARY_ELEMENT6);
    _assertInvalid(c, READY_LIBRARY_ELEMENT7);
    // Analyze and validate that all results are valid.
    _performPendingAnalysisTasks();
    _assertValid(a, LIBRARY_ERRORS_READY);
    _assertValid(b, LIBRARY_ERRORS_READY);
    _assertValid(c, LIBRARY_ERRORS_READY);
    _assertValid(d, LIBRARY_ERRORS_READY);
  }

  void test_sequence_dependenciesWithCycles() {
    Source a = addSource(
        '/a.dart',
        r'''
const A = 1;
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'c.dart';
const B = C1 + 1;
''');
    Source c = addSource(
        '/c.dart',
        r'''
import 'a.dart';
import 'b.dart';
const C1 = A + 1;
const C2 = B + 2;
''');
    Source d = addSource(
        '/d.dart',
        r'''
import 'c.dart';
const D = C2 + 1;
''');
    _performPendingAnalysisTasks();
    // Update "A" constant.
    // This should invalidate results in all sources.
    context.setContents(
        a,
        r'''
const A = 2;
''');
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalid(c, LIBRARY_ERRORS_READY);
    _assertInvalid(d, LIBRARY_ERRORS_READY);
  }

  void test_sequence_inBodyChange_addRef_deltaChange() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main(A a) {
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(0));
    // Update b.dart: in-body incremental change - start referencing 'foo'.
    //   Should update referenced names.
    context.setContents(
        b,
        r'''
import 'a.dart';
main(A a) {
  a.foo;
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(1));
    // Update a.dart: add A.foo
    //   b.dart is invalid, because it references 'foo'.
    context.setContents(
        a,
        r'''
class A {
  int foo;
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
    // No errors after analysis.
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(0));
  }

  void test_sequence_inBodyChange_removeRef_deltaChange() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main(A a) {
  a.foo;
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(1));
    // Update b.dart: in-body incremental change - stop referencing 'foo'.
    //   Should update referenced names.
    context.setContents(
        b,
        r'''
import 'a.dart';
main(A a) {
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(b).errors, hasLength(0));
    // Update a.dart: add A.foo
    //   b.dart is still valid, because it does references 'foo' anymore.
    context.setContents(
        a,
        r'''
class A {
  int foo;
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_sequence_middleLimited_thenFirstFull() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
export 'a.dart';
''');
    Source c = addSource(
        '/c.dart',
        r'''
import 'b.dart';
A a;
''');
    _performPendingAnalysisTasks();
    // Update b.dart: limited invalidation.
    // Results in c.dart are valid, because the change in b.dart does not
    // affect anything in c.dart.
    context.setContents(
        b,
        r'''
export 'a.dart';
class B {}
''');
    _assertValid(a, LIBRARY_ERRORS_READY);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertValid(c, LIBRARY_ERRORS_READY);
    _assertUnitValid(c, RESOLVED_UNIT4);
    _assertUnitValid(c, RESOLVED_UNIT5);
    // Update a.dart: unlimited invalidation.
    // Results RESOLVED_UNIT4, RESOLVED_UNIT5, and RESOLVED_UNIT6 in c.dart
    // are invalid, because after unlimited change to a.dart everything
    // should be invalidated.
    // This fixes the problem that c.dart was not re-resolving type names.
    context.setContents(
        a,
        r'''
import 'dart:async';
class A {}
''');
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalid(c, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(c, RESOLVED_UNIT4);
  }

  void test_sequence_noChange_thenChange() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  A();
}

class B {
  B();
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
}
''');
    _performPendingAnalysisTasks();
    expect(context.getErrors(a).errors, hasLength(0));
    expect(context.getErrors(b).errors, hasLength(0));
    var unitA = context.getResolvedCompilationUnit2(a, a);
    var unitElementA = unitA.element;
    var libraryElementA = unitElementA.library;
    // Update a.dart, no declaration changes.
    context.setContents(
        a,
        r'''
class A {
  A();
}
class B {
  B();
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
    // The a.dart's unit and element are updated incrementally.
    // They are the same instances as initially.
    // So, all the references from other units are still valid.
    {
      LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
      expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
      expect(unitA.element, same(unitElementA));
      expect(unitElementA.library, same(libraryElementA));
    }
    // Analyze.
    _performPendingAnalysisTasks();
    expect(context.getErrors(a).errors, hasLength(0));
    expect(context.getErrors(b).errors, hasLength(0));
    // The a.dart's unit and element are the same.
    {
      LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
      expect(analysisCache.getValue(target, RESOLVED_UNIT), same(unitA));
      expect(unitA.element, same(unitElementA));
      expect(unitElementA.library, same(libraryElementA));
    }
    // Add a new method to a.dart. This invalidates b.dart, so
    // we know that the previous update did not damage dependencies.
    context.setContents(
        a,
        r'''
class A {
  A();
  m() {}
}
class B {
  B();
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllResolution(b);
    _assertValidAllErrors(b);
    // The a.dart's unit and element are the same.
    {
      LibrarySpecificUnit target = new LibrarySpecificUnit(a, a);
      expect(analysisCache.getValue(target, RESOLVED_UNIT1), same(unitA));
      expect(unitA.element, same(unitElementA));
      expect(unitElementA.library, same(libraryElementA));
    }
    // Analyze.
    _performPendingAnalysisTasks();
    expect(context.getErrors(a).errors, hasLength(0));
    expect(context.getErrors(b).errors, hasLength(0));
  }

  void test_sequence_parts_disableForPart() {
    Source a = addSource(
        '/a.dart',
        r'''
library my_lib;
part 'b.dart';
''');
    Source b = addSource(
        '/b.dart',
        r'''
part of my_lib;
class A {}
''');
    _performPendingAnalysisTasks();
    // Update b.dart - it is a part, which we don't support.
    // So, invalidate everything.
    context.setContents(
        b,
        r'''
part of my_lib;
class A {}
class B {}
''');
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(a, RESOLVED_UNIT2);
    _assertInvalidUnits(b, RESOLVED_UNIT1);
  }

  void test_sequence_parts_disableWithPart() {
    Source a = addSource(
        '/a.dart',
        r'''
library my_lib;
part 'b.dart';
''');
    Source b = addSource(
        '/b.dart',
        r'''
part of my_lib;
class B {}
''');
    _performPendingAnalysisTasks();
    // Update a.dart - it is a library with a part, which we don't support.
    // So, invalidate everything.
    context.setContents(
        a,
        r'''
library my_lib;
part 'b.dart';
class A {}
''');
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(a, RESOLVED_UNIT1);
    _assertInvalidUnits(b, RESOLVED_UNIT1);
  }

  void test_sequence_reorder_localFunctions() {
    Source a = addSource(
        '/a.dart',
        r'''
f1() {
  localFunction() {
    const C = 1;
  }
}
f2() {}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: reorder functions.
    // This should not fail with FrozenHashCodeException, because identifiers
    // of local elements should be relative to the enclosing top-level elements.
    context.setContents(
        a,
        r'''
f2() {}
f1() {
  localFunction() {
    const C = 1;
  }
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
  }

  void test_sequence_unitConstants_addRemove() {
    Source a = addSource(
        '/a.dart',
        r'''
const A = 1;
const B = 2;
const C = 3;
foo() {
  const V1 = 10;
}
bar() {
  const V2 = 20;
}
''');
    _performPendingAnalysisTasks();
    LibrarySpecificUnit unitA = new LibrarySpecificUnit(a, a);
    List<ConstantEvaluationTarget> oldConstants =
        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
    expect(oldConstants, hasLength(5));
    ConstVariableElement oldA = _findConstVariable(oldConstants, 'A');
    ConstVariableElement oldB = _findConstVariable(oldConstants, 'B');
    ConstVariableElement oldC = _findConstVariable(oldConstants, 'C');
    ConstVariableElement oldV1 = _findConstVariable(oldConstants, 'V1');
    ConstVariableElement oldV2 = _findConstVariable(oldConstants, 'V2');
    expect(context.analysisCache.get(oldA), isNotNull);
    expect(context.analysisCache.get(oldB), isNotNull);
    expect(context.analysisCache.get(oldC), isNotNull);
    expect(context.analysisCache.get(oldV1), isNotNull);
    // Update and validate new constants.
    context.setContents(
        a,
        r'''
const A = 1;
const B = 2;
const D = 4;
foo() {
  const V1 = 10;
}
baz() {
  const V3 = 30;
}
''');
    List<ConstantEvaluationTarget> newConstants =
        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
    expect(newConstants, hasLength(5));
    expect(newConstants, contains(same(oldA)));
    expect(newConstants, contains(same(oldB)));
    expect(newConstants, contains(same(oldV1)));
    ConstVariableElement newD = _findConstVariable(newConstants, 'D');
    ConstVariableElement newV3 = _findConstVariable(newConstants, 'V3');
    // Perform analysis, compute constant values.
    _performPendingAnalysisTasks();
    // Validate const variable values.
    expect(context.analysisCache.get(oldA), isNotNull);
    expect(context.analysisCache.get(oldB), isNotNull);
    expect(context.analysisCache.get(oldV1), isNotNull);
    expect(context.analysisCache.get(oldC), isNull);
    expect(context.analysisCache.get(oldV2), isNull);
    expect(context.analysisCache.get(newD), isNotNull);
    expect(context.analysisCache.get(newV3), isNotNull);
    expect(oldA.evaluationResult.value.toIntValue(), 1);
    expect(oldB.evaluationResult.value.toIntValue(), 2);
    expect(newD.evaluationResult.value.toIntValue(), 4);
    expect(oldV1.evaluationResult.value.toIntValue(), 10);
    expect(newV3.evaluationResult.value.toIntValue(), 30);
  }

  void test_sequence_unitConstants_local_insertSpace() {
    Source a = addSource(
        '/a.dart',
        r'''
main() {
  const C = 1;
}
''');
    _performPendingAnalysisTasks();
    LibrarySpecificUnit unitA = new LibrarySpecificUnit(a, a);
    List<ConstantEvaluationTarget> oldConstants =
        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
    expect(oldConstants, hasLength(1));
    ConstVariableElement C = _findConstVariable(oldConstants, 'C');
    expect(context.analysisCache.get(C), isNotNull);
    // Insert a space before the name.
    context.setContents(
        a,
        r'''
main() {
  const  C = 1;
}
''');
    List<ConstantEvaluationTarget> newConstants =
        context.getResult(unitA, COMPILATION_UNIT_CONSTANTS);
    expect(newConstants, hasLength(1));
    expect(newConstants, contains(same(C)));
    // Perform analysis, compute constant values.
    _performPendingAnalysisTasks();
    // Validate const variable values.
    expect(context.analysisCache.get(C), isNotNull);
    expect(C.evaluationResult.value.toIntValue(), 1);
  }

  void test_sequence_useAnyResolvedUnit() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
class B {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
}
''');
    _performPendingAnalysisTasks();
    _assertValid(a, LIBRARY_ERRORS_READY);
    _assertValid(b, LIBRARY_ERRORS_READY);
    // Invalidate RESOLVED_UNIT
    CacheEntry entryA = context.getCacheEntry(new LibrarySpecificUnit(a, a));
    entryA.setState(RESOLVED_UNIT, CacheState.FLUSHED);
    entryA.setState(RESOLVED_UNIT1, CacheState.FLUSHED);
    entryA.setState(RESOLVED_UNIT2, CacheState.FLUSHED);
    entryA.setState(RESOLVED_UNIT3, CacheState.FLUSHED);
    context.setContents(
        a,
        r'''
class A {}
class B2 {}
''');
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_unusedName_class_add() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
class B {}
class C {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
  new C();
}
''');
    _performPendingAnalysisTasks();
    _assertValid(a, LINE_INFO);
    // The class B is not referenced.
    //   a.dart is invalid.
    //   b.dart is valid.
    context.setContents(
        a,
        r'''
class A {}
class B2 {}
class C {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertUnitInvalid(a, RESOLVED_UNIT);
    _assertValidForDependentLibrary(b);
    _assertValidAllLibraryUnitResults(b);
    _assertValid(b, LIBRARY_ERRORS_READY);
  }

  void test_usedName_class_name_asHole_inBody() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
class B {}
class C {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
  new C2();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove C, add C2.
    //   b.dart is invalid, because it references C2.
    context.setContents(
        a,
        r'''
class A {}
class B {}
class C2 {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
  }

  void test_usedName_class_name_asSuper() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
class B extends A {}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A, add A2.
    //   b.dart is invalid, because it references A.
    context.setContents(
        a,
        r'''
class A2 {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
  }

  void test_usedName_class_name_asTypeBound() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
class B<T extends A> {
  T f;
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A, add A2.
    //   b.dart is invalid, because it references A.
    context.setContents(
        a,
        r'''
class A2 {}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
  }

  void test_usedName_class_name_inBody() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {}
class B {}
class C {}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  new A();
  new C();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove C, add C2.
    //   b.dart is invalid, because it references C.
    context.setContents(
        a,
        r'''
class A {}
class B {}
class C2 {}
''');
    _assertValidForChangedLibrary(a);
    _assertValidForDependentLibrary(b);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
  }

  void test_usedName_classMethod_name_inBody() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  m() {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
main() {
  A a = new A();
  a.m();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A.m, add A.m2.
    //   b.dart is invalid, because it references 'm'.
    context.setContents(
        a,
        r'''
class A {
  m2() {}
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalidLibraryElements(b, LIBRARY_ELEMENT4);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
  }

  void test_usedName_indirect_classMethod_name_inBody() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  m() {}
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
class B extends A {}
''');
    Source c = addSource(
        '/c.dart',
        r'''
import 'b.dart';
main() {
  B b = new B();
  b.m();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A.m, add A.m2.
    //   b.dart has valid resolution, and invalid errors.
    //   c.dart is invalid, because 'main' references 'm'.
    context.setContents(
        a,
        r'''
class A {
  m2() {}
}
''');
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);

    _assertValidForDependentLibrary(b);
    _assertValidAllResolution(b);
    _assertInvalidHintsVerifyErrors(b);

    _assertValidForDependentLibrary(c);
    _assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
    _assertInvalidUnits(c, RESOLVED_UNIT4);
    _assertInvalid(c, LIBRARY_ERRORS_READY);
  }

  void test_usedName_indirect_classMethod_returnType_inBody() {
    Source a = addSource(
        '/a.dart',
        r'''
class A {
  int m() {
    return 1;
  }
}
''');
    Source b = addSource(
        '/b.dart',
        r'''
import 'a.dart';
class B extends A {}
''');
    Source c = addSource(
        '/c.dart',
        r'''
import 'b.dart';
main() {
  B b = new B();
  b.m();
}
''');
    _performPendingAnalysisTasks();
    // Update a.dart: remove A.m, add A.m2.
    //   b.dart is invalid, because B extends A.
    //   c.dart is invalid, because 'main' references 'm'.
    context.setContents(
        a,
        r'''
class A {
  double m() {
    return 1.2;
  }
}
''');
    _assertInvalid(a, LIBRARY_ERRORS_READY);

    _assertValidForDependentLibrary(b);
    _assertValidAllResolution(b);
    _assertInvalidHintsVerifyErrors(b);

    _assertValidForDependentLibrary(c);
    _assertInvalidLibraryElements(c, LIBRARY_ELEMENT5);
    _assertInvalidUnits(c, RESOLVED_UNIT4);
    _assertInvalid(c, LIBRARY_ERRORS_READY);
  }

  void _assertInvalid(AnalysisTarget target, ResultDescriptor descriptor) {
    CacheState actual = analysisCache.getState(target, descriptor);
    if (actual != CacheState.INVALID) {
      fail("cache state of $target $descriptor: wanted INVALID, got: $actual");
    }
  }

  /**
   * Assert that [VERIFY_ERRORS] and other error results that include it,
   * are invalid.
   */
  void _assertInvalidHintsVerifyErrors(Source unit) {
    _assertUnitInvalid(unit, HINTS);
    _assertUnitInvalid(unit, VERIFY_ERRORS);
    _assertUnitInvalid(unit, LIBRARY_UNIT_ERRORS);
    _assertInvalid(unit, DART_ERRORS);
    _assertInvalid(unit, LIBRARY_ERRORS_READY);
  }

  /**
   * Assert that [LIBRARY_ELEMENT_RESULTS] for [first] and after it are invalid.
   */
  void _assertInvalidLibraryElements(
      Source source, ResultDescriptor<LibraryElement> first) {
    bool foundFirst = false;
    for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
      foundFirst = foundFirst || result == first;
      if (foundFirst) {
        _assertInvalid(source, result);
      }
    }
  }

  void _assertInvalidUnits(Source unit, ResultDescriptor<CompilationUnit> first,
      {Source library}) {
    var target = new LibrarySpecificUnit(library ?? unit, unit);
    bool foundFirst = false;
    for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
      foundFirst = foundFirst || result == first;
      if (foundFirst) {
        _assertInvalid(target, result);
      }
    }
  }

  void _assertUnitInvalid(Source unitSource, ResultDescriptor descriptor,
      {Source librarySource}) {
    librarySource ??= unitSource;
    _assertInvalid(
        new LibrarySpecificUnit(librarySource, unitSource), descriptor);
  }

  void _assertUnitValid(Source unitSource, ResultDescriptor descriptor,
      {Source librarySource}) {
    librarySource ??= unitSource;
    _assertValid(
        new LibrarySpecificUnit(librarySource, unitSource), descriptor);
  }

  void _assertUnitValidTaskResults(Source unitSource, TaskDescriptor descriptor,
      {Source librarySource}) {
    librarySource ??= unitSource;
    for (ResultDescriptor result in descriptor.results) {
      _assertUnitValid(unitSource, result, librarySource: librarySource);
    }
  }

  void _assertValid(AnalysisTarget target, ResultDescriptor descriptor) {
    CacheState state = analysisCache.getState(target, descriptor);
    expect(state, isIn([CacheState.VALID, CacheState.FLUSHED]),
        reason: '$descriptor in $target');
  }

  /**
   * Assert that all error results for the given [unit] are valid.
   */
  void _assertValidAllErrors(Source unit) {
    for (ListResultDescriptor<AnalysisError> result in ERROR_SOURCE_RESULTS) {
      _assertValid(unit, result);
    }
    for (ListResultDescriptor<AnalysisError> result in ERROR_UNIT_RESULTS) {
      _assertUnitValid(unit, result);
    }
  }

  void _assertValidAllLibraryUnitResults(Source source, {Source library}) {
    library ??= source;
    for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
      if (result == LIBRARY_ELEMENT4) {
        continue;
      }
      _assertValid(library, result);
    }
    LibrarySpecificUnit target = new LibrarySpecificUnit(library, source);
    for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
      _assertValid(target, result);
    }
  }

  void _assertValidAllResolution(Source unit) {
    _assertValidUnits(unit, null);
    _assertUnitValidTaskResults(unit, ResolveUnitTypeNamesTask.DESCRIPTOR);
    _assertUnitValidTaskResults(unit, ResolveUnitTask.DESCRIPTOR);
    _assertValidTaskResults(unit, ResolveLibraryReferencesTask.DESCRIPTOR);
    _assertValidTaskResults(unit, ResolveLibraryTask.DESCRIPTOR);
  }

  void _assertValidForAnyLibrary(Source source) {
    // Source results.
    _assertValidTaskResults(source, ScanDartTask.DESCRIPTOR);
    // Library results.
    _assertValidTaskResults(source, BuildLibraryElementTask.DESCRIPTOR);
    _assertValidTaskResults(source, BuildDirectiveElementsTask.DESCRIPTOR);
    _assertValidTaskResults(source, BuildSourceExportClosureTask.DESCRIPTOR);
    _assertValidTaskResults(source, ReadyLibraryElement2Task.DESCRIPTOR);
    _assertValidTaskResults(source, ComputeLibraryCycleTask.DESCRIPTOR);
    // Unit results.
    _assertUnitValidTaskResults(
        source, BuildCompilationUnitElementTask.DESCRIPTOR);
    _assertUnitValidTaskResults(
        source, ResolveDirectiveElementsTask.DESCRIPTOR);
    _assertUnitValidTaskResults(source, BuildEnumMemberElementsTask.DESCRIPTOR);
  }

  void _assertValidForChangedLibrary(Source source) {
    _assertValidForAnyLibrary(source);
  }

  void _assertValidForDependentLibrary(Source source) {
    _assertValidForAnyLibrary(source);
    // Library results.
    _assertValidTaskResults(source, BuildPublicNamespaceTask.DESCRIPTOR);
  }

  void _assertValidTaskResults(AnalysisTarget target, TaskDescriptor task) {
    for (ResultDescriptor result in task.results) {
      _assertValid(target, result);
    }
  }

  void _assertValidUnits(Source unit, ResultDescriptor<CompilationUnit> last,
      {Source library}) {
    var target = new LibrarySpecificUnit(library ?? unit, unit);
    bool foundLast = false;
    for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
      if (!foundLast) {
        _assertValid(target, result);
      }
      foundLast = foundLast || result == last;
    }
  }

  ConstVariableElement _findConstVariable(
      List<ConstantEvaluationTarget> constants, String name) {
    return constants.singleWhere((c) {
      return c is ConstVariableElement && c.name == name;
    });
  }

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

  void _verifyTwoLibrariesAllValid(
      String firstCodeA, String secondCodeA, String codeB) {
    Source a = addSource('/a.dart', firstCodeA);
    Source b = addSource('/b.dart', codeB);
    _performPendingAnalysisTasks();
    context.setContents(a, secondCodeA);
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllResolution(b);
    _assertValidAllErrors(b);
  }

  void _verifyTwoLibrariesInvalidatesResolution(
      String firstCodeA, String secondCodeA, String codeB) {
    Source a = addSource('/a.dart', firstCodeA);
    Source b = addSource('/b.dart', codeB);
    _performPendingAnalysisTasks();
    context.setContents(a, secondCodeA);
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertInvalid(b, LIBRARY_ERRORS_READY);
    _assertInvalidUnits(b, RESOLVED_UNIT4);
  }

  void _verifyTwoLibrariesInvalidHintsVerifyErrors(
      String firstCodeA, String secondCodeA, String codeB) {
    Source a = addSource('/a.dart', firstCodeA);
    Source b = addSource('/b.dart', codeB);
    _performPendingAnalysisTasks();
    context.setContents(a, secondCodeA);
    _assertValidForChangedLibrary(a);
    _assertInvalid(a, LIBRARY_ERRORS_READY);
    _assertValidForDependentLibrary(b);
    _assertValidAllResolution(b);
    _assertUnitValid(b, RESOLVE_UNIT_ERRORS);
    _assertInvalidHintsVerifyErrors(b);
  }
}

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];
    if (!identical(previousElement, element)) {
      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);
  }
}

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