diff --git a/CHANGELOG.md b/CHANGELOG.md
index 087ba19..3172396 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,9 @@
   * Added `Uri.data` getter for `data:` URIs, and `UriData` class for the
     return type.
   * Added `growable` parameter to `List.filled` constructor.
+  * Added microsecond support to `DateTime`: `DateTime.microsecond`,
+    `DateTime.microsecondsSinceEpoch`, and
+    `new DateTime.fromMicrosecondsSinceEpoch`.
 
 * `dart:math`
   * `Random` added a `secure` constructor returning a cryptographically secure
@@ -21,6 +24,12 @@
 
 ### Tool changes
 
+* `dartfmt`
+
+  * Better line splitting in a variety of cases.
+
+  * Other optimizations and bug fixes.
+
 * Pub
 
   * **Breaking:** Pub now eagerly emits an error when a pubspec's "name" field
diff --git a/DEPS b/DEPS
index 8f64f6c..ed1aa95 100644
--- a/DEPS
+++ b/DEPS
@@ -39,7 +39,7 @@
   # Revisions of /third_party/* dependencies.
   "7zip_rev" : "@19997",
   "args_tag": "@0.13.0",
-  "async_tag": "@1.2.0",
+  "async_tag": "@1.4.0",
   "barback_tag" : "@0.15.2+7",
   "boringssl_rev" : "@daeafc22c66ad48f6b32fc8d3362eb9ba31b774e",
   "charcode_tag": "@1.1.0",
@@ -47,12 +47,13 @@
   "clang_rev" : "@28450",
   "cli_util_tag" : "@0.0.1+2",
   "collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
+  "convert_tag": "@1.0.0",
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
   "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
-  "dartdoc_tag" : "@v0.8.3",
+  "dartdoc_tag" : "@v0.8.4",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
-  "dart_style_tag": "@0.2.0",
+  "dart_style_tag": "@0.2.2",
   "dev_compiler_rev": "@0.1.9",
   "fake_async_rev" : "@38614",
   "firefox_jsshell_rev" : "@45554",
@@ -60,14 +61,14 @@
   "gsutil_rev" : "@33376",
   "html_tag" : "@0.12.1+1",
   "http_rev" : "@9b93e1542c753090c50b46ef1592d44bc858bfe7",
-  "http_multi_server_tag" : "@1.3.2",
-  "http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
+  "http_multi_server_tag" : "@2.0.0",
+  "http_parser_tag" : "@1.1.0",
   "http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
   "idl_parser_rev": "@6316d5982dc24b34d09dd8b10fbeaaff28d83a48",
-  "intl_rev": "@32047558bd220a53c1f4d93a26d54b83533b1475",
+  "intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@1.1.1",
-  "linter_rev": "@e5281475126efdc556c3eba6a8b6683fd814b033",
+  "linter_rev": "@5a599fd32d3b6ef00ffa7c330d1f32bbad287228",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
@@ -82,13 +83,13 @@
   "petitparser_rev" : "@37878",
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "plugin_tag": "@0.1.0",
-  "pool_rev": "@e454b4b54d2987e8d2f0fbd3ac519641ada9bd0f",
-  "pub_rev": "@8c091bf6332e8b392fdac63ae297426fb65ed925",
+  "pool_tag": "@1.2.1",
+  "pub_rev": "@3000544b752bbc89e5e01559eed7f70e9401632b",
   "pub_cache_tag": "@v0.1.0",
   "pub_semver_tag": "@1.2.1",
   "quiver_tag": "@0.21.4",
   "root_certificates_rev": "@c3a41df63afacec62fcb8135196177e35fe72f71",
-  "scheduled_test_tag": "@0.12.1+2",
+  "scheduled_test_tag": "@0.12.4+2",
   "shelf_tag": "@0.6.2+1",
   "smoke_rev" : "@f3361191cc2a85ebc1e4d4c33aec672d7915aba9",
   "source_maps_tag": "@0.10.1",
@@ -99,7 +100,7 @@
   "stack_trace_tag": "@1.4.2",
   "string_scanner_tag": "@0.1.4",
   "sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
-  "test_tag": "@0.12.3+8",
+  "test_tag": "@0.12.6+1",
   "test_reflective_loader_tag": "@0.0.3",
   "utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
   "unittest_tag": "@0.11.6",
@@ -183,6 +184,8 @@
       (Var("github_mirror") % "cli_util") + Var("cli_util_tag"),
   Var("dart_root") + "/third_party/pkg/collection":
       (Var("github_mirror") % "collection") + Var("collection_rev"),
+  Var("dart_root") + "/third_party/pkg/convert":
+      "https://github.com/dart-lang/convert.git" + Var("convert_tag"),
   Var("dart_root") + "/third_party/pkg/crypto":
       (Var("github_mirror") % "crypto") + Var("crypto_rev"),
   Var("dart_root") + "/third_party/pkg/csslib":
@@ -205,7 +208,7 @@
       (Var("github_mirror") % "http_multi_server") +
       Var("http_multi_server_tag"),
   Var("dart_root") + "/third_party/pkg/http_parser":
-      (Var("github_mirror") % "http_parser") + Var("http_parser_rev"),
+      (Var("github_mirror") % "http_parser") + Var("http_parser_tag"),
   Var("dart_root") + "/third_party/pkg/http_throttle":
       (Var("github_mirror") % "http_throttle") +
       Var("http_throttle_rev"),
@@ -244,7 +247,7 @@
   Var("dart_root") + "/third_party/pkg/plugin":
       (Var("github_mirror") % "plugin") + Var("plugin_tag"),
   Var("dart_root") + "/third_party/pkg/pool":
-      (Var("github_mirror") % "pool") + Var("pool_rev"),
+      (Var("github_mirror") % "pool") + Var("pool_tag"),
   Var("dart_root") + "/third_party/pkg/pub_semver":
       (Var("github_mirror") % "pub_semver") + Var("pub_semver_tag"),
   Var("dart_root") + "/third_party/pkg/pub":
diff --git a/pkg/analysis_server/benchmark/integration/README.md b/pkg/analysis_server/benchmark/integration/README.md
index 78431f9..9955c11 100644
--- a/pkg/analysis_server/benchmark/integration/README.md
+++ b/pkg/analysis_server/benchmark/integration/README.md
@@ -20,9 +20,7 @@
 * **inputFile** = the instrumentation or log file
 
 Additional arguments are passed directly to main.dart.
-For example, you may want to specify --newTaskModel to measure performance
-with the new task model versus the old task model,
-or if the log was recorded on one machine and is played back on another,
+For example, if the log was recorded on one machine and is played back on another,
 then you might need to specify -m<oldSrcPath>,<newSrcPath>
 to map the source paths for playback.
 When specifying additional arguments, any occurrences of @tmpSrcDir@
@@ -49,7 +47,6 @@
 *  **-t, --tmpSrcDir         <dirPath>**
 The temporary directory containing source used during performance measurement.
 WARNING: The contents of the target directory will be modified
-*  **--newTaskModel**       enable the use of the new task model
 *  **-d, --diagnosticPort** localhost port on which server
                             will provide diagnostic web pages
 *  **-v, --verbose**        Verbose logging
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 80aec4c1..aac45a2 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -45,8 +45,6 @@
 
   final Logger logger = new Logger('Driver');
 
-  final bool newTaskModel;
-
   /**
    * The diagnostic port for Analysis Server or `null` if none.
    */
@@ -70,7 +68,7 @@
    */
   Completer<Results> _runCompleter = new Completer<Results>();
 
-  Driver({this.newTaskModel, this.diagnosticPort});
+  Driver({this.diagnosticPort});
 
   /**
    * Return a [Future] that completes with the [Results] of running
@@ -114,9 +112,7 @@
     });
     running = true;
     return server
-        .start(
-            diagnosticPort: diagnosticPort,
-            newTaskModel: newTaskModel /*profileServer: true*/)
+        .start(diagnosticPort: diagnosticPort /*profileServer: true*/)
         .then((params) {
       server.listenToOutput(dispatchNotification);
       server.exitCode.then((_) {
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index 100ab6f..e0fbc80 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -26,8 +26,7 @@
   });
   PerfArgs args = parseArgs(rawArgs);
 
-  Driver driver = new Driver(
-      diagnosticPort: args.diagnosticPort, newTaskModel: args.newTaskModel);
+  Driver driver = new Driver(diagnosticPort: args.diagnosticPort);
   Stream<Operation> stream = openInput(args);
   StreamSubscription<Operation> subscription;
   subscription = stream.listen((Operation op) {
@@ -57,7 +56,6 @@
 const HELP_CMDLINE_OPTION = 'help';
 const INPUT_CMDLINE_OPTION = 'input';
 const MAP_OPTION = 'map';
-const NEW_TASK_MODEL_OPTION = 'newTaskModel';
 
 /**
  * The amount of time to give the server to respond to a shutdown request
@@ -94,10 +92,6 @@
       help: '<dirPath>\n'
           'The temporary directory containing source used during performance measurement.\n'
           'WARNING: The contents of the target directory will be modified');
-  _argParser.addFlag(NEW_TASK_MODEL_OPTION,
-      help: "enable the use of the new task model",
-      defaultsTo: false,
-      negatable: false);
   _argParser.addOption(DIAGNOSTIC_PORT_OPTION,
       abbr: 'd',
       help: 'localhost port on which server will provide diagnostic web pages');
@@ -181,8 +175,6 @@
     showHelp = true;
   }
 
-  perfArgs.newTaskModel = args[NEW_TASK_MODEL_OPTION];
-
   String portText = args[DIAGNOSTIC_PORT_OPTION];
   if (portText != null) {
     perfArgs.diagnosticPort = int.parse(portText, onError: (s) {
@@ -253,9 +245,4 @@
    * The diagnostic port for Analysis Server or `null` if none.
    */
   int diagnosticPort;
-
-  /**
-   * `true` if the server should run using the new task model.
-   */
-  bool newTaskModel;
 }
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 68947be..b20b660 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -61,7 +61,7 @@
 </style></head>
   <body>
     <h1>Analysis Server API Specification</h1>
-    <h1 style="color:#999999">Version 1.13.0</h1>
+    <h1 style="color:#999999">Version 1.14.0</h1>
     <p>
       This document contains a specification of the API provided by the
       analysis server.  The API in this document is currently under
@@ -2304,7 +2304,27 @@
               field is omitted if the file is not an HTML file.
             </p>
           </dd></dl></dd></dl>
-    
+    <h2 class="domain"><a name="domain_diagnostic">Domain: diagnostic</a></h2>
+      <p>
+        The diagnostic domain contains server diagnostics APIs.
+      </p>
+      
+    <h3>Requests</h3><dl><dt class="request"><a name="request_diagnostic.getDiagnostics">diagnostic.getDiagnostics</a> (<a href="#request_diagnostic.getDiagnostics">#</a>)</dt><dd><div class="box"><pre>request: {
+  "id": String
+  "method": "diagnostic.getDiagnostics"
+}</pre><br><pre>response: {
+  "id": String
+  "error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
+  "result": {
+    "<b>contexts</b>": List&lt;<a href="#type_ContextData">ContextData</a>&gt;
+  }
+}</pre></div>
+        <p>Return server diagnostics.</p>
+        
+      <h4>Returns</h4><dl><dt class="field"><b><i>contexts ( List&lt;<a href="#type_ContextData">ContextData</a>&gt; )</i></b></dt><dd>
+            
+            <p>The list of analysis contexts.</p>
+          </dd></dl></dd></dl>
     
       <h2 class="domain"><a name="types">Types</a></h2>
       <p>
@@ -2755,7 +2775,37 @@
               For suggestions of this kind, the completion is
               the named argument identifier including a trailing ':' and space.
             </p>
-          </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
+          </dd><dt class="value">OPTIONAL_ARGUMENT</dt><dt class="value">PARAMETER</dt></dl></dd><dt class="typeDefinition"><a name="type_ContextData">ContextData: object</a></dt><dd>
+        <p>
+          Information about an analysis context.
+        </p>
+        
+      <dl><dt class="field"><b><i>name ( String )</i></b></dt><dd>
+            
+            <p>
+              The name of the context.
+            </p>
+          </dd><dt class="field"><b><i>explicitFileCount ( int )</i></b></dt><dd>
+            
+            <p>
+              Explicitly analyzed files.
+            </p>
+          </dd><dt class="field"><b><i>implicitFileCount ( int )</i></b></dt><dd>
+            
+            <p>
+              Implicitly analyzed files.
+            </p>
+          </dd><dt class="field"><b><i>workItemQueueLength ( int )</i></b></dt><dd>
+            
+            <p>
+              The number of work items in the queue.
+            </p>
+          </dd><dt class="field"><b><i>cacheEntryExceptions ( List&lt;String&gt; )</i></b></dt><dd>
+            
+            <p>
+              Exceptions associated with cache entries.
+            </p>
+          </dd></dl></dd><dt class="typeDefinition"><a name="type_Element">Element: object</a></dt><dd>
         <p>
           Information about an element (something that can be declared
           in code).
@@ -2858,7 +2908,12 @@
       <dl><dt class="value">LIBRARY</dt><dt class="value">PART</dt></dl></dd><dt class="typeDefinition"><a name="type_FilePath">FilePath: String</a></dt><dd>
         
         <p>
-          The absolute path of a file.
+          The absolute, normalized path of a file.
+        </p>
+        <p>
+          If the format of a file path in a request is not valid, e.g. the
+          path is not absolute or is not normalized, then an error of type
+          <tt>INVALID_FILE_PATH_FORMAT</tt> will be generated.
         </p>
       </dd><dt class="typeDefinition"><a name="type_FoldingKind">FoldingKind: String</a></dt><dd>
         <p>
@@ -3636,6 +3691,12 @@
               The context root used to create an execution context does not
               exist.
             </p>
+          </dd><dt class="value">INVALID_FILE_PATH_FORMAT</dt><dd>
+            
+            <p>
+              The format of the given file path is invalid, e.g. is not
+              absolute and normalized.
+            </p>
           </dd><dt class="value">INVALID_OVERLAY_CHANGE</dt><dd>
             
             <p>
@@ -4301,7 +4362,7 @@
       TBD
     </p>
     <h2 class="domain"><a name="index">Index</a></h2>
-    <h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
+    <h3>Domains</h3><h4>server (<a href="#domain_server">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_server.getVersion">getVersion</a></li><li><a href="#request_server.shutdown">shutdown</a></li><li><a href="#request_server.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_server.connected">connected</a></li><li><a href="#notification_server.error">error</a></li><li><a href="#notification_server.status">status</a></li></ul></div></div><h4>analysis (<a href="#domain_analysis">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_analysis.getErrors">getErrors</a></li><li><a href="#request_analysis.getHover">getHover</a></li><li><a href="#request_analysis.getReachableSources">getReachableSources</a></li><li><a href="#request_analysis.getLibraryDependencies">getLibraryDependencies</a></li><li><a href="#request_analysis.getNavigation">getNavigation</a></li><li><a href="#request_analysis.reanalyze">reanalyze</a></li><li><a href="#request_analysis.setAnalysisRoots">setAnalysisRoots</a></li><li><a href="#request_analysis.setGeneralSubscriptions">setGeneralSubscriptions</a></li><li><a href="#request_analysis.setPriorityFiles">setPriorityFiles</a></li><li><a href="#request_analysis.setSubscriptions">setSubscriptions</a></li><li><a href="#request_analysis.updateContent">updateContent</a></li><li><a href="#request_analysis.updateOptions">updateOptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_analysis.analyzedFiles">analyzedFiles</a></li><li><a href="#notification_analysis.errors">errors</a></li><li><a href="#notification_analysis.flushResults">flushResults</a></li><li><a href="#notification_analysis.folding">folding</a></li><li><a href="#notification_analysis.highlights">highlights</a></li><li><a href="#notification_analysis.implemented">implemented</a></li><li><a href="#notification_analysis.invalidate">invalidate</a></li><li><a href="#notification_analysis.navigation">navigation</a></li><li><a href="#notification_analysis.occurrences">occurrences</a></li><li><a href="#notification_analysis.outline">outline</a></li><li><a href="#notification_analysis.overrides">overrides</a></li></ul></div></div><h4>completion (<a href="#domain_completion">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_completion.getSuggestions">getSuggestions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_completion.results">results</a></li></ul></div></div><h4>search (<a href="#domain_search">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_search.findElementReferences">findElementReferences</a></li><li><a href="#request_search.findMemberDeclarations">findMemberDeclarations</a></li><li><a href="#request_search.findMemberReferences">findMemberReferences</a></li><li><a href="#request_search.findTopLevelDeclarations">findTopLevelDeclarations</a></li><li><a href="#request_search.getTypeHierarchy">getTypeHierarchy</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_search.results">results</a></li></ul></div></div><h4>edit (<a href="#domain_edit">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_edit.format">format</a></li><li><a href="#request_edit.getAssists">getAssists</a></li><li><a href="#request_edit.getAvailableRefactorings">getAvailableRefactorings</a></li><li><a href="#request_edit.getFixes">getFixes</a></li><li><a href="#request_edit.getRefactoring">getRefactoring</a></li><li><a href="#request_edit.sortMembers">sortMembers</a></li><li><a href="#request_edit.organizeDirectives">organizeDirectives</a></li></ul></div><h4>execution (<a href="#domain_execution">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_execution.createContext">createContext</a></li><li><a href="#request_execution.deleteContext">deleteContext</a></li><li><a href="#request_execution.mapUri">mapUri</a></li><li><a href="#request_execution.setSubscriptions">setSubscriptions</a></li></ul><h5>Notifications</h5><div class="subindex"><ul><li><a href="#notification_execution.launchData">launchData</a></li></ul></div></div><h4>diagnostic (<a href="#domain_diagnostic">↑</a>)</h4><div class="subindex"><h5>Requests</h5><ul><li><a href="#request_diagnostic.getDiagnostics">getDiagnostics</a></li></ul></div><h3>Types (<a href="#types">↑</a>)</h3><div class="subindex"><ul><li><a href="#type_AddContentOverlay">AddContentOverlay</a></li><li><a href="#type_AnalysisError">AnalysisError</a></li><li><a href="#type_AnalysisErrorFixes">AnalysisErrorFixes</a></li><li><a href="#type_AnalysisErrorSeverity">AnalysisErrorSeverity</a></li><li><a href="#type_AnalysisErrorType">AnalysisErrorType</a></li><li><a href="#type_AnalysisOptions">AnalysisOptions</a></li><li><a href="#type_AnalysisService">AnalysisService</a></li><li><a href="#type_AnalysisStatus">AnalysisStatus</a></li><li><a href="#type_ChangeContentOverlay">ChangeContentOverlay</a></li><li><a href="#type_CompletionId">CompletionId</a></li><li><a href="#type_CompletionSuggestion">CompletionSuggestion</a></li><li><a href="#type_CompletionSuggestionKind">CompletionSuggestionKind</a></li><li><a href="#type_ContextData">ContextData</a></li><li><a href="#type_Element">Element</a></li><li><a href="#type_ElementKind">ElementKind</a></li><li><a href="#type_ExecutableFile">ExecutableFile</a></li><li><a href="#type_ExecutableKind">ExecutableKind</a></li><li><a href="#type_ExecutionContextId">ExecutionContextId</a></li><li><a href="#type_ExecutionService">ExecutionService</a></li><li><a href="#type_FileKind">FileKind</a></li><li><a href="#type_FilePath">FilePath</a></li><li><a href="#type_FoldingKind">FoldingKind</a></li><li><a href="#type_FoldingRegion">FoldingRegion</a></li><li><a href="#type_GeneralAnalysisService">GeneralAnalysisService</a></li><li><a href="#type_HighlightRegion">HighlightRegion</a></li><li><a href="#type_HighlightRegionType">HighlightRegionType</a></li><li><a href="#type_HoverInformation">HoverInformation</a></li><li><a href="#type_ImplementedClass">ImplementedClass</a></li><li><a href="#type_ImplementedMember">ImplementedMember</a></li><li><a href="#type_LinkedEditGroup">LinkedEditGroup</a></li><li><a href="#type_LinkedEditSuggestion">LinkedEditSuggestion</a></li><li><a href="#type_LinkedEditSuggestionKind">LinkedEditSuggestionKind</a></li><li><a href="#type_Location">Location</a></li><li><a href="#type_NavigationRegion">NavigationRegion</a></li><li><a href="#type_NavigationTarget">NavigationTarget</a></li><li><a href="#type_Occurrences">Occurrences</a></li><li><a href="#type_Outline">Outline</a></li><li><a href="#type_Override">Override</a></li><li><a href="#type_OverriddenMember">OverriddenMember</a></li><li><a href="#type_Position">Position</a></li><li><a href="#type_PubStatus">PubStatus</a></li><li><a href="#type_RefactoringKind">RefactoringKind</a></li><li><a href="#type_RefactoringMethodParameter">RefactoringMethodParameter</a></li><li><a href="#type_RefactoringFeedback">RefactoringFeedback</a></li><li><a href="#type_RefactoringOptions">RefactoringOptions</a></li><li><a href="#type_RefactoringMethodParameterKind">RefactoringMethodParameterKind</a></li><li><a href="#type_RefactoringProblem">RefactoringProblem</a></li><li><a href="#type_RefactoringProblemSeverity">RefactoringProblemSeverity</a></li><li><a href="#type_RemoveContentOverlay">RemoveContentOverlay</a></li><li><a href="#type_RequestError">RequestError</a></li><li><a href="#type_RequestErrorCode">RequestErrorCode</a></li><li><a href="#type_SearchId">SearchId</a></li><li><a href="#type_SearchResult">SearchResult</a></li><li><a href="#type_SearchResultKind">SearchResultKind</a></li><li><a href="#type_ServerService">ServerService</a></li><li><a href="#type_SourceChange">SourceChange</a></li><li><a href="#type_SourceEdit">SourceEdit</a></li><li><a href="#type_SourceFileEdit">SourceFileEdit</a></li><li><a href="#type_TypeHierarchyItem">TypeHierarchyItem</a></li></ul></div><h3>Refactorings (<a href="#refactorings">↑</a>)</h3><div class="subindex"><ul><li><a href="#refactoring_CONVERT_GETTER_TO_METHOD">CONVERT_GETTER_TO_METHOD</a></li><li><a href="#refactoring_CONVERT_METHOD_TO_GETTER">CONVERT_METHOD_TO_GETTER</a></li><li><a href="#refactoring_EXTRACT_LOCAL_VARIABLE">EXTRACT_LOCAL_VARIABLE</a></li><li><a href="#refactoring_EXTRACT_METHOD">EXTRACT_METHOD</a></li><li><a href="#refactoring_INLINE_LOCAL_VARIABLE">INLINE_LOCAL_VARIABLE</a></li><li><a href="#refactoring_INLINE_METHOD">INLINE_METHOD</a></li><li><a href="#refactoring_MOVE_FILE">MOVE_FILE</a></li><li><a href="#refactoring_RENAME">RENAME</a></li></ul></div>
   
 
 </body></html>
\ No newline at end of file
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index 81ad8dc..e931ba3 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -9447,7 +9447,6 @@
  *   "explicitFileCount": int
  *   "implicitFileCount": int
  *   "workItemQueueLength": int
- *   "workItemQueueLengthAverage": String
  *   "cacheEntryExceptions": List<String>
  * }
  *
@@ -9462,8 +9461,6 @@
 
   int _workItemQueueLength;
 
-  String _workItemQueueLengthAverage;
-
   List<String> _cacheEntryExceptions;
 
   /**
@@ -9519,21 +9516,6 @@
   }
 
   /**
-   * A rolling average of work items in the queue. (A double encoded as a
-   * String.)
-   */
-  String get workItemQueueLengthAverage => _workItemQueueLengthAverage;
-
-  /**
-   * A rolling average of work items in the queue. (A double encoded as a
-   * String.)
-   */
-  void set workItemQueueLengthAverage(String value) {
-    assert(value != null);
-    this._workItemQueueLengthAverage = value;
-  }
-
-  /**
    * Exceptions associated with cache entries.
    */
   List<String> get cacheEntryExceptions => _cacheEntryExceptions;
@@ -9546,12 +9528,11 @@
     this._cacheEntryExceptions = value;
   }
 
-  ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, String workItemQueueLengthAverage, List<String> cacheEntryExceptions) {
+  ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
     this.name = name;
     this.explicitFileCount = explicitFileCount;
     this.implicitFileCount = implicitFileCount;
     this.workItemQueueLength = workItemQueueLength;
-    this.workItemQueueLengthAverage = workItemQueueLengthAverage;
     this.cacheEntryExceptions = cacheEntryExceptions;
   }
 
@@ -9584,19 +9565,13 @@
       } else {
         throw jsonDecoder.missingKey(jsonPath, "workItemQueueLength");
       }
-      String workItemQueueLengthAverage;
-      if (json.containsKey("workItemQueueLengthAverage")) {
-        workItemQueueLengthAverage = jsonDecoder.decodeString(jsonPath + ".workItemQueueLengthAverage", json["workItemQueueLengthAverage"]);
-      } else {
-        throw jsonDecoder.missingKey(jsonPath, "workItemQueueLengthAverage");
-      }
       List<String> cacheEntryExceptions;
       if (json.containsKey("cacheEntryExceptions")) {
         cacheEntryExceptions = jsonDecoder.decodeList(jsonPath + ".cacheEntryExceptions", json["cacheEntryExceptions"], jsonDecoder.decodeString);
       } else {
         throw jsonDecoder.missingKey(jsonPath, "cacheEntryExceptions");
       }
-      return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, workItemQueueLengthAverage, cacheEntryExceptions);
+      return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "ContextData", json);
     }
@@ -9608,7 +9583,6 @@
     result["explicitFileCount"] = explicitFileCount;
     result["implicitFileCount"] = implicitFileCount;
     result["workItemQueueLength"] = workItemQueueLength;
-    result["workItemQueueLengthAverage"] = workItemQueueLengthAverage;
     result["cacheEntryExceptions"] = cacheEntryExceptions;
     return result;
   }
@@ -9623,7 +9597,6 @@
           explicitFileCount == other.explicitFileCount &&
           implicitFileCount == other.implicitFileCount &&
           workItemQueueLength == other.workItemQueueLength &&
-          workItemQueueLengthAverage == other.workItemQueueLengthAverage &&
           listEqual(cacheEntryExceptions, other.cacheEntryExceptions, (String a, String b) => a == b);
     }
     return false;
@@ -9636,7 +9609,6 @@
     hash = JenkinsSmiHash.combine(hash, explicitFileCount.hashCode);
     hash = JenkinsSmiHash.combine(hash, implicitFileCount.hashCode);
     hash = JenkinsSmiHash.combine(hash, workItemQueueLength.hashCode);
-    hash = JenkinsSmiHash.combine(hash, workItemQueueLengthAverage.hashCode);
     hash = JenkinsSmiHash.combine(hash, cacheEntryExceptions.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
@@ -14093,6 +14065,7 @@
  *   GET_REACHABLE_SOURCES_INVALID_FILE
  *   INVALID_ANALYSIS_ROOT
  *   INVALID_EXECUTION_CONTEXT
+ *   INVALID_FILE_PATH_FORMAT
  *   INVALID_OVERLAY_CHANGE
  *   INVALID_PARAMETER
  *   INVALID_REQUEST
@@ -14166,6 +14139,12 @@
   static const INVALID_EXECUTION_CONTEXT = const RequestErrorCode._("INVALID_EXECUTION_CONTEXT");
 
   /**
+   * The format of the given file path is invalid, e.g. is not absolute and
+   * normalized.
+   */
+  static const INVALID_FILE_PATH_FORMAT = const RequestErrorCode._("INVALID_FILE_PATH_FORMAT");
+
+  /**
    * An "analysis.updateContent" request contained a ChangeContentOverlay
    * object which can't be applied, due to an edit having an offset or length
    * that is out of range.
@@ -14260,7 +14239,7 @@
   /**
    * A list containing all of the enum values that are defined.
    */
-  static const List<RequestErrorCode> VALUES = const <RequestErrorCode>[CONTENT_MODIFIED, FILE_NOT_ANALYZED, FORMAT_INVALID_FILE, FORMAT_WITH_ERRORS, GET_ERRORS_INVALID_FILE, GET_NAVIGATION_INVALID_FILE, GET_REACHABLE_SOURCES_INVALID_FILE, INVALID_ANALYSIS_ROOT, INVALID_EXECUTION_CONTEXT, INVALID_OVERLAY_CHANGE, INVALID_PARAMETER, INVALID_REQUEST, NO_INDEX_GENERATED, ORGANIZE_DIRECTIVES_ERROR, REFACTORING_REQUEST_CANCELLED, SERVER_ALREADY_STARTED, SERVER_ERROR, SORT_MEMBERS_INVALID_FILE, SORT_MEMBERS_PARSE_ERRORS, UNANALYZED_PRIORITY_FILES, UNKNOWN_REQUEST, UNKNOWN_SOURCE, UNSUPPORTED_FEATURE];
+  static const List<RequestErrorCode> VALUES = const <RequestErrorCode>[CONTENT_MODIFIED, FILE_NOT_ANALYZED, FORMAT_INVALID_FILE, FORMAT_WITH_ERRORS, GET_ERRORS_INVALID_FILE, GET_NAVIGATION_INVALID_FILE, GET_REACHABLE_SOURCES_INVALID_FILE, INVALID_ANALYSIS_ROOT, INVALID_EXECUTION_CONTEXT, INVALID_FILE_PATH_FORMAT, INVALID_OVERLAY_CHANGE, INVALID_PARAMETER, INVALID_REQUEST, NO_INDEX_GENERATED, ORGANIZE_DIRECTIVES_ERROR, REFACTORING_REQUEST_CANCELLED, SERVER_ALREADY_STARTED, SERVER_ERROR, SORT_MEMBERS_INVALID_FILE, SORT_MEMBERS_PARSE_ERRORS, UNANALYZED_PRIORITY_FILES, UNKNOWN_REQUEST, UNKNOWN_SOURCE, UNSUPPORTED_FEATURE];
 
   final String name;
 
@@ -14286,6 +14265,8 @@
         return INVALID_ANALYSIS_ROOT;
       case "INVALID_EXECUTION_CONTEXT":
         return INVALID_EXECUTION_CONTEXT;
+      case "INVALID_FILE_PATH_FORMAT":
+        return INVALID_FILE_PATH_FORMAT;
       case "INVALID_OVERLAY_CHANGE":
         return INVALID_OVERLAY_CHANGE;
       case "INVALID_PARAMETER":
diff --git a/pkg/analysis_server/lib/plugin/protocol/protocol.dart b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
index 5617efc..9daa9f0 100644
--- a/pkg/analysis_server/lib/plugin/protocol/protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/protocol.dart
@@ -441,6 +441,15 @@
                 "Invalid execution context: $contextId"));
 
   /**
+   * Initialize a newly created instance to represent the
+   * INVALID_FILE_PATH_FORMAT error condition.
+   */
+  Response.invalidFilePathFormat(Request request, path)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.INVALID_FILE_PATH_FORMAT,
+                'Invalid file path format: $path'));
+
+  /**
    * Initialize a newly created instance to represent an error condition caused
    * by a [request] that had invalid parameter.  [path] is the path to the
    * invalid parameter, in Javascript notation (e.g. "foo.bar" means that the
diff --git a/pkg/analysis_server/lib/src/analysis_logger.dart b/pkg/analysis_server/lib/src/analysis_logger.dart
index bc2276e..8b9c9b6 100644
--- a/pkg/analysis_server/lib/src/analysis_logger.dart
+++ b/pkg/analysis_server/lib/src/analysis_logger.dart
@@ -47,11 +47,6 @@
   }
 
   @override
-  void logError2(String message, Object exception) {
-    baseLogger.severe(message, exception);
-  }
-
-  @override
   void logInformation(String message, [CaughtException exception]) {
     if (exception == null) {
       baseLogger.info(message);
@@ -59,9 +54,4 @@
       baseLogger.info(message, exception.exception, exception.stackTrace);
     }
   }
-
-  @override
-  void logInformation2(String message, Object exception) {
-    baseLogger.info(message, exception);
-  }
 }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 6a5ace1..f72f051 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -72,7 +72,7 @@
    * The version of the analysis server. The value should be replaced
    * automatically during the build.
    */
-  static final String VERSION = '1.12.0';
+  static final String VERSION = '1.14.0';
 
   /**
    * The number of milliseconds to perform operations before inserting
@@ -185,8 +185,8 @@
    * A table mapping [AnalysisContext]s to the completers that should be
    * completed when analysis of this context is finished.
    */
-  Map<AnalysisContext,
-          Completer<AnalysisDoneReason>> contextAnalysisDoneCompleters =
+  Map<AnalysisContext, Completer<AnalysisDoneReason>>
+      contextAnalysisDoneCompleters =
       new HashMap<AnalysisContext, Completer<AnalysisDoneReason>>();
 
   /**
@@ -732,6 +732,15 @@
   }
 
   /**
+   * Return `true` if the given path is a valid `FilePath`.
+   *
+   * This means that it is absolute and normalized.
+   */
+  bool isValidFilePath(String path) {
+    return resourceProvider.absolutePathContext.isValid(path);
+  }
+
+  /**
    * Returns a [Future] completing when [file] has been completely analyzed, in
    * particular, all its errors have been computed.  The future is completed
    * with an [AnalysisDoneReason] indicating what caused the file's analysis to
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 061cc23..15e3c80 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -539,7 +539,7 @@
    */
   void processOptionsForContext(ContextInfo info, Folder folder,
       {bool optionsRemoved: false}) {
-    Map<String, YamlNode> options;
+    Map<String, Object> options;
     try {
       options = analysisOptionsProvider.getOptions(folder);
     } catch (_) {
@@ -550,6 +550,24 @@
       return;
     }
 
+    // In case options files are removed, revert to defaults.
+    if (optionsRemoved) {
+      // Start with defaults.
+      info.context.analysisOptions = new AnalysisOptionsImpl();
+
+      // Apply inherited options.
+      options = _getEmbeddedOptions(info.context);
+      if (options != null) {
+        configureContextOptions(info.context, options);
+      }
+    } else {
+      // Check for embedded options.
+      YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
+      if (embeddedOptions != null) {
+        options = new Merger().merge(embeddedOptions, options);
+      }
+    }
+
     // Notify options processors.
     AnalysisEngine.instance.optionsPlugin.optionsProcessors
         .forEach((OptionsProcessor p) {
@@ -562,34 +580,19 @@
       }
     });
 
-    // In case options files are removed, revert to defaults.
-    if (optionsRemoved) {
-      // Start with defaults.
-      info.context.analysisOptions = new AnalysisOptionsImpl();
+    configureContextOptions(info.context, options);
 
-      // Apply inherited options.
-      YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
-      if (embeddedOptions != null) {
-        configureContextOptions(info.context, embeddedOptions);
-      }
+    // Nothing more to do.
+    if (options == null) {
       return;
     }
 
-    // Check for embedded options.
-    YamlMap embeddedOptions = _getEmbeddedOptions(info.context);
-    if (embeddedOptions != null) {
-      options = new Merger().merge(embeddedOptions, options);
-    }
-
-    // Analysis options are processed 'in-line'.
     var analyzer = options[AnalyzerOptions.analyzer];
     if (analyzer is! Map) {
-      // No options for analyzer.
+      // Done.
       return;
     }
 
-    configureContextOptions(info.context, options);
-
     // Set ignore patterns.
     YamlList exclude = analyzer[AnalyzerOptions.exclude];
     if (exclude != null) {
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index f1bdf14..19cf98e 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -65,7 +65,8 @@
           if (errorInfo == null) {
             server.sendResponse(new Response.getErrorsInvalidFile(request));
           } else {
-            errors = doAnalysisError_listFromEngine(
+            engine.AnalysisContext context = server.getAnalysisContext(file);
+            errors = doAnalysisError_listFromEngine(context,
                 errorInfo.lineInfo, errorInfo.errors);
             server.sendResponse(
                 new AnalysisGetErrorsResult(errors).toResponse(request.id));
@@ -175,8 +176,9 @@
     if (pair.context == null || pair.source == null) {
       return new Response.getReachableSourcesInvalidFile(request);
     }
-    Map<String, List<String>> sources = new ReachableSourceCollector(
-        pair.source, pair.context).collectSources();
+    Map<String, List<String>> sources =
+        new ReachableSourceCollector(pair.source, pair.context)
+            .collectSources();
     return new AnalysisGetReachableSourcesResult(sources)
         .toResponse(request.id);
   }
@@ -245,9 +247,22 @@
    */
   Response setAnalysisRoots(Request request) {
     var params = new AnalysisSetAnalysisRootsParams.fromRequest(request);
+    List<String> includedPathList = params.included;
+    List<String> excludedPathList = params.excluded;
+    // validate
+    for (String path in includedPathList) {
+      if (!server.isValidFilePath(path)) {
+        return new Response.invalidFilePathFormat(request, path);
+      }
+    }
+    for (String path in excludedPathList) {
+      if (!server.isValidFilePath(path)) {
+        return new Response.invalidFilePathFormat(request, path);
+      }
+    }
     // continue in server
-    server.setAnalysisRoots(request.id, params.included, params.excluded,
-        params.packageRoots == null ? {} : params.packageRoots);
+    server.setAnalysisRoots(request.id, includedPathList, excludedPathList,
+        params.packageRoots ?? <String, String>{});
     return new AnalysisSetAnalysisRootsResult().toResponse(request.id);
   }
 
@@ -347,8 +362,8 @@
 class AnalysisDomainImpl implements AnalysisDomain {
   final AnalysisServer server;
 
-  final Map<ResultDescriptor,
-          StreamController<engine.ComputedResult>> controllers =
+  final Map<ResultDescriptor, StreamController<engine.ComputedResult>>
+      controllers =
       <ResultDescriptor, StreamController<engine.ComputedResult>>{};
 
   AnalysisDomainImpl(this.server) {
diff --git a/pkg/analysis_server/lib/src/domain_diagnostic.dart b/pkg/analysis_server/lib/src/domain_diagnostic.dart
index 5d30d92..e9bd0c3 100644
--- a/pkg/analysis_server/lib/src/domain_diagnostic.dart
+++ b/pkg/analysis_server/lib/src/domain_diagnostic.dart
@@ -2,20 +2,17 @@
 // 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 src.domain_diagnostic;
+library analysis_server.src.domain_diagnostic;
 
-import 'dart:async';
 import 'dart:collection';
 import 'dart:core' hide Resource;
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/utilities/average.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisCache, AnalysisContextImpl;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
 import 'package:analyzer/src/task/driver.dart';
@@ -36,20 +33,12 @@
   /// The analysis server that is using this handler to process requests.
   final AnalysisServer server;
 
-  /// The sampler tracking rolling work queue length averages.
-  Sampler sampler;
-
   /// Initialize a newly created handler to handle requests for the given
   /// [server].
   DiagnosticDomainHandler(this.server);
 
   /// Answer the `diagnostic.diagnostics` request.
   Response computeDiagnostics(Request request) {
-    // Initialize sampler if needed.
-    if (sampler == null) {
-      sampler = new Sampler(server);
-    }
-
     List<ContextData> infos = <ContextData>[];
     server.folderMap.forEach((Folder folder, AnalysisContext context) {
       infos.add(extractData(folder, context));
@@ -63,11 +52,9 @@
     int explicitFiles = 0;
     int implicitFiles = 0;
     int workItems = 0;
-    String workItemAverage = '-1';
     Set<String> exceptions = new HashSet<String>();
     if (context is AnalysisContextImpl) {
       workItems = _workItemCount(context);
-      workItemAverage = sampler.getAverage(folder)?.toString() ?? '-1';
       var cache = context.analysisCache;
       if (cache is AnalysisCache) {
         Set<AnalysisTarget> countedTargets = new HashSet<AnalysisTarget>();
@@ -92,7 +79,7 @@
       }
     }
     return new ContextData(context.name, explicitFiles, implicitFiles,
-        workItems, workItemAverage, exceptions.toList());
+        workItems, exceptions.toList());
   }
 
   @override
@@ -108,83 +95,3 @@
     return null;
   }
 }
-
-/// Keeps track of a moving average of work item queue lengths mapped to
-/// contexts.
-///
-/// Sampling terminates after [maxSampleCount], if no one expresses interest
-/// by calling [resetTimerCountdown].
-class Sampler {
-  /// Timer interval.
-  static const Duration duration = const Duration(seconds: 1);
-
-  /// Maximum number of samples taken between calls to [reset].
-  static const int maxSampleCount = 30;
-
-  /// Current sample count.
-  int sampleCount = 0;
-
-  /// The shared timer.
-  Timer timer;
-
-  /// Map of contexts (tracked as folders to avoid leaks) to averages.
-  /// TOOD(pq): consider adding GC to remove mappings for deleted folders
-  Map<Folder, Average> averages = new HashMap<Folder, Average>();
-
-  final AnalysisServer server;
-  Sampler(this.server) {
-    start();
-    _sample();
-  }
-
-  /// Get the average for the context associated with the given [folder].
-  num getAverage(Folder folder) {
-    resetTimerCountdown();
-    return averages[folder].value;
-  }
-
-  /// Check if we're currently sampling.
-  bool isSampling() => timer?.isActive ?? false;
-
-  /// Reset counter.
-  void resetTimerCountdown() {
-    sampleCount = 0;
-  }
-
-  /// Start sampling.
-  void start() {
-    // No need to (re)start if already sampling.
-    if (isSampling()) {
-      return;
-    }
-    timer = new Timer.periodic(duration, (Timer timer) {
-      _sample();
-      if (sampleCount++ >= maxSampleCount) {
-        timer.cancel();
-      }
-    });
-  }
-
-  /// Stop sampling.
-  void stop() {
-    timer.cancel();
-  }
-
-  /// Take a sample.
-  void _sample() {
-    try {
-      server.folderMap.forEach((Folder folder, AnalysisContext context) {
-        if (context is AnalysisContextImpl) {
-          Average average = averages[folder];
-          if (average == null) {
-            average = new Average();
-            averages[folder] = average;
-          }
-          average.addSample(_workItemCount(context));
-        }
-      });
-    } on Exception {
-      stop();
-    }
-  }
-}
diff --git a/pkg/analysis_server/lib/src/domain_execution.dart b/pkg/analysis_server/lib/src/domain_execution.dart
index c2f8a5a..3988de2 100644
--- a/pkg/analysis_server/lib/src/domain_execution.dart
+++ b/pkg/analysis_server/lib/src/domain_execution.dart
@@ -161,8 +161,7 @@
       String filePath = source.fullName;
       // check files
       bool isDartFile = notice.resolvedDartUnit != null;
-      bool isHtmlFile = notice.resolvedHtmlUnit != null;
-      if (!isDartFile && !isHtmlFile) {
+      if (!isDartFile) {
         return;
       }
       // prepare context
@@ -184,10 +183,6 @@
         server.sendNotification(
             new ExecutionLaunchDataParams(filePath, kind: kind)
                 .toNotification());
-      } else if (isHtmlFile) {
-        List<Source> libraries = context.getLibrariesReferencedFromHtml(source);
-        server.sendNotification(new ExecutionLaunchDataParams(filePath,
-            referencedFiles: _getFullNames(libraries)).toNotification());
       }
     });
   }
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 1865146..93ad959 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -250,15 +250,20 @@
     if (!engine.AnalysisEngine.isDartFileName(file)) {
       return new Response.sortMembersInvalidFile(request);
     }
-    // prepare resolved units
-    List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
-    if (units.isEmpty) {
+    // prepare location
+    ContextSourcePair contextSource = server.getContextSourcePair(file);
+    engine.AnalysisContext context = contextSource.context;
+    Source source = contextSource.source;
+    if (context == null || source == null) {
       return new Response.sortMembersInvalidFile(request);
     }
-    // prepare context
-    CompilationUnit unit = units.first;
-    engine.AnalysisContext context = unit.element.context;
-    Source source = unit.element.source;
+    // prepare parsed unit
+    CompilationUnit unit;
+    try {
+      unit = context.parseCompilationUnit(source);
+    } catch (e) {
+      return new Response.sortMembersInvalidFile(request);
+    }
     // check if there are scan/parse errors in the file
     engine.AnalysisErrorInfo errors = context.getErrors(source);
     int numScanParseErrors = _getNumberOfScanParseErrors(errors.errors);
diff --git a/pkg/analysis_server/lib/src/get_handler.dart b/pkg/analysis_server/lib/src/get_handler.dart
deleted file mode 100644
index fbf70a1..0000000
--- a/pkg/analysis_server/lib/src/get_handler.dart
+++ /dev/null
@@ -1,1655 +0,0 @@
-// 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 analysis_server.src.get_handler;
-
-import 'dart:async';
-import 'dart:collection';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:math';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
-import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/domain_completion.dart';
-import 'package:analysis_server/src/domain_execution.dart';
-import 'package:analysis_server/src/operation/operation.dart';
-import 'package:analysis_server/src/operation/operation_analysis.dart';
-import 'package:analysis_server/src/operation/operation_queue.dart';
-import 'package:analysis_server/src/services/index/index.dart';
-import 'package:analysis_server/src/services/index/local_index.dart';
-import 'package:analysis_server/src/services/index/store/split_store.dart';
-import 'package:analysis_server/src/socket_server.dart';
-import 'package:analysis_server/src/status/ast_writer.dart';
-import 'package:analysis_server/src/status/element_writer.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/task/model.dart' as newTask;
-import 'package:plugin/plugin.dart';
-
-/**
- * A function that can be used to generate HTML output into the given [buffer].
- * The HTML that is generated must be valid (special characters must already be
- * encoded).
- */
-typedef void HtmlGenerator(StringBuffer buffer);
-
-/**
- * Instances of the class [GetHandler] handle GET requests.
- */
-class GetHandler {
-  /**
-   * The path used to request overall performance information.
-   */
-  static const String ANALYSIS_PERFORMANCE_PATH = '/perf/analysis';
-
-  /**
-   * The path used to request information about a element model.
-   */
-  static const String AST_PATH = '/ast';
-
-  /**
-   * The path used to request information about the cache entry corresponding
-   * to a single file.
-   */
-  static const String CACHE_ENTRY_PATH = '/cache_entry';
-
-  /**
-   * The path used to request the list of source files in a certain cache
-   * state.
-   */
-  static const String CACHE_STATE_PATH = '/cache_state';
-
-  /**
-   * The path used to request code completion information.
-   */
-  static const String COMPLETION_PATH = '/completion';
-
-  /**
-   * The path used to request communication performance information.
-   */
-  static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
-
-  /**
-   * The path used to request information about a specific context.
-   */
-  static const String CONTEXT_PATH = '/context';
-
-  /**
-   * The path used to request information about a element model.
-   */
-  static const String ELEMENT_PATH = '/element';
-
-  /**
-   * The path used to request information about elements with the given name.
-   */
-  static const String INDEX_ELEMENT_BY_NAME = '/index/element-by-name';
-
-  /**
-   * The path used to request an overlay contents.
-   */
-  static const String OVERLAY_PATH = '/overlay';
-
-  /**
-   * The path used to request overlays information.
-   */
-  static const String OVERLAYS_PATH = '/overlays';
-
-  /**
-   * The path used to request the status of the analysis server as a whole.
-   */
-  static const String STATUS_PATH = '/status';
-
-  /**
-   * Query parameter used to represent the context to search for, when
-   * accessing [CACHE_ENTRY_PATH] or [CACHE_STATE_PATH].
-   */
-  static const String CONTEXT_QUERY_PARAM = 'context';
-
-  /**
-   * Query parameter used to represent the descriptor to search for, when
-   * accessing [CACHE_STATE_PATH].
-   */
-  static const String DESCRIPTOR_QUERY_PARAM = 'descriptor';
-
-  /**
-   * Query parameter used to represent the name of elements to search for, when
-   * accessing [INDEX_ELEMENT_BY_NAME].
-   */
-  static const String INDEX_ELEMENT_NAME = 'name';
-
-  /**
-   * Query parameter used to represent the path of an overlayed file.
-   */
-  static const String PATH_PARAM = 'path';
-
-  /**
-   * Query parameter used to represent the source to search for, when accessing
-   * [CACHE_ENTRY_PATH].
-   */
-  static const String SOURCE_QUERY_PARAM = 'entry';
-
-  /**
-   * Query parameter used to represent the cache state to search for, when
-   * accessing [CACHE_STATE_PATH].
-   */
-  static const String STATE_QUERY_PARAM = 'state';
-
-  static final ContentType _htmlContent =
-      new ContentType("text", "html", charset: "utf-8");
-
-  /**
-   * The socket server whose status is to be reported on.
-   */
-  SocketServer _server;
-
-  /**
-   * Buffer containing strings printed by the analysis server.
-   */
-  List<String> _printBuffer;
-
-  /**
-   * Contents of overlay files.
-   */
-  final Map<String, String> _overlayContents = <String, String>{};
-
-  /**
-   * Initialize a newly created handler for GET requests.
-   */
-  GetHandler(this._server, this._printBuffer);
-
-  /**
-   * Return the active [CompletionDomainHandler]
-   * or `null` if either analysis server is not running
-   * or there is no completion domain handler.
-   */
-  CompletionDomainHandler get _completionDomainHandler {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return null;
-    }
-    return analysisServer.handlers
-        .firstWhere((h) => h is CompletionDomainHandler, orElse: () => null);
-  }
-
-  /**
-   * Handle a GET request received by the HTTP server.
-   */
-  void handleGetRequest(HttpRequest request) {
-    String path = request.uri.path;
-    if (path == STATUS_PATH) {
-      _returnServerStatus(request);
-    } else if (path == ANALYSIS_PERFORMANCE_PATH) {
-      _returnAnalysisPerformance(request);
-    } else if (path == AST_PATH) {
-      _returnAst(request);
-    } else if (path == CACHE_STATE_PATH) {
-      _returnCacheState(request);
-    } else if (path == CACHE_ENTRY_PATH) {
-      _returnCacheEntry(request);
-    } else if (path == COMPLETION_PATH) {
-      _returnCompletionInfo(request);
-    } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
-      _returnCommunicationPerformance(request);
-    } else if (path == CONTEXT_PATH) {
-      _returnContextInfo(request);
-    } else if (path == ELEMENT_PATH) {
-      _returnElement(request);
-    } else if (path == INDEX_ELEMENT_BY_NAME) {
-      _returnIndexElementByName(request);
-    } else if (path == OVERLAY_PATH) {
-      _returnOverlayContents(request);
-    } else if (path == OVERLAYS_PATH) {
-      _returnOverlaysInfo(request);
-    } else {
-      _returnUnknownRequest(request);
-    }
-  }
-
-  /**
-   * Return the folder being managed by the given [analysisServer] that matches
-   * the given [contextFilter], or `null` if there is none.
-   */
-  Folder _findFolder(AnalysisServer analysisServer, String contextFilter) {
-    return analysisServer.folderMap.keys.firstWhere(
-        (Folder folder) => folder.path == contextFilter,
-        orElse: () => null);
-  }
-
-  /**
-   * Return `true` if the given analysis [context] has at least one entry with
-   * an exception.
-   */
-  bool _hasException(AnalysisContextImpl context) {
-    bool hasException = false;
-    context.visitCacheItems((Source source, SourceEntry sourceEntry,
-        DataDescriptor rowDesc, CacheState state) {
-      if (sourceEntry.exception != null) {
-        hasException = true;
-      }
-    });
-    return hasException;
-  }
-
-  /**
-   * Return the folder in the [folderMap] with which the given [context] is
-   * associated.
-   */
-  Folder _keyForValue(
-      Map<Folder, AnalysisContext> folderMap, AnalysisContext context) {
-    for (Folder folder in folderMap.keys) {
-      if (folderMap[folder] == context) {
-        return folder;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return a response displaying overall performance information.
-   */
-  void _returnAnalysisPerformance(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server is not running');
-    }
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Analysis Performance', [],
-          (StringBuffer buffer) {
-        buffer.write('<h3>Analysis Performance</h3>');
-
-        //
-        // Write performance tags.
-        //
-        {
-          buffer.write('<p><b>Time spent in each phase of analysis</b></p>');
-          buffer.write(
-              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-          _writeRow(buffer, ['Time (in ms)', 'Percent', 'Analysis Phase'],
-              header: true);
-          // prepare sorted tags
-          List<PerformanceTag> tags = PerformanceTag.all.toList();
-          tags.remove(ServerPerformanceStatistics.idle);
-          tags.sort((a, b) => b.elapsedMs - a.elapsedMs);
-          // prepare total time
-          int totalTime = 0;
-          tags.forEach((PerformanceTag tag) {
-            totalTime += tag.elapsedMs;
-          });
-          // write rows
-          void writeRow(PerformanceTag tag) {
-            double percent = (tag.elapsedMs * 100) / totalTime;
-            String percentStr = '${percent.toStringAsFixed(2)}%';
-            _writeRow(buffer, [tag.elapsedMs, percentStr, tag.label],
-                classes: ["right", "right", null]);
-          }
-          tags.forEach(writeRow);
-          buffer.write('</table>');
-        }
-
-        //
-        // Write new task model timing information.
-        //
-        if (AnalysisEngine.instance.useTaskModel) {
-          buffer.write('<p><b>Task performace data</b></p>');
-          buffer.write(
-              '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-          _writeRow(
-              buffer,
-              [
-                'Task Name',
-                'Count',
-                'Total Time (in ms)',
-                'Average Time (in ms)'
-              ],
-              header: true);
-
-          Map<Type, int> countMap = newTask.AnalysisTask.countMap;
-          Map<Type, Stopwatch> stopwatchMap = newTask.AnalysisTask.stopwatchMap;
-          List<Type> taskClasses = stopwatchMap.keys.toList();
-          taskClasses.sort((Type first, Type second) =>
-              first.toString().compareTo(second.toString()));
-          int totalTime = 0;
-          taskClasses.forEach((Type taskClass) {
-            int count = countMap[taskClass];
-            if (count == null) {
-              count = 0;
-            }
-            int taskTime = stopwatchMap[taskClass].elapsedMilliseconds;
-            totalTime += taskTime;
-            _writeRow(buffer, [
-              taskClass.toString(),
-              count,
-              taskTime,
-              count <= 0 ? '-' : (taskTime / count).toStringAsFixed(3)
-            ], classes: [
-              null,
-              "right",
-              "right",
-              "right"
-            ]);
-          });
-          _writeRow(buffer, ['Total', '-', totalTime, '-'],
-              classes: [null, "right", "right", "right"]);
-          buffer.write('</table>');
-        }
-
-        //
-        // Write old task model transition information.
-        //
-        {
-          Map<DataDescriptor, Map<CacheState, int>> transitionMap =
-              SourceEntry.transitionMap;
-          buffer.write(
-              '<p><b>Number of times a state transitioned to VALID (grouped by descriptor)</b></p>');
-          if (transitionMap.isEmpty) {
-            buffer.write('<p>none</p>');
-          } else {
-            List<DataDescriptor> descriptors = transitionMap.keys.toList();
-            descriptors.sort((DataDescriptor first, DataDescriptor second) =>
-                first.toString().compareTo(second.toString()));
-            for (DataDescriptor key in descriptors) {
-              Map<CacheState, int> countMap = transitionMap[key];
-              List<CacheState> oldStates = countMap.keys.toList();
-              oldStates.sort((CacheState first, CacheState second) =>
-                  first.toString().compareTo(second.toString()));
-              buffer.write('<p>${key.toString()}</p>');
-              buffer.write(
-                  '<table style="border-collapse: separate; border-spacing: 10px 5px;">');
-              _writeRow(buffer, ['Count', 'Previous State'], header: true);
-              for (CacheState state in oldStates) {
-                _writeRow(buffer, [countMap[state], state.toString()],
-                    classes: ["right", null]);
-              }
-              buffer.write('</table>');
-            }
-          }
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about an AST structure.
-   */
-  void _returnAst(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
-    if (sourceUri == null) {
-      return _returnFailure(
-          request, 'Query parameter $SOURCE_QUERY_PARAM required');
-    }
-
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - AST Structure',
-          ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) {
-        Source source = context.sourceFactory.forUri(sourceUri);
-        if (source == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        SourceEntry entry = context.getReadableSourceEntryOrNull(source);
-        if (entry == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        CompilationUnit ast = (entry as DartEntry).anyParsedCompilationUnit;
-        if (ast == null) {
-          buffer.write('<p>null</p>');
-          return;
-        }
-        AstWriter writer = new AstWriter(buffer);
-        ast.accept(writer);
-        if (writer.exceptions.isNotEmpty) {
-          buffer.write('<h3>Exceptions while creating page</h3>');
-          for (CaughtException exception in writer.exceptions) {
-            _writeException(buffer, exception);
-          }
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about a single source file in the
-   * cache.
-   */
-  void _returnCacheEntry(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
-    if (sourceUri == null) {
-      return _returnFailure(
-          request, 'Query parameter $SOURCE_QUERY_PARAM required');
-    }
-
-    List<Folder> allContexts = <Folder>[];
-    Map<Folder, SourceEntry> entryMap = new HashMap<Folder, SourceEntry>();
-    analysisServer.folderMap
-        .forEach((Folder folder, AnalysisContextImpl context) {
-      Source source = context.sourceFactory.forUri(sourceUri);
-      if (source != null) {
-        SourceEntry entry = context.getReadableSourceEntryOrNull(source);
-        if (entry != null) {
-          allContexts.add(folder);
-          entryMap[folder] = entry;
-        }
-      }
-    });
-    allContexts.sort((Folder firstFolder, Folder secondFolder) =>
-        firstFolder.path.compareTo(secondFolder.path));
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Cache Entry',
-          ['Context: $contextFilter', 'File: $sourceUri'], (HttpResponse) {
-        buffer.write('<h3>Analyzing Contexts</h3><p>');
-        bool first = true;
-        allContexts.forEach((Folder folder) {
-          if (first) {
-            first = false;
-          } else {
-            buffer.write('<br>');
-          }
-          AnalysisContextImpl analyzingContext =
-              analysisServer.folderMap[folder];
-          if (analyzingContext == context) {
-            buffer.write(folder.path);
-          } else {
-            buffer.write(makeLink(
-                CACHE_ENTRY_PATH,
-                {
-                  CONTEXT_QUERY_PARAM: folder.path,
-                  SOURCE_QUERY_PARAM: sourceUri
-                },
-                HTML_ESCAPE.convert(folder.path)));
-          }
-          if (entryMap[folder].explicitlyAdded) {
-            buffer.write(' (explicit)');
-          } else {
-            buffer.write(' (implicit)');
-          }
-        });
-        buffer.write('</p>');
-
-        SourceEntry entry = entryMap[folder];
-        if (entry == null) {
-          buffer.write('<p>Not being analyzed in this context.</p>');
-          return;
-        }
-        Map<String, String> linkParameters = <String, String>{
-          CONTEXT_QUERY_PARAM: folder.path,
-          SOURCE_QUERY_PARAM: sourceUri
-        };
-
-        buffer.write('<h3>Library Independent</h3>');
-        _writeDescriptorTable(buffer, entry.descriptors, entry.getState,
-            entry.getValue, linkParameters);
-        if (entry is DartEntry) {
-          for (Source librarySource in entry.containingLibraries) {
-            String libraryName = HTML_ESCAPE.convert(librarySource.fullName);
-            buffer.write('<h3>In library $libraryName:</h3>');
-            _writeDescriptorTable(
-                buffer,
-                entry.libraryDescriptors,
-                (DataDescriptor descriptor) =>
-                    entry.getStateInLibrary(descriptor, librarySource),
-                (DataDescriptor descriptor) =>
-                    entry.getValueInLibrary(descriptor, librarySource),
-                linkParameters);
-          }
-        }
-        if (entry.exception != null) {
-          buffer.write('<h3>Exception</h3>');
-          _writeException(buffer, entry.exception);
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response indicating the set of source files in a certain cache
-   * state.
-   */
-  void _returnCacheState(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    // Figure out which context is being searched within.
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    // Figure out what CacheState is being searched for.
-    String stateQueryParam = request.uri.queryParameters[STATE_QUERY_PARAM];
-    if (stateQueryParam == null) {
-      return _returnFailure(
-          request, 'Query parameter $STATE_QUERY_PARAM required');
-    }
-    CacheState stateFilter = null;
-    for (CacheState value in CacheState.values) {
-      if (value.toString() == stateQueryParam) {
-        stateFilter = value;
-      }
-    }
-    if (stateFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $STATE_QUERY_PARAM is invalid');
-    }
-    // Figure out which descriptor is being searched for.
-    String descriptorFilter =
-        request.uri.queryParameters[DESCRIPTOR_QUERY_PARAM];
-    if (descriptorFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $DESCRIPTOR_QUERY_PARAM required');
-    }
-
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-    List<String> links = <String>[];
-    context.visitCacheItems((Source source, SourceEntry dartEntry,
-        DataDescriptor rowDesc, CacheState state) {
-      if (state != stateFilter || rowDesc.toString() != descriptorFilter) {
-        return;
-      }
-      String link = makeLink(
-          CACHE_ENTRY_PATH,
-          {
-            CONTEXT_QUERY_PARAM: folder.path,
-            SOURCE_QUERY_PARAM: source.uri.toString()
-          },
-          HTML_ESCAPE.convert(source.fullName));
-      links.add(link);
-    });
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Cache Search', [
-        'Context: $contextFilter',
-        'Descriptor: ${HTML_ESCAPE.convert(descriptorFilter)}',
-        'State: ${HTML_ESCAPE.convert(stateQueryParam)}'
-      ], (StringBuffer buffer) {
-        buffer.write('<p>${links.length} files found</p>');
-        buffer.write('<ul>');
-        links.forEach((String link) {
-          buffer.write('<li>$link</li>');
-        });
-        buffer.write('</ul>');
-      });
-    });
-  }
-
-  /**
-   * Return a response displaying overall performance information.
-   */
-  void _returnCommunicationPerformance(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server is not running');
-    }
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Communication Performance', [],
-          (StringBuffer buffer) {
-        buffer.write('<h3>Communication Performance</h3>');
-        _writeTwoColumns(buffer, (StringBuffer buffer) {
-          ServerPerformance perf = analysisServer.performanceDuringStartup;
-          int requestCount = perf.requestCount;
-          num averageLatency = requestCount > 0
-              ? (perf.requestLatency / requestCount).round()
-              : 0;
-          int maximumLatency = perf.maxLatency;
-          num slowRequestPercent = requestCount > 0
-              ? (perf.slowRequestCount * 100 / requestCount).round()
-              : 0;
-          buffer.write('<h4>Startup</h4>');
-          buffer.write('<table>');
-          _writeRow(buffer, [requestCount, 'requests'],
-              classes: ["right", null]);
-          _writeRow(buffer, [averageLatency, 'ms average latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
-              classes: ["right", null]);
-          if (analysisServer.performanceAfterStartup != null) {
-            int startupTime = analysisServer.performanceAfterStartup.startTime -
-                perf.startTime;
-            _writeRow(
-                buffer, [startupTime, 'ms for initial analysis to complete']);
-          }
-          buffer.write('</table>');
-        }, (StringBuffer buffer) {
-          ServerPerformance perf = analysisServer.performanceAfterStartup;
-          if (perf == null) {
-            return;
-          }
-          int requestCount = perf.requestCount;
-          num averageLatency = requestCount > 0
-              ? (perf.requestLatency * 10 / requestCount).round() / 10
-              : 0;
-          int maximumLatency = perf.maxLatency;
-          num slowRequestPercent = requestCount > 0
-              ? (perf.slowRequestCount * 100 / requestCount).round()
-              : 0;
-          buffer.write('<h4>Current</h4>');
-          buffer.write('<table>');
-          _writeRow(buffer, [requestCount, 'requests'],
-              classes: ["right", null]);
-          _writeRow(buffer, [averageLatency, 'ms average latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [maximumLatency, 'ms maximum latency'],
-              classes: ["right", null]);
-          _writeRow(buffer, [slowRequestPercent, '% > 150 ms latency'],
-              classes: ["right", null]);
-          buffer.write('</table>');
-        });
-      });
-    });
-  }
-
-  /**
-   * Return a response displaying code completion information.
-   */
-  void _returnCompletionInfo(HttpRequest request) {
-    String value = request.requestedUri.queryParameters['index'];
-    int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Completion Stats', [],
-          (StringBuffer buffer) {
-        _writeCompletionPerformanceDetail(buffer, index);
-        _writeCompletionPerformanceList(buffer);
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about a single source file in the
-   * cache.
-   */
-  void _returnContextInfo(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-
-    List<String> priorityNames;
-    List<String> explicitNames = <String>[];
-    List<String> implicitNames = <String>[];
-    Map<String, String> links = new HashMap<String, String>();
-    List<CaughtException> exceptions = <CaughtException>[];
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-    priorityNames = context.prioritySources
-        .map((Source source) => source.fullName)
-        .toList();
-    context.visitCacheItems((Source source, SourceEntry sourceEntry,
-        DataDescriptor rowDesc, CacheState state) {
-      String sourceName = source.fullName;
-      if (!links.containsKey(sourceName)) {
-        CaughtException exception = sourceEntry.exception;
-        if (exception != null) {
-          exceptions.add(exception);
-        }
-        String link = makeLink(
-            CACHE_ENTRY_PATH,
-            {
-              CONTEXT_QUERY_PARAM: folder.path,
-              SOURCE_QUERY_PARAM: source.uri.toString()
-            },
-            sourceName,
-            exception != null);
-        if (sourceEntry.explicitlyAdded) {
-          explicitNames.add(sourceName);
-        } else {
-          implicitNames.add(sourceName);
-        }
-        links[sourceName] = link;
-      }
-    });
-    explicitNames.sort();
-    implicitNames.sort();
-
-    _overlayContents.clear();
-    context.visitContentCache((String fullName, int stamp, String contents) {
-      _overlayContents[fullName] = contents;
-    });
-
-    void _writeFiles(
-        StringBuffer buffer, String title, List<String> fileNames) {
-      buffer.write('<h3>$title</h3>');
-      if (fileNames == null || fileNames.isEmpty) {
-        buffer.write('<p>None</p>');
-      } else {
-        buffer.write('<table style="width: 100%">');
-        for (String fileName in fileNames) {
-          buffer.write('<tr><td>');
-          buffer.write(links[fileName]);
-          buffer.write('</td><td>');
-          if (_overlayContents.containsKey(fileName)) {
-            buffer.write(
-                makeLink(OVERLAY_PATH, {PATH_PARAM: fileName}, 'overlay'));
-          }
-          buffer.write('</td></tr>');
-        }
-        buffer.write('</table>');
-      }
-    }
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(
-          buffer, 'Analysis Server - Context', ['Context: $contextFilter'],
-          (StringBuffer buffer) {
-        List headerRowText = ['Context'];
-        headerRowText.addAll(CacheState.values);
-        buffer.write('<h3>Summary</h3>');
-        buffer.write('<table>');
-        _writeRow(buffer, headerRowText, header: true);
-        AnalysisContextStatistics statistics = context.statistics;
-        statistics.cacheRows.forEach((AnalysisContextStatistics_CacheRow row) {
-          List rowText = [row.name];
-          for (CacheState state in CacheState.values) {
-            String text = row.getCount(state).toString();
-            Map<String, String> params = <String, String>{
-              STATE_QUERY_PARAM: state.toString(),
-              CONTEXT_QUERY_PARAM: folder.path,
-              DESCRIPTOR_QUERY_PARAM: row.name
-            };
-            rowText.add(makeLink(CACHE_STATE_PATH, params, text));
-          }
-          _writeRow(buffer, rowText, classes: [null, "right"]);
-        });
-        buffer.write('</table>');
-
-        _writeFiles(buffer, 'Priority Files', priorityNames);
-        _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
-        _writeFiles(buffer, 'Implicitly Analyzed Files', implicitNames);
-
-        buffer.write('<h3>Exceptions</h3>');
-        if (exceptions.isEmpty) {
-          buffer.write('<p>None</p>');
-        } else {
-          exceptions.forEach((CaughtException exception) {
-            _writeException(buffer, exception);
-          });
-        }
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about an element structure.
-   */
-  void _returnElement(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
-    if (contextFilter == null) {
-      return _returnFailure(
-          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
-    }
-    Folder folder = _findFolder(analysisServer, contextFilter);
-    if (folder == null) {
-      return _returnFailure(request, 'Invalid context: $contextFilter');
-    }
-    String sourceUri = request.uri.queryParameters[SOURCE_QUERY_PARAM];
-    if (sourceUri == null) {
-      return _returnFailure(
-          request, 'Query parameter $SOURCE_QUERY_PARAM required');
-    }
-
-    AnalysisContextImpl context = analysisServer.folderMap[folder];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Element Model', [
-        'Context: $contextFilter',
-        'File: $sourceUri'
-      ], (StringBuffer buffer) {
-        Source source = context.sourceFactory.forUri(sourceUri);
-        if (source == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        SourceEntry entry = context.getReadableSourceEntryOrNull(source);
-        if (entry == null) {
-          buffer.write('<p>Not found.</p>');
-          return;
-        }
-        LibraryElement element = entry.getValue(DartEntry.ELEMENT);
-        if (element == null) {
-          buffer.write('<p>null</p>');
-          return;
-        }
-        element.accept(new ElementWriter(buffer));
-      });
-    });
-  }
-
-  void _returnFailure(HttpRequest request, String message) {
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Failure', [],
-          (StringBuffer buffer) {
-        buffer.write(HTML_ESCAPE.convert(message));
-      });
-    });
-  }
-
-  /**
-   * Return a response containing information about elements with the given
-   * name.
-   */
-  Future _returnIndexElementByName(HttpRequest request) async {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server not running');
-    }
-    Index index = analysisServer.index;
-    if (index == null) {
-      return _returnFailure(request, 'Indexing is disabled');
-    }
-    String name = request.uri.queryParameters[INDEX_ELEMENT_NAME];
-    if (name == null) {
-      return _returnFailure(
-          request, 'Query parameter $INDEX_ELEMENT_NAME required');
-    }
-    if (index is LocalIndex) {
-      Map<List<String>, List<InspectLocation>> relations =
-          await index.findElementsByName(name);
-      _writeResponse(request, (StringBuffer buffer) {
-        _writePage(buffer, 'Analysis Server - Index Elements', ['Name: $name'],
-            (StringBuffer buffer) {
-          buffer.write('<table border="1">');
-          _writeRow(buffer, ['Element', 'Relationship', 'Location'],
-              header: true);
-          relations.forEach(
-              (List<String> elementPath, List<InspectLocation> relations) {
-            String elementLocation = elementPath.join(' ');
-            relations.forEach((InspectLocation location) {
-              var relString = location.relationship.identifier;
-              var locString = '${location.path} offset=${location.offset} '
-                  'length=${location.length} flags=${location.flags}';
-              _writeRow(buffer, [elementLocation, relString, locString]);
-            });
-          });
-          buffer.write('</table>');
-        });
-      });
-    } else {
-      return _returnFailure(request, 'LocalIndex expected, but $index found.');
-    }
-  }
-
-  void _returnOverlayContents(HttpRequest request) {
-    String path = request.requestedUri.queryParameters[PATH_PARAM];
-    if (path == null) {
-      return _returnFailure(request, 'Query parameter $PATH_PARAM required');
-    }
-    String contents = _overlayContents[path];
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Overlay', [],
-          (StringBuffer buffer) {
-        buffer.write('<pre>${HTML_ESCAPE.convert(contents)}</pre>');
-      });
-    });
-  }
-
-  /**
-   * Return a response displaying overlays information.
-   */
-  void _returnOverlaysInfo(HttpRequest request) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    if (analysisServer == null) {
-      return _returnFailure(request, 'Analysis server is not running');
-    }
-
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Overlays', [],
-          (StringBuffer buffer) {
-        buffer.write('<table border="1">');
-        _overlayContents.clear();
-        ContentCache overlayState = analysisServer.overlayState;
-        overlayState.accept((String fullName, int stamp, String contents) {
-          buffer.write('<tr>');
-          String link =
-              makeLink(OVERLAY_PATH, {PATH_PARAM: fullName}, fullName);
-          DateTime time = new DateTime.fromMillisecondsSinceEpoch(stamp);
-          _writeRow(buffer, [link, time]);
-          _overlayContents[fullName] = contents;
-        });
-        int count = _overlayContents.length;
-        buffer.write('<tr><td colspan="2">Total: $count entries.</td></tr>');
-        buffer.write('</table>');
-      });
-    });
-  }
-
-  /**
-   * Return a response indicating the status of the analysis server.
-   */
-  void _returnServerStatus(HttpRequest request) {
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server - Status', [], (StringBuffer buffer) {
-        if (_writeServerStatus(buffer)) {
-          _writeAnalysisStatus(buffer);
-          _writeEditStatus(buffer);
-          _writeExecutionStatus(buffer);
-          _writePluginStatus(buffer);
-          _writeRecentOutput(buffer);
-        }
-      });
-    });
-  }
-
-  /**
-   * Return an error in response to an unrecognized request received by the HTTP
-   * server.
-   */
-  void _returnUnknownRequest(HttpRequest request) {
-    _writeResponse(request, (StringBuffer buffer) {
-      _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
-        buffer.write('<h3>Pages</h3>');
-        buffer.write('<p>');
-        buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer
-            .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
-        buffer.write('</p>');
-      });
-    });
-  }
-
-  /**
-   * Return a two digit decimal representation of the given non-negative integer
-   * [value].
-   */
-  String _twoDigit(int value) {
-    if (value < 10) {
-      return '0$value';
-    }
-    return value.toString();
-  }
-
-  /**
-   * Write the status of the analysis domain (on the main status page) to the
-   * given [buffer] object.
-   */
-  void _writeAnalysisStatus(StringBuffer buffer) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    Map<Folder, AnalysisContext> folderMap = analysisServer.folderMap;
-    List<Folder> folders = folderMap.keys.toList();
-    folders.sort((Folder first, Folder second) =>
-        first.shortName.compareTo(second.shortName));
-    AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
-    ServerOperationQueue operationQueue = analysisServer.operationQueue;
-
-    buffer.write('<h3>Analysis Domain</h3>');
-    _writeTwoColumns(buffer, (StringBuffer buffer) {
-      if (operationQueue.isEmpty) {
-        buffer.write('<p>Status: Done analyzing</p>');
-      } else {
-        ServerOperation operation = operationQueue.peek();
-        if (operation is PerformAnalysisOperation) {
-          Folder folder = _keyForValue(folderMap, operation.context);
-          if (folder == null) {
-            buffer.write('<p>Status: Analyzing in unmapped context</p>');
-          } else {
-            buffer.write('<p>Status: Analyzing in ${folder.path}</p>');
-          }
-        } else {
-          buffer.write('<p>Status: Analyzing</p>');
-        }
-      }
-
-      buffer.write('<p><b>Analysis Contexts</b></p>');
-      buffer.write('<p>');
-      bool first = true;
-      folders.forEach((Folder folder) {
-        if (first) {
-          first = false;
-        } else {
-          buffer.write('<br>');
-        }
-        String key = folder.shortName;
-        buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path},
-            key, _hasException(folderMap[folder])));
-      });
-      buffer.write('</p>');
-
-      buffer.write('<p><b>Options</b></p>');
-      buffer.write('<p>');
-      _writeOption(
-          buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
-      _writeOption(buffer, 'Cache size', options.cacheSize);
-      _writeOption(
-          buffer, 'Enable strict call checks', options.enableStrictCallChecks);
-      _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
-      _writeOption(buffer, 'Generate hints', options.hint);
-      _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
-      _writeOption(buffer, 'Generate errors in implicit files',
-          options.generateImplicitErrors);
-      _writeOption(
-          buffer, 'Generate errors in SDK files', options.generateSdkErrors);
-      _writeOption(buffer, 'Incremental resolution', options.incremental);
-      _writeOption(buffer, 'Incremental resolution with API changes',
-          options.incrementalApi);
-      _writeOption(buffer, 'Preserve comments', options.preserveComments,
-          last: true);
-      buffer.write('</p>');
-      int freq = AnalysisServer.performOperationDelayFreqency;
-      String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
-      buffer.write('<p><b>perform operation delay:</b> $delay</p>');
-
-      buffer.write('<p><b>Performance Data</b></p>');
-      buffer.write('<p>');
-      buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
-      buffer.write('</p>');
-    }, (StringBuffer buffer) {
-      _writeSubscriptionMap(
-          buffer, AnalysisService.VALUES, analysisServer.analysisServices);
-    });
-  }
-
-  /**
-   * Write performance information about a specific completion request
-   * to the given [buffer] object.
-   */
-  void _writeCompletionPerformanceDetail(StringBuffer buffer, int index) {
-    CompletionDomainHandler handler = _completionDomainHandler;
-    CompletionPerformance performance;
-    if (handler != null) {
-      List<CompletionPerformance> list = handler.performanceList;
-      if (list != null && list.isNotEmpty) {
-        performance = list[max(0, min(list.length - 1, index))];
-      }
-    }
-    if (performance == null) {
-      buffer.write('<h3>Completion Performance Detail</h3>');
-      buffer.write('<p>No completions yet</p>');
-      return;
-    }
-    buffer.write('<h3>Completion Performance Detail</h3>');
-    buffer.write('<p>${performance.startTimeAndMs} for ${performance.source}');
-    buffer.write('<table>');
-    _writeRow(buffer, ['Elapsed', '', 'Operation'], header: true);
-    performance.operations.forEach((OperationPerformance op) {
-      String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
-      _writeRow(buffer, [elapsed, '&nbsp;&nbsp;', op.name]);
-    });
-    buffer.write('</table>');
-    buffer.write('<p><b>Compute Cache Performance</b>: ');
-    if (handler.computeCachePerformance == null) {
-      buffer.write('none');
-    } else {
-      int elapsed = handler.computeCachePerformance.elapsedInMilliseconds;
-      Source source = handler.computeCachePerformance.source;
-      buffer.write(' $elapsed ms for $source');
-    }
-    buffer.write('</p>');
-  }
-
-  /**
-   * Write a table showing summary information for the last several
-   * completion requests to the given [buffer] object.
-   */
-  void _writeCompletionPerformanceList(StringBuffer buffer) {
-    CompletionDomainHandler handler = _completionDomainHandler;
-    buffer.write('<h3>Completion Performance List</h3>');
-    if (handler == null) {
-      return;
-    }
-    buffer.write('<table>');
-    _writeRow(
-        buffer,
-        [
-          'Start Time',
-          '',
-          'First (ms)',
-          '',
-          'Complete (ms)',
-          '',
-          '# Notifications',
-          '',
-          '# Suggestions',
-          '',
-          'Snippet'
-        ],
-        header: true);
-    int index = 0;
-    for (CompletionPerformance performance in handler.performanceList) {
-      String link = makeLink(COMPLETION_PATH, {'index': '$index'},
-          '${performance.startTimeAndMs}');
-      _writeRow(buffer, [
-        link,
-        '&nbsp;&nbsp;',
-        performance.firstNotificationInMilliseconds,
-        '&nbsp;&nbsp;',
-        performance.elapsedInMilliseconds,
-        '&nbsp;&nbsp;',
-        performance.notificationCount,
-        '&nbsp;&nbsp;',
-        performance.suggestionCount,
-        '&nbsp;&nbsp;',
-        HTML_ESCAPE.convert(performance.snippet)
-      ]);
-      ++index;
-    }
-
-    buffer.write('</table>');
-    buffer.write('''
-      <p><strong>First (ms)</strong> - the number of milliseconds
-        from when completion received the request until the first notification
-        with completion results was queued for sending back to the client.
-      <p><strong>Complete (ms)</strong> - the number of milliseconds
-        from when completion received the request until the final notification
-        with completion results was queued for sending back to the client.
-      <p><strong># Notifications</strong> - the total number of notifications
-        sent to the client with completion results for this request.
-      <p><strong># Suggestions</strong> - the number of suggestions
-        sent to the client in the first notification, followed by a comma,
-        followed by the number of suggestions send to the client
-        in the last notification. If there is only one notification,
-        then there will be only one number in this column.''');
-  }
-
-  /**
-   * Generate a table showing the cache values corresponding to the given
-   * [descriptors], using [getState] to get the cache state corresponding to
-   * each descriptor, and [getValue] to get the cached value corresponding to
-   * each descriptor.  Append the resulting HTML to the given [buffer]. The
-   * [linkParameters] will be used if the value is too large to be displayed on
-   * the current page and needs to be linked to a separate page.
-   */
-  void _writeDescriptorTable(
-      StringBuffer buffer,
-      List<DataDescriptor> descriptors,
-      CacheState getState(DataDescriptor),
-      dynamic getValue(DataDescriptor),
-      Map<String, String> linkParameters) {
-    buffer.write('<dl>');
-    for (DataDescriptor descriptor in descriptors) {
-      String descriptorName = HTML_ESCAPE.convert(descriptor.toString());
-      String descriptorState =
-          HTML_ESCAPE.convert(getState(descriptor).toString());
-      buffer.write('<dt>$descriptorName ($descriptorState)</dt><dd>');
-      try {
-        _writeValueAsHtml(buffer, getValue(descriptor), linkParameters);
-      } catch (exception) {
-        buffer.write('(${HTML_ESCAPE.convert(exception.toString())})');
-      }
-      buffer.write('</dd>');
-    }
-    buffer.write('</dl>');
-  }
-
-  /**
-   * Write the status of the edit domain (on the main status page) to the given
-   * [buffer].
-   */
-  void _writeEditStatus(StringBuffer buffer) {
-    buffer.write('<h3>Edit Domain</h3>');
-    _writeTwoColumns(buffer, (StringBuffer buffer) {
-      buffer.write('<p><b>Performance Data</b></p>');
-      buffer.write('<p>');
-      buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
-      buffer.write('</p>');
-    }, (StringBuffer buffer) {});
-  }
-
-  /**
-   * Write a representation of the given [caughtException] to the given
-   * [buffer]. If [isCause] is `true`, then the exception was a cause for
-   * another exception.
-   */
-  void _writeException(StringBuffer buffer, CaughtException caughtException,
-      {bool isCause: false}) {
-    Object exception = caughtException.exception;
-
-    if (exception is AnalysisException) {
-      buffer.write('<p>');
-      if (isCause) {
-        buffer.write('Caused by ');
-      }
-      buffer.write(exception.message);
-      buffer.write('</p>');
-      _writeStackTrace(buffer, caughtException.stackTrace);
-      CaughtException cause = exception.cause;
-      if (cause != null) {
-        buffer.write('<blockquote>');
-        _writeException(buffer, cause, isCause: true);
-        buffer.write('</blockquote>');
-      }
-    } else {
-      buffer.write('<p>');
-      if (isCause) {
-        buffer.write('Caused by ');
-      }
-      buffer.write(exception.toString());
-      buffer.write('<p>');
-      _writeStackTrace(buffer, caughtException.stackTrace);
-    }
-  }
-
-  /**
-   * Write the status of the execution domain (on the main status page) to the
-   * given [buffer].
-   */
-  void _writeExecutionStatus(StringBuffer buffer) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    ExecutionDomainHandler handler = analysisServer.handlers.firstWhere(
-        (RequestHandler handler) => handler is ExecutionDomainHandler,
-        orElse: () => null);
-    Set<ExecutionService> services = new Set<ExecutionService>();
-    if (handler.onFileAnalyzed != null) {
-      services.add(ExecutionService.LAUNCH_DATA);
-    }
-
-    if (handler != null) {
-      buffer.write('<h3>Execution Domain</h3>');
-      _writeTwoColumns(buffer, (StringBuffer buffer) {
-        _writeSubscriptionList(buffer, ExecutionService.VALUES, services);
-      }, (StringBuffer buffer) {});
-    }
-  }
-
-  /**
-   * Write a representation of an analysis option with the given [name] and
-   * [value] to the given [buffer]. The option should be separated from other
-   * options unless the [last] flag is true, indicating that this is the last
-   * option in the list of options.
-   */
-  void _writeOption(StringBuffer buffer, String name, Object value,
-      {bool last: false}) {
-    buffer.write(name);
-    buffer.write(' = ');
-    buffer.write(value.toString());
-    if (!last) {
-      buffer.write('<br>');
-    }
-  }
-
-  /**
-   * Write a standard HTML page to the given [buffer]. The page will have the
-   * given [title] and a body that is generated by the given [body] generator.
-   */
-  void _writePage(StringBuffer buffer, String title, List<String> subtitles,
-      HtmlGenerator body) {
-    DateTime now = new DateTime.now();
-    String date = "${now.month}/${now.day}/${now.year}";
-    String time =
-        "${now.hour}:${_twoDigit(now.minute)}:${_twoDigit(now.second)}.${now.millisecond}";
-
-    buffer.write('<!DOCTYPE html>');
-    buffer.write('<html>');
-    buffer.write('<head>');
-    buffer.write('<meta charset="utf-8">');
-    buffer.write(
-        '<meta name="viewport" content="width=device-width, initial-scale=1.0">');
-    buffer.write('<title>$title</title>');
-    buffer.write('<style>');
-    buffer.write('a {color: #0000DD; text-decoration: none;}');
-    buffer.write('a:link.error {background-color: #FFEEEE;}');
-    buffer.write('a:visited.error {background-color: #FFEEEE;}');
-    buffer.write('a:hover.error {background-color: #FFEEEE;}');
-    buffer.write('a:active.error {background-color: #FFEEEE;}');
-    buffer.write(
-        'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
-    buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
-//    response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
-    buffer.write(
-        'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
-    buffer.write('td.column {vertical-align: top; width: 50%;}');
-    buffer.write('td.right {text-align: right;}');
-    buffer.write('</style>');
-    buffer.write('</head>');
-
-    buffer.write('<body>');
-    buffer.write(
-        '<h2>$title <small><small>(as of $time on $date)</small></small></h2>');
-    if (subtitles != null && subtitles.isNotEmpty) {
-      buffer.write('<blockquote>');
-      bool first = true;
-      for (String subtitle in subtitles) {
-        if (first) {
-          first = false;
-        } else {
-          buffer.write('<br>');
-        }
-        buffer.write('<b>');
-        buffer.write(subtitle);
-        buffer.write('</b>');
-      }
-      buffer.write('</blockquote>');
-    }
-    try {
-      body(buffer);
-    } catch (exception, stackTrace) {
-      buffer.write('<h3>Exception while creating page</h3>');
-      _writeException(buffer, new CaughtException(exception, stackTrace));
-    }
-    buffer.write('</body>');
-    buffer.write('</html>');
-  }
-
-  /**
-   * Write the recent output section (on the main status page) to the given
-   * [buffer] object.
-   */
-  void _writePluginStatus(StringBuffer buffer) {
-    void writePlugin(Plugin plugin) {
-      buffer.write(plugin.uniqueIdentifier);
-      buffer.write(' (');
-      buffer.write(plugin.runtimeType);
-      buffer.write(')<br>');
-    }
-    buffer.write('<h3>Plugin Status</h3><p>');
-    writePlugin(AnalysisEngine.instance.enginePlugin);
-    writePlugin(_server.serverPlugin);
-    for (Plugin plugin in _server.analysisServer.userDefinedPlugins) {
-      writePlugin(plugin);
-    }
-    buffer.write('<p>');
-  }
-
-  /**
-   * Write the recent output section (on the main status page) to the given
-   * [buffer] object.
-   */
-  void _writeRecentOutput(StringBuffer buffer) {
-    buffer.write('<h3>Recent Output</h3>');
-    String output = HTML_ESCAPE.convert(_printBuffer.join('\n'));
-    if (output.isEmpty) {
-      buffer.write('<i>none</i>');
-    } else {
-      buffer.write('<pre>');
-      buffer.write(output);
-      buffer.write('</pre>');
-    }
-  }
-
-  void _writeResponse(HttpRequest request, HtmlGenerator writePage) {
-    HttpResponse response = request.response;
-    response.statusCode = HttpStatus.OK;
-    response.headers.contentType = _htmlContent;
-    try {
-      StringBuffer buffer = new StringBuffer();
-      try {
-        writePage(buffer);
-      } catch (exception, stackTrace) {
-        buffer.clear();
-        _writePage(buffer, 'Internal Exception', [], (StringBuffer buffer) {
-          _writeException(buffer, new CaughtException(exception, stackTrace));
-        });
-      }
-      response.write(buffer.toString());
-    } finally {
-      response.close();
-    }
-  }
-
-  /**
-   * Write a single row within a table to the given [buffer]. The row will have
-   * one cell for each of the [columns], and will be a header row if [header] is
-   * `true`.
-   */
-  void _writeRow(StringBuffer buffer, List<Object> columns,
-      {bool header: false, List<String> classes}) {
-    buffer.write('<tr>');
-    int count = columns.length;
-    int maxClassIndex = classes == null ? 0 : classes.length - 1;
-    for (int i = 0; i < count; i++) {
-      String classAttribute = '';
-      if (classes != null) {
-        String className = classes[min(i, maxClassIndex)];
-        if (className != null) {
-          classAttribute = ' class="$className"';
-        }
-      }
-      if (header) {
-        buffer.write('<th$classAttribute>');
-      } else {
-        buffer.write('<td$classAttribute>');
-      }
-      buffer.write(columns[i]);
-      if (header) {
-        buffer.write('</th>');
-      } else {
-        buffer.write('</td>');
-      }
-    }
-    buffer.write('</tr>');
-  }
-
-  /**
-   * Write the status of the service domain (on the main status page) to the
-   * given [response] object.
-   */
-  bool _writeServerStatus(StringBuffer buffer) {
-    AnalysisServer analysisServer = _server.analysisServer;
-    Set<ServerService> services = analysisServer.serverServices;
-
-    buffer.write('<h3>Server Domain</h3>');
-    _writeTwoColumns(buffer, (StringBuffer buffer) {
-      if (analysisServer == null) {
-        buffer.write('Status: <span style="color:red">Not running</span>');
-        return false;
-      }
-      buffer.write('<p>');
-      buffer.write('Status: Running<br>');
-      buffer.write('Instrumentation: ');
-      if (AnalysisEngine.instance.instrumentationService.isActive) {
-        buffer.write('<span style="color:red">Active</span>');
-      } else {
-        buffer.write('Inactive');
-      }
-      buffer.write('<br>');
-      buffer.write('Version: ');
-      buffer.write(AnalysisServer.VERSION);
-      buffer.write('</p>');
-
-      buffer.write('<p><b>Performance Data</b></p>');
-      buffer.write('<p>');
-      buffer.write(makeLink(
-          COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
-      buffer.write('</p>');
-    }, (StringBuffer buffer) {
-      _writeSubscriptionList(buffer, ServerService.VALUES, services);
-    });
-    return true;
-  }
-
-  /**
-   * Write a representation of the given [stackTrace] to the given [buffer].
-   */
-  void _writeStackTrace(StringBuffer buffer, StackTrace stackTrace) {
-    if (stackTrace != null) {
-      String trace = stackTrace.toString().replaceAll('#', '<br>#');
-      if (trace.startsWith('<br>#')) {
-        trace = trace.substring(4);
-      }
-      buffer.write('<p>');
-      buffer.write(trace);
-      buffer.write('</p>');
-    }
-  }
-
-  /**
-   * Given a [service] that could be subscribed to and a set of the services
-   * that are actually subscribed to ([subscribedServices]), write a
-   * representation of the service to the given [buffer].
-   */
-  void _writeSubscriptionInList(
-      StringBuffer buffer, Enum service, Set<Enum> subscribedServices) {
-    if (subscribedServices.contains(service)) {
-      buffer.write('<code>+ </code>');
-    } else {
-      buffer.write('<code>- </code>');
-    }
-    buffer.write(service.name);
-    buffer.write('<br>');
-  }
-
-  /**
-   * Given a [service] that could be subscribed to and a set of paths that are
-   * subscribed to the services ([subscribedPaths]), write a representation of
-   * the service to the given [buffer].
-   */
-  void _writeSubscriptionInMap(
-      StringBuffer buffer, Enum service, Set<String> subscribedPaths) {
-    buffer.write('<p>');
-    buffer.write(service.name);
-    buffer.write('</p>');
-    if (subscribedPaths == null || subscribedPaths.isEmpty) {
-      buffer.write('none');
-    } else {
-      List<String> paths = subscribedPaths.toList();
-      paths.sort();
-      for (String path in paths) {
-        buffer.write('<p>');
-        buffer.write(path);
-        buffer.write('</p>');
-      }
-    }
-  }
-
-  /**
-   * Given a list containing all of the services that can be subscribed to in a
-   * single domain ([allServices]) and a set of the services that are actually
-   * subscribed to ([subscribedServices]), write a representation of the
-   * subscriptions to the given [buffer].
-   */
-  void _writeSubscriptionList(StringBuffer buffer, List<Enum> allServices,
-      Set<Enum> subscribedServices) {
-    buffer.write('<p><b>Subscriptions</b></p>');
-    buffer.write('<p>');
-    for (Enum service in allServices) {
-      _writeSubscriptionInList(buffer, service, subscribedServices);
-    }
-    buffer.write('</p>');
-  }
-
-  /**
-   * Given a list containing all of the services that can be subscribed to in a
-   * single domain ([allServices]) and a set of the services that are actually
-   * subscribed to ([subscribedServices]), write a representation of the
-   * subscriptions to the given [buffer].
-   */
-  void _writeSubscriptionMap(StringBuffer buffer, List<Enum> allServices,
-      Map<Enum, Set<String>> subscribedServices) {
-    buffer.write('<p><b>Subscriptions</b></p>');
-    for (Enum service in allServices) {
-      _writeSubscriptionInMap(buffer, service, subscribedServices[service]);
-    }
-  }
-
-  /**
-   * Write two columns of information to the given [buffer], where the
-   * [leftColumn] and [rightColumn] functions are used to generate the content
-   * of those columns.
-   */
-  void _writeTwoColumns(StringBuffer buffer, HtmlGenerator leftColumn,
-      HtmlGenerator rightColumn) {
-    buffer
-        .write('<table class="column"><tr class="column"><td class="column">');
-    leftColumn(buffer);
-    buffer.write('</td><td class="column">');
-    rightColumn(buffer);
-    buffer.write('</td></tr></table>');
-  }
-
-  /**
-   * Render the given [value] as HTML and append it to the given [buffer]. The
-   * [linkParameters] will be used if the value is too large to be displayed on
-   * the current page and needs to be linked to a separate page.
-   */
-  void _writeValueAsHtml(
-      StringBuffer buffer, Object value, Map<String, String> linkParameters) {
-    if (value == null) {
-      buffer.write('<i>null</i>');
-    } else if (value is String) {
-      buffer.write('<pre>${HTML_ESCAPE.convert(value)}</pre>');
-    } else if (value is List) {
-      buffer.write('List containing ${value.length} entries');
-      buffer.write('<ul>');
-      for (var entry in value) {
-        buffer.write('<li>');
-        _writeValueAsHtml(buffer, entry, linkParameters);
-        buffer.write('</li>');
-      }
-      buffer.write('</ul>');
-    } else if (value is AstNode) {
-      String link =
-          makeLink(AST_PATH, linkParameters, value.runtimeType.toString());
-      buffer.write('<i>$link</i>');
-    } else if (value is Element) {
-      String link =
-          makeLink(ELEMENT_PATH, linkParameters, value.runtimeType.toString());
-      buffer.write('<i>$link</i>');
-    } else {
-      buffer.write(HTML_ESCAPE.convert(value.toString()));
-      buffer.write(' <i>(${value.runtimeType.toString()})</i>');
-    }
-  }
-
-  /**
-   * Create a link to [path] with query parameters [params], with inner HTML
-   * [innerHtml]. If [hasError] is `true`, then the link will have the class
-   * 'error'.
-   */
-  static String makeLink(
-      String path, Map<String, String> params, String innerHtml,
-      [bool hasError = false]) {
-    Uri uri = new Uri(path: path, queryParameters: params);
-    String href = HTML_ESCAPE.convert(uri.toString());
-    String classAttribute = hasError ? ' class="error"' : '';
-    return '<a href="$href"$classAttribute>$innerHtml</a>';
-  }
-}
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index aeb8d03..66fac73 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -21,7 +21,6 @@
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart';
 import 'package:analyzer/src/generated/source.dart';
 
 /**
@@ -152,14 +151,18 @@
   });
 }
 
-void sendAnalysisNotificationErrors(AnalysisServer server, String file,
-    LineInfo lineInfo, List<AnalysisError> errors) {
+void sendAnalysisNotificationErrors(
+    AnalysisServer server,
+    AnalysisContext context,
+    String file,
+    LineInfo lineInfo,
+    List<AnalysisError> errors) {
   _sendNotification(server, () {
     if (errors == null) {
       errors = <AnalysisError>[];
     }
     var serverErrors =
-        protocol.doAnalysisError_listFromEngine(lineInfo, errors);
+        protocol.doAnalysisError_listFromEngine(context, lineInfo, errors);
     var params = new protocol.AnalysisErrorsParams(file, serverErrors);
     server.sendNotification(params.toNotification());
   });
@@ -422,16 +425,6 @@
         server.sendServerErrorNotification(
             'Failed to index Dart file: $file', exception, stackTrace);
       }
-      // HTML
-      try {
-        HtmlUnit htmlUnit = notice.resolvedHtmlUnit;
-        if (htmlUnit != null) {
-          server.addOperation(new _HtmlIndexOperation(context, file, htmlUnit));
-        }
-      } catch (exception, stackTrace) {
-        server.sendServerErrorNotification(
-            'Failed to index HTML file: $file', exception, stackTrace);
-      }
     }
   }
 }
@@ -510,24 +503,6 @@
   }
 }
 
-class _HtmlIndexOperation extends _SingleFileOperation {
-  final HtmlUnit unit;
-
-  _HtmlIndexOperation(AnalysisContext context, String file, this.unit)
-      : super(context, file);
-
-  @override
-  ServerOperationPriority get priority {
-    return ServerOperationPriority.ANALYSIS_INDEX;
-  }
-
-  @override
-  void perform(AnalysisServer server) {
-    Index index = server.index;
-    index.index(context, unit);
-  }
-}
-
 class _NotificationErrorsOperation extends _SingleFileOperation {
   final LineInfo lineInfo;
   final List<AnalysisError> errors;
@@ -543,7 +518,7 @@
 
   @override
   void perform(AnalysisServer server) {
-    sendAnalysisNotificationErrors(server, file, lineInfo, errors);
+    sendAnalysisNotificationErrors(server, context, file, lineInfo, errors);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index 678361f..981b694 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -9,6 +9,7 @@
 import 'package:analysis_server/src/services/correction/fix.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart'
     as engine;
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/ast.dart' as engine;
 import 'package:analyzer/src/generated/element.dart' as engine;
 import 'package:analyzer/src/generated/engine.dart' as engine;
@@ -20,14 +21,29 @@
 export 'package:analysis_server/plugin/protocol/protocol_dart.dart';
 
 /**
- * Returns a list of AnalysisErrors correponding to the given list of Engine
+ * Returns a list of AnalysisErrors corresponding to the given list of Engine
  * errors.
  */
 List<AnalysisError> doAnalysisError_listFromEngine(
-    engine.LineInfo lineInfo, List<engine.AnalysisError> errors) {
-  return errors.map((engine.AnalysisError error) {
-    return newAnalysisError_fromEngine(lineInfo, error);
-  }).toList();
+    engine.AnalysisContext context,
+    engine.LineInfo lineInfo,
+    List<engine.AnalysisError> errors) {
+  List<AnalysisError> serverErrors = <AnalysisError>[];
+  for (engine.AnalysisError error in errors) {
+    ErrorProcessor processor = ErrorProcessor.getProcessor(context, error);
+    if (processor != null) {
+      engine.ErrorSeverity severity = processor.severity;
+      // Errors with null severity are filtered out.
+      if (severity != null) {
+        // Specified severities override.
+        serverErrors
+            .add(newAnalysisError_fromEngine(lineInfo, error, severity));
+      }
+    } else {
+      serverErrors.add(newAnalysisError_fromEngine(lineInfo, error));
+    }
+  }
+  return serverErrors;
 }
 
 /**
@@ -55,7 +71,7 @@
     if (element.kind == engine.ElementKind.SETTER) {
       return null;
     } else {
-      return element.returnType.toString();
+      return element.returnType?.toString();
     }
   } else if (element is engine.VariableElement) {
     engine.DartType type = element.type;
@@ -69,9 +85,12 @@
 
 /**
  * Construct based on error information from the analyzer engine.
+ *
+ * If an [errorSeverity] is specified, it will override the one in [error].
  */
 AnalysisError newAnalysisError_fromEngine(
-    engine.LineInfo lineInfo, engine.AnalysisError error) {
+    engine.LineInfo lineInfo, engine.AnalysisError error,
+    [engine.ErrorSeverity errorSeverity]) {
   engine.ErrorCode errorCode = error.errorCode;
   // prepare location
   Location location;
@@ -90,8 +109,12 @@
     }
     location = new Location(file, offset, length, startLine, startColumn);
   }
+
+  // Deafult to the error's severity if none is specified.
+  errorSeverity ??= errorCode.errorSeverity;
+
   // done
-  var severity = new AnalysisErrorSeverity(errorCode.errorSeverity.name);
+  var severity = new AnalysisErrorSeverity(errorSeverity.name);
   var type = new AnalysisErrorType(errorCode.type.name);
   String message = error.message;
   String correction = error.correction;
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index 816894d..827024b 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -10,6 +10,8 @@
 import 'package:analysis_server/src/provisional/completion/completion_core.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
 import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/source.dart';
 
 export 'package:analysis_server/src/provisional/completion/completion_core.dart'
     show EMPTY_LIST;
@@ -60,27 +62,61 @@
  */
 abstract class DartCompletionRequest extends CompletionRequest {
   /**
+   * Return the expression to the right of the "dot" or "dot dot",
+   * or `null` if this is not a "dot" completion (e.g. `foo.b`).
+   */
+  Expression get dotTarget;
+
+  /**
+   * Return `true` if free standing identifiers should be suggested
+   */
+  bool get includeIdentifiers;
+
+  /**
+   * Return the library element which contains the unit in which the completion
+   * is occurring. This may return `null` if the library cannot be determined
+   * (e.g. unlinked part file).
+   */
+  LibraryElement get libraryElement;
+
+  /**
+   * The source for the library containing the completion request.
+   * This may be different from the source in which the completion is requested
+   * if the completion is being requested in a part file.
+   * This may be `null` if the library for a part file cannot be determined.
+   */
+  Source get librarySource;
+
+  /**
+   * Answer the [DartType] for Object in dart:core
+   */
+  DartType get objectType;
+
+  /**
    * Return the completion target.  This determines what part of the parse tree
    * will receive the newly inserted text.
+   * At a minimum, all declarations in the completion scope in [target.unit]
+   * will be resolved if they can be resolved.
    */
   CompletionTarget get target;
 
   /**
-   * Return a [Future] that completes with a compilation unit in which
-   * all declarations in all scopes containing [target] have been resolved.
-   * The [Future] may return `null` if the unit cannot be resolved
+   * Return a [Future] that completes with a list of directives for the library
+   * in which in which the completion is occurring.
+   * The [Future] may return `null` if the library unit cannot be determined
    * (e.g. unlinked part file).
    * Any information obtained from [target] prior to calling this method
    * should be discarded as it may have changed.
    */
-  Future<CompilationUnit> resolveDeclarationsInScope();
+  Future<List<Directive>> resolveDirectives();
 
   /**
    * Return a [Future] that completes when the element associated with
-   * the given [identifier] is available or if the identifier cannot be resolved
+   * the given [expression] in the target compilation unit is available.
+   * It may also complete if the expression cannot be resolved
    * (e.g. unknown identifier, completion aborted, etc).
    * Any information obtained from [target] prior to calling this method
    * should be discarded as it may have changed.
    */
-  Future resolveIdentifier(SimpleIdentifier identifier);
+  Future resolveExpression(Expression expression);
 }
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
index 014c270..64fecef 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_plugin.dart
@@ -12,6 +12,11 @@
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
 import 'package:plugin/plugin.dart';
 
@@ -77,6 +82,16 @@
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new KeywordContributor());
     registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LibraryMemberContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new LibraryPrefixContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new NamedConstructorContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new StaticMemberContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
+        () => new TypeMemberContributor());
+    registerExtension(DART_COMPLETION_CONTRIBUTOR_EXTENSION_POINT_ID,
         () => new UriContributor());
   }
 
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
index 0cb0035..7762e9e 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
@@ -91,6 +91,11 @@
   final CompilationUnit unit;
 
   /**
+   * The offset within the source at which the completion is being requested.
+   */
+  final int offset;
+
+  /**
    * The context in which the completion is occurring.  This is the AST node
    * which is a direct parent of [entity].
    */
@@ -162,11 +167,11 @@
             Token commentToken = _getContainingCommentToken(entity, offset);
             if (commentToken != null) {
               return new CompletionTarget._(
-                  compilationUnit, containingNode, commentToken, true);
+                  compilationUnit, offset, containingNode, commentToken, true);
             }
             // Target found.
             return new CompletionTarget._(
-                compilationUnit, containingNode, entity, false);
+                compilationUnit, offset, containingNode, entity, false);
           } else {
             // Since entity is a token, we don't need to look inside it; just
             // proceed to the next entity.
@@ -195,12 +200,12 @@
               if (docComment != null) {
                 containingNode = docComment;
               } else {
-                return new CompletionTarget._(
-                    compilationUnit, compilationUnit, commentToken, true);
+                return new CompletionTarget._(compilationUnit, offset,
+                    compilationUnit, commentToken, true);
               }
             }
             return new CompletionTarget._(
-                compilationUnit, containingNode, entity, false);
+                compilationUnit, offset, containingNode, entity, false);
           }
 
           // Otherwise, the completion target is somewhere inside the entity,
@@ -225,7 +230,7 @@
       // Since no completion target was found, we set the completion target
       // entity to null and use the compilationUnit as the parent.
       return new CompletionTarget._(
-          compilationUnit, compilationUnit, null, false);
+          compilationUnit, offset, compilationUnit, null, false);
     }
   }
 
@@ -233,13 +238,30 @@
    * Create a [CompletionTarget] holding the given [containingNode] and
    * [entity].
    */
-  CompletionTarget._(
-      this.unit, AstNode containingNode, Object entity, this.isCommentText)
+  CompletionTarget._(this.unit, this.offset, AstNode containingNode,
+      Object entity, this.isCommentText)
       : this.containingNode = containingNode,
         this.entity = entity,
         this.argIndex = _computeArgIndex(containingNode, entity);
 
   /**
+   * Return `true` if the [containingNode] is a cascade
+   * and the completion insertion is not between the two dots.
+   * For example, `..d^` and `..^d` are considered a cascade
+   * from a completion standpoint, but `.^.d` is not.
+   */
+  bool get isCascade {
+    AstNode node = containingNode;
+    if (node is PropertyAccess) {
+      return node.isCascaded && offset > node.operator.offset + 1;
+    }
+    if (node is MethodInvocation) {
+      return node.isCascaded && offset > node.operator.offset + 1;
+    }
+    return false;
+  }
+
+  /**
    * Return `true` if the target is a functional argument in an argument list.
    * The target [AstNode] hierarchy *must* be resolved for this to work.
    */
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 27fb203..5833af4 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -27,6 +27,7 @@
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:args/args.dart';
 import 'package:linter/src/plugin/linter_plugin.dart';
+import 'package:plugin/manager.dart';
 import 'package:plugin/plugin.dart';
 
 /**
@@ -208,11 +209,6 @@
   static const String CLIENT_VERSION = "client-version";
 
   /**
-   * The name of the option used to disable the use of the new task model.
-   */
-  static const String DISABLE_NEW_TASK_MODEL = "disable-new-task-model";
-
-  /**
    * The name of the option used to enable incremental resolution of API
    * changes.
    */
@@ -398,25 +394,21 @@
         results[CLIENT_VERSION], AnalysisServer.VERSION, defaultSdk.sdkVersion);
     AnalysisEngine.instance.instrumentationService = service;
     //
-    // Enable the new task model, if appropriate.
-    //
-    AnalysisEngine.instance.useTaskModel = !results[DISABLE_NEW_TASK_MODEL];
-    //
     // Process all of the plugins so that extensions are registered.
     //
     ServerPlugin serverPlugin = new ServerPlugin();
     List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
     plugins.add(serverPlugin);
-    plugins.addAll(_userDefinedPlugins);
     plugins.add(linterPlugin);
     plugins.add(linterServerPlugin);
     plugins.add(dartCompletionPlugin);
+    plugins.addAll(_userDefinedPlugins);
 
-    // Defer to the extension manager in AE for plugin registration.
-    AnalysisEngine.instance.userDefinedPlugins = plugins;
-    // Force registration.
-    AnalysisEngine.instance.taskManager;
-
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
     //
     // Create the sockets and start listening for requests.
     //
@@ -480,11 +472,6 @@
     parser.addOption(CLIENT_ID,
         help: "an identifier used to identify the client");
     parser.addOption(CLIENT_VERSION, help: "the version of the client");
-    parser.addFlag(DISABLE_NEW_TASK_MODEL,
-        help: "disable the use of the new task model",
-        defaultsTo: false,
-        hide: true,
-        negatable: false);
     parser.addFlag(ENABLE_INCREMENTAL_RESOLUTION_API,
         help: "enable using incremental resolution for API changes",
         defaultsTo: false,
diff --git a/pkg/analysis_server/lib/src/server/http_server.dart b/pkg/analysis_server/lib/src/server/http_server.dart
index c047d1f..9afabda 100644
--- a/pkg/analysis_server/lib/src/server/http_server.dart
+++ b/pkg/analysis_server/lib/src/server/http_server.dart
@@ -2,16 +2,14 @@
 // 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 http.server;
+library analysis_server.src.server.http_server;
 
 import 'dart:async';
 import 'dart:io';
 
 import 'package:analysis_server/src/channel/web_socket_channel.dart';
-import 'package:analysis_server/src/get_handler.dart';
 import 'package:analysis_server/src/socket_server.dart';
-import 'package:analysis_server/src/status/get_handler.dart' as newHandler;
-import 'package:analyzer/src/generated/engine.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
 
 /**
  * Instances of the class [HttpServer] implement a simple HTTP server. The
@@ -36,11 +34,6 @@
   GetHandler getHandler;
 
   /**
-   * An object that can handle GET requests when the new task model is in use.
-   */
-  newHandler.GetHandler newGetHandler;
-
-  /**
    * Future that is completed with the HTTP server once it is running.
    */
   Future<HttpServer> _server;
@@ -89,17 +82,10 @@
    * Handle a GET request received by the HTTP server.
    */
   void _handleGetRequest(HttpRequest request) {
-    if (AnalysisEngine.instance.useTaskModel) {
-      if (newGetHandler == null) {
-        newGetHandler = new newHandler.GetHandler(socketServer, _printBuffer);
-      }
-      newGetHandler.handleGetRequest(request);
-    } else {
-      if (getHandler == null) {
-        getHandler = new GetHandler(socketServer, _printBuffer);
-      }
-      getHandler.handleGetRequest(request);
+    if (getHandler == null) {
+      getHandler = new GetHandler(socketServer, _printBuffer);
     }
+    getHandler.handleGetRequest(request);
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 46e20aa..29f463b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -87,6 +87,23 @@
 }
 
 /**
+ * Determine if the completion target is the label for a named argument.
+ */
+bool _isEditingNamedArgLabel(DartCompletionRequest request) {
+  AstNode node = request.target.containingNode;
+  if (node is ArgumentList) {
+    var entity = request.target.entity;
+    if (entity is NamedExpression) {
+      int offset = request.offset;
+      if (entity.offset <= offset && offset < entity.end) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+/**
  * Determine if the completion target is an emtpy argument list.
  */
 bool _isEmptyArgList(DartCompletionRequest request) {
@@ -134,7 +151,7 @@
     }
 
     // Resolve the target expression to determine the arguments
-    await request.resolveIdentifier(targetId);
+    await request.resolveExpression(targetId);
     // Gracefully degrade if the element could not be resolved
     // e.g. target changed, completion aborted
     targetId = _getTargetId(request.target.containingNode);
@@ -171,32 +188,35 @@
   }
 
   void _addArgListSuggestion(Iterable<ParameterElement> requiredParam) {
-    StringBuffer completion = new StringBuffer('(');
-    List<String> paramNames = new List<String>();
-    List<String> paramTypes = new List<String>();
-    for (ParameterElement param in requiredParam) {
-      String name = param.name;
-      if (name != null && name.length > 0) {
-        if (completion.length > 1) {
-          completion.write(', ');
-        }
-        completion.write(name);
-        paramNames.add(name);
-        paramTypes.add(_getParamType(param));
-      }
-    }
-    completion.write(')');
-    CompletionSuggestion suggestion = new CompletionSuggestion(
-        CompletionSuggestionKind.ARGUMENT_LIST,
-        DART_RELEVANCE_HIGH,
-        completion.toString(),
-        completion.length,
-        0,
-        false,
-        false);
-    suggestion.parameterNames = paramNames;
-    suggestion.parameterTypes = paramTypes;
-    suggestions.add(suggestion);
+    // DEPRECATED... argument lists are no longer suggested.
+    // See https://github.com/dart-lang/sdk/issues/25197
+
+    // StringBuffer completion = new StringBuffer('(');
+    // List<String> paramNames = new List<String>();
+    // List<String> paramTypes = new List<String>();
+    // for (ParameterElement param in requiredParam) {
+    //   String name = param.name;
+    //   if (name != null && name.length > 0) {
+    //     if (completion.length > 1) {
+    //       completion.write(', ');
+    //     }
+    //     completion.write(name);
+    //     paramNames.add(name);
+    //     paramTypes.add(_getParamType(param));
+    //   }
+    // }
+    // completion.write(')');
+    // CompletionSuggestion suggestion = new CompletionSuggestion(
+    //     CompletionSuggestionKind.ARGUMENT_LIST,
+    //     DART_RELEVANCE_HIGH,
+    //     completion.toString(),
+    //     completion.length,
+    //     0,
+    //     false,
+    //     false);
+    // suggestion.parameterNames = paramNames;
+    // suggestion.parameterTypes = paramTypes;
+    // suggestions.add(suggestion);
   }
 
   void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters) {
@@ -233,7 +253,7 @@
       _addArgListSuggestion(requiredParam);
       return;
     }
-    if (_isAppendingToArgList(request)) {
+    if (_isEditingNamedArgLabel(request) || _isAppendingToArgList(request)) {
       if (requiredCount == 0 || requiredCount < _argCount(request)) {
         _addDefaultParamSuggestions(parameters);
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index cba3bd4..a08b8bb 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -26,20 +26,6 @@
       return EMPTY_LIST;
     }
 
-    // Partially resolve the compilation unit
-    CompilationUnit unit = await request.resolveDeclarationsInScope();
-    // Gracefully degrade if the compilation unit could not be resolved
-    // e.g. detached part file or source change
-    if (unit == null) {
-      return EMPTY_LIST;
-    }
-
-    // Check the target since resolution may have changed it
-    node = request.target.containingNode;
-    if (node is! Combinator) {
-      return EMPTY_LIST;
-    }
-
     // Build list of suggestions
     var directive = node.getAncestor((parent) => parent is NamespaceDirective);
     if (directive is NamespaceDirective) {
@@ -47,7 +33,7 @@
       if (library != null) {
         LibraryElementSuggestionBuilder builder =
             new LibraryElementSuggestionBuilder(
-                request, CompletionSuggestionKind.IDENTIFIER, false, false);
+                library, CompletionSuggestionKind.IDENTIFIER, false, false);
         library.visitChildren(builder);
         return builder.suggestions;
       }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 6f182d8..a635b8c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -18,10 +18,12 @@
 import 'package:analyzer/src/context/context.dart'
     show AnalysisFutureHelper, AnalysisContextImpl;
 import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/task/dart.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
 
 /**
  * [DartCompletionManager] determines if a completion request is Dart specific
@@ -30,24 +32,17 @@
 class DartCompletionManager implements CompletionContributor {
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
-      CompletionRequest request) {
-    if (AnalysisEngine.isDartFileName(request.source.shortName)) {
-      return _computeDartSuggestions(
-          new DartCompletionRequestImpl.forRequest(request));
+      CompletionRequest request) async {
+    if (!AnalysisEngine.isDartFileName(request.source.shortName)) {
+      return EMPTY_LIST;
     }
-    return new Future.value();
-  }
 
-  /**
-   * Return a [Future] that completes with a list of suggestions
-   * for the given completion [request].
-   */
-  Future<List<CompletionSuggestion>> _computeDartSuggestions(
-      DartCompletionRequest request) async {
     // Request Dart specific completions from each contributor
+    DartCompletionRequestImpl dartRequest =
+        await DartCompletionRequestImpl.from(request);
     List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
     for (DartCompletionContributor c in dartCompletionPlugin.contributors) {
-      suggestions.addAll(await c.computeSuggestions(request));
+      suggestions.addAll(await c.computeSuggestions(dartRequest));
     }
     return suggestions;
   }
@@ -59,115 +54,139 @@
 class DartCompletionRequestImpl extends CompletionRequestImpl
     implements DartCompletionRequest {
   /**
-   * The cached completion target or `null` if not computed yet.
+   * Return a [Future] that completes with a newly created completion request
+   * based on the given [request].
    */
-  CompletionTarget _target;
+  static Future<DartCompletionRequest> from(CompletionRequest request) async {
+    Source source = request.source;
+    AnalysisContext context = request.context;
+    CompilationUnit unit = request.context.computeResult(source, PARSED_UNIT);
 
-  /**
-   * `true` if [resolveDeclarationsInScope] has partially resolved the unit
-   * referenced by [target], else `false`.
-   */
-  bool _haveResolveDeclarationsInScope = false;
+    Source libSource;
+    if (unit.directives.any((d) => d is PartOfDirective)) {
+      List<Source> libraries = context.getLibrariesContaining(source);
+      if (libraries.isNotEmpty) {
+        libSource = libraries[0];
+      }
+    } else {
+      libSource = source;
+    }
 
-  /**
-   * Initialize a newly created completion request based on the given request.
-   */
-  factory DartCompletionRequestImpl.forRequest(CompletionRequest request) {
+    // Most (all?) contributors need declarations in scope to be resolved
+    if (libSource != null) {
+      unit = await new AnalysisFutureHelper<CompilationUnit>(context,
+              new LibrarySpecificUnit(libSource, source), RESOLVED_UNIT3)
+          .computeAsync();
+    }
+
     return new DartCompletionRequestImpl._(
         request.context,
         request.resourceProvider,
         request.searchEngine,
+        libSource,
         request.source,
-        request.offset);
+        request.offset,
+        unit);
   }
 
   DartCompletionRequestImpl._(
       AnalysisContext context,
       ResourceProvider resourceProvider,
       SearchEngine searchEngine,
+      this.librarySource,
       Source source,
-      int offset)
-      : super(context, resourceProvider, searchEngine, source, offset);
+      int offset,
+      CompilationUnit unit)
+      : super(context, resourceProvider, searchEngine, source, offset) {
+    _updateTargets(unit);
+  }
+
+  /**
+   * The [DartType] for Object in dart:core
+   */
+  InterfaceType _objectType;
 
   @override
-  CompletionTarget get target {
-    if (_target == null) {
-      CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
-      _target = new CompletionTarget.forOffset(unit, offset);
+  Expression dotTarget;
+
+  @override
+  Source librarySource;
+
+  OpType _opType;
+
+  @override
+  CompletionTarget target;
+
+  @override
+  bool get includeIdentifiers {
+    if (_opType == null) {
+      _opType = new OpType.forCompletion(target, offset);
     }
-    return _target;
+    return !_opType.isPrefixed &&
+        (_opType.includeReturnValueSuggestions ||
+            _opType.includeTypeNameSuggestions ||
+            _opType.includeVoidReturnSuggestions ||
+            _opType.includeConstructorSuggestions);
   }
 
   @override
-  Future<CompilationUnit> resolveDeclarationsInScope() async {
+  LibraryElement get libraryElement {
+    //TODO(danrubel) build the library element rather than all the declarations
     CompilationUnit unit = target.unit;
-    if (_haveResolveDeclarationsInScope) {
-      return unit;
-    }
-
-    // Determine the library source
-    Source librarySource;
-    if (unit.directives.any((d) => d is PartOfDirective)) {
-      List<Source> libraries = context.getLibrariesContaining(source);
-      if (libraries.isEmpty) {
-        return null;
+    if (unit != null) {
+      CompilationUnitElement elem = unit.element;
+      if (elem != null) {
+        return elem.library;
       }
-      librarySource = libraries[0];
-    } else {
-      librarySource = source;
     }
-
-    // Resolve declarations in the target unit
-    CompilationUnit resolvedUnit =
-        await new AnalysisFutureHelper<CompilationUnit>(
-            context,
-            new LibrarySpecificUnit(librarySource, source),
-            RESOLVED_UNIT3).computeAsync();
-
-    // TODO(danrubel) determine if the underlying source has been modified
-    // in a way that invalidates the completion request
-    // and return null
-
-    // Gracefully degrade if unit cannot be resolved
-    if (resolvedUnit == null) {
-      return null;
-    }
-
-    // Recompute the target for the newly resolved unit
-    _target = new CompletionTarget.forOffset(resolvedUnit, offset);
-    _haveResolveDeclarationsInScope = true;
-    return resolvedUnit;
+    return null;
   }
 
   @override
-  Future resolveIdentifier(SimpleIdentifier identifier) async {
-    if (identifier.bestElement != null) {
+  InterfaceType get objectType {
+    if (_objectType == null) {
+      Source coreUri = context.sourceFactory.forUri('dart:core');
+      LibraryElement coreLib = context.getLibraryElement(coreUri);
+      _objectType = coreLib.getType('Object').type;
+    }
+    return _objectType;
+  }
+
+  @override
+  Future<List<Directive>> resolveDirectives() async {
+    CompilationUnit libUnit;
+    if (librarySource == source) {
+      libUnit = target.unit;
+    } else if (librarySource != null) {
+      // TODO(danrubel) only resolve the directives
+      libUnit = await new AnalysisFutureHelper<CompilationUnit>(
+              context,
+              new LibrarySpecificUnit(librarySource, librarySource),
+              RESOLVED_UNIT3)
+          .computeAsync();
+    }
+    return libUnit?.directives;
+  }
+
+  @override
+  Future resolveExpression(Expression expression) async {
+    // Return immediately if the expression has already been resolved
+    if (expression.propagatedType != null) {
       return;
     }
 
-    //TODO(danrubel) resolve the expression or containing method
+    // Gracefully degrade if librarySource cannot be determined
+    if (librarySource == null) {
+      return;
+    }
+
+    // Resolve declarations in the target unit
+    // TODO(danrubel) resolve the expression or containing method
     // rather than the entire complilation unit
-
-    CompilationUnit unit = target.unit;
-
-    // Determine the library source
-    Source librarySource;
-    if (unit.directives.any((d) => d is PartOfDirective)) {
-      List<Source> libraries = context.getLibrariesContaining(source);
-      if (libraries.isEmpty) {
-        return;
-      }
-      librarySource = libraries[0];
-    } else {
-      librarySource = source;
-    }
-
-    // Resolve declarations in the target unit
     CompilationUnit resolvedUnit =
-        await new AnalysisFutureHelper<CompilationUnit>(
-            context,
-            new LibrarySpecificUnit(librarySource, source),
-            RESOLVED_UNIT).computeAsync();
+        await new AnalysisFutureHelper<CompilationUnit>(context,
+                new LibrarySpecificUnit(librarySource, source), RESOLVED_UNIT)
+            .computeAsync();
 
     // TODO(danrubel) determine if the underlying source has been modified
     // in a way that invalidates the completion request
@@ -179,7 +198,35 @@
     }
 
     // Recompute the target for the newly resolved unit
-    _target = new CompletionTarget.forOffset(resolvedUnit, offset);
-    _haveResolveDeclarationsInScope = true;
+    _updateTargets(resolvedUnit);
+  }
+
+  /**
+   * Update the completion [target] and [dotTarget] based on the given [unit].
+   */
+  void _updateTargets(CompilationUnit unit) {
+    _opType = null;
+    dotTarget = null;
+    target = new CompletionTarget.forOffset(unit, offset);
+    AstNode node = target.containingNode;
+    if (node is MethodInvocation) {
+      if (identical(node.methodName, target.entity)) {
+        dotTarget = node.realTarget;
+      } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
+        dotTarget = node.realTarget;
+      }
+    }
+    if (node is PropertyAccess) {
+      if (identical(node.propertyName, target.entity)) {
+        dotTarget = node.realTarget;
+      } else if (node.isCascaded && node.operator.offset + 1 == target.offset) {
+        dotTarget = node.realTarget;
+      }
+    }
+    if (node is PrefixedIdentifier) {
+      if (identical(node.identifier, target.entity)) {
+        dotTarget = node.prefix;
+      }
+    }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
index f708685..3c16a7d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/field_formal_contributor.dart
@@ -20,19 +20,6 @@
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    if (request.target.containingNode is! FieldFormalParameter) {
-      return EMPTY_LIST;
-    }
-
-    // Partially resolve the compilation unit
-    CompilationUnit unit = await request.resolveDeclarationsInScope();
-    // Gracefully degrade if the compilation unit could not be resolved
-    // e.g. detached part file or source change
-    if (unit == null) {
-      return EMPTY_LIST;
-    }
-
-    // Recompute the target since resolution may have changed it
     AstNode node = request.target.containingNode;
     if (node is! FieldFormalParameter) {
       return EMPTY_LIST;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
index fdfb353..2ab41e3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_contributor.dart
@@ -26,26 +26,10 @@
   @override
   Future<List<CompletionSuggestion>> computeSuggestions(
       DartCompletionRequest request) async {
-    // Determine if the target looks like a partial identifier
-    // inside a class declaration
     SimpleIdentifier targetId = _getTargetId(request.target);
     if (targetId == null) {
       return EMPTY_LIST;
     }
-
-    // Partially resolve the compilation unit
-    CompilationUnit unit = await request.resolveDeclarationsInScope();
-    // Gracefully degrade if the compilation unit could not be resolved
-    // e.g. detached part file or source change
-    if (unit == null) {
-      return EMPTY_LIST;
-    }
-
-    // Recompute the target since resolution may have changed it
-    targetId = _getTargetId(request.target);
-    if (targetId == null) {
-      return EMPTY_LIST;
-    }
     ClassDeclaration classDecl =
         targetId.getAncestor((p) => p is ClassDeclaration);
     if (classDecl == null) {
@@ -65,7 +49,7 @@
       // Gracefully degrade if the overridden element has not been resolved.
       if (element.returnType != null) {
         CompletionSuggestion suggestion =
-            _buildSuggestion(request, targetId, unit, element);
+            _buildSuggestion(request, targetId, element);
         if (suggestion != null) {
           suggestions.add(suggestion);
         }
@@ -119,13 +103,10 @@
    * Build a suggestion to replace [targetId] in the given [unit]
    * with an override of the given [element].
    */
-  CompletionSuggestion _buildSuggestion(
-      DartCompletionRequest request,
-      SimpleIdentifier targetId,
-      CompilationUnit unit,
-      ExecutableElement element) {
-    String completion =
-        _buildRepacementText(request.source, targetId, unit, element);
+  CompletionSuggestion _buildSuggestion(DartCompletionRequest request,
+      SimpleIdentifier targetId, ExecutableElement element) {
+    String completion = _buildRepacementText(
+        request.source, targetId, request.target.unit, element);
     if (completion == null || completion.length == 0) {
       return null;
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 57beb27..28de09b 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -13,7 +13,11 @@
 import 'package:analyzer/src/generated/scanner.dart';
 
 const ASYNC = 'async';
+const ASYNC_STAR = 'async*';
 const AWAIT = 'await';
+const SYNC_STAR = 'sync*';
+const YIELD = 'yield';
+const YIELD_STAR = 'yield*';
 
 /**
  * A contributor for calculating `completion.getSuggestions` request results
@@ -47,8 +51,19 @@
 
   @override
   visitArgumentList(ArgumentList node) {
-    if (entity == node.rightParenthesis ||
-        (entity is SimpleIdentifier && node.arguments.contains(entity))) {
+    if (entity == node.rightParenthesis) {
+      _addExpressionKeywords(node);
+      Token previous = (entity as Token).previous;
+      if (previous.isSynthetic) {
+        previous = previous.previous;
+      }
+      if (previous.lexeme == ')') {
+        _addSuggestion2(ASYNC);
+        _addSuggestion2(ASYNC_STAR);
+        _addSuggestion2(SYNC_STAR);
+      }
+    }
+    if (entity is SimpleIdentifier && node.arguments.contains(entity)) {
       _addExpressionKeywords(node);
     }
   }
@@ -69,6 +84,8 @@
         }
         if (previous.lexeme == ')' && next.lexeme == '{') {
           _addSuggestion2(ASYNC);
+          _addSuggestion2(ASYNC_STAR);
+          _addSuggestion2(SYNC_STAR);
         }
       }
     }
@@ -92,6 +109,8 @@
       ClassMember previous = index > 0 ? node.members[index - 1] : null;
       if (previous is MethodDeclaration && previous.body is EmptyFunctionBody) {
         _addSuggestion2(ASYNC);
+        _addSuggestion2(ASYNC_STAR);
+        _addSuggestion2(SYNC_STAR);
       }
     } else {
       _addClassDeclarationKeywords(node);
@@ -138,6 +157,8 @@
           previousMember.functionExpression is FunctionExpression &&
           previousMember.functionExpression.body is EmptyFunctionBody) {
         _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+        _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+        _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
       }
       _addCompilationUnitKeywords();
     }
@@ -200,8 +221,13 @@
   @override
   visitFunctionExpression(FunctionExpression node) {
     if (entity == node.body) {
-      if (!node.body.isAsynchronous) {
+      FunctionBody body = node.body;
+      if (!body.isAsynchronous) {
         _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+        if (body is! ExpressionFunctionBody) {
+          _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+          _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+        }
       }
       if (node.body is EmptyFunctionBody &&
           node.parent is FunctionDeclaration &&
@@ -266,8 +292,14 @@
       if (node.body is EmptyFunctionBody) {
         _addClassBodyKeywords();
         _addSuggestion2(ASYNC);
+        _addSuggestion2(ASYNC_STAR);
+        _addSuggestion2(SYNC_STAR);
       } else {
         _addSuggestion2(ASYNC, relevance: DART_RELEVANCE_HIGH);
+        if (node.body is! ExpressionFunctionBody) {
+          _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+          _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
+        }
       }
     }
   }
@@ -433,6 +465,10 @@
     }
     if (_inAsyncMethodOrFunction(node)) {
       _addSuggestion2(AWAIT);
+    } else if (_inAsyncStarOrSyncStarMethodOrFunction(node)) {
+      _addSuggestion2(AWAIT);
+      _addSuggestion2(YIELD);
+      _addSuggestion2(YIELD_STAR);
     }
     if (_inLoop(node)) {
       _addSuggestions([Keyword.BREAK, Keyword.CONTINUE]);
@@ -481,7 +517,12 @@
 
   bool _inAsyncMethodOrFunction(AstNode node) {
     FunctionBody body = node.getAncestor((n) => n is FunctionBody);
-    return body != null && body.isAsynchronous;
+    return body != null && body.isAsynchronous && body.star == null;
+  }
+
+  bool _inAsyncStarOrSyncStarMethodOrFunction(AstNode node) {
+    FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+    return body != null && body.keyword != null && body.star != null;
   }
 
   bool _inCatchClause(Block node) =>
@@ -506,7 +547,7 @@
 
   bool _inForLoop(AstNode node) =>
       node.getAncestor((p) => p is ForStatement || p is ForEachStatement) !=
-          null;
+      null;
 
   bool _inLoop(AstNode node) =>
       _inDoLoop(node) || _inForLoop(node) || _inWhileLoop(node);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
new file mode 100644
index 0000000..7ecbc64
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -0,0 +1,90 @@
+// 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 services.completion.contributor.dart.library_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating prefixed import library member suggestions
+ * `completion.getSuggestions` request results.
+ */
+class LibraryMemberContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a library prefix
+    if (request.dotTarget is! SimpleIdentifier) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the expression and the containing library
+    await request.resolveExpression(request.dotTarget);
+
+    // Recompute the target since resolution may have changed it
+    Expression targetId = request.dotTarget;
+    if (targetId is SimpleIdentifier && !request.target.isCascade) {
+      Element elem = targetId.bestElement;
+      if (elem is PrefixElement) {
+        List<Directive> directives = await request.resolveDirectives();
+        LibraryElement containingLibrary = request.libraryElement;
+        // Gracefully degrade if the library or directives
+        // could not be determined (e.g. detached part file or source change)
+        if (containingLibrary != null && directives != null) {
+          return _buildSuggestions(
+              request, elem, containingLibrary, directives);
+        }
+      }
+    }
+    return EMPTY_LIST;
+  }
+
+  List<CompletionSuggestion> _buildSuggestions(
+      DartCompletionRequest request,
+      PrefixElement elem,
+      LibraryElement containingLibrary,
+      List<Directive> directives) {
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (Directive directive in directives) {
+      if (directive is ImportDirective) {
+        if (directive.prefix != null) {
+          if (directive.prefix.name == elem.name) {
+            LibraryElement library = directive.uriElement;
+
+            // Suggest elements from the imported library
+            if (library != null) {
+              AstNode parent = request.target.containingNode.parent;
+              bool isConstructor = parent.parent is ConstructorName;
+              bool typesOnly = parent is TypeName;
+              bool instCreation = typesOnly && isConstructor;
+              LibraryElementSuggestionBuilder builder =
+                  new LibraryElementSuggestionBuilder(
+                      containingLibrary,
+                      CompletionSuggestionKind.INVOCATION,
+                      typesOnly,
+                      instCreation);
+              library.visitChildren(builder);
+              suggestions.addAll(builder.suggestions);
+
+              // If the import is 'deferred' then suggest 'loadLibrary'
+              if (directive.deferredKeyword != null) {
+                FunctionElement loadLibFunct = library.loadLibraryFunction;
+                suggestions.add(createSuggestion(loadLibFunct));
+              }
+            }
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
new file mode 100644
index 0000000..791c122
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -0,0 +1,55 @@
+// 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 services.completion.contributor.dart.library_prefix;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating prefixed import library member suggestions
+ * `completion.getSuggestions` request results.
+ */
+class LibraryPrefixContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    if (!request.includeIdentifiers) {
+      return EMPTY_LIST;
+    }
+
+    List<Directive> directives = await request.resolveDirectives();
+    if (directives == null) {
+      return EMPTY_LIST;
+    }
+
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (Directive directive in directives) {
+      if (directive is ImportDirective) {
+        SimpleIdentifier prefix = directive.prefix;
+        ImportElement element = directive.element;
+        if (prefix != null && element != null) {
+          String completion = prefix.name;
+          LibraryElement libElem = element.importedLibrary;
+          if (completion != null && completion.length > 0 && libElem != null) {
+            CompletionSuggestion suggestion = createSuggestion(libElem,
+                completion: completion,
+                kind: CompletionSuggestionKind.IDENTIFIER);
+            if (suggestion != null) {
+              suggestions.add(suggestion);
+            }
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
new file mode 100644
index 0000000..86640d9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -0,0 +1,83 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.contributor.dart.named_constructor;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+
+/**
+ * A contributor for calculating named constructor suggestions
+ * such as suggesting `bar` in `new Foo.bar()`.
+ */
+class NamedConstructorContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a named constructor.
+    AstNode parsedNode = request.target.containingNode;
+    SimpleIdentifier targetId;
+    if (parsedNode is ConstructorName) {
+      TypeName type = parsedNode.type;
+      if (type != null) {
+        targetId = type.name;
+      }
+    } else if (parsedNode is PrefixedIdentifier) {
+      // Some PrefixedIdentifier nodes are transformed into
+      // ConstructorName nodes during the resolution process.
+      targetId = parsedNode.prefix;
+    }
+    if (targetId == null) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the target to determine the type
+    await request.resolveExpression(targetId);
+
+    // Recompute the target since resolution may have changed it
+    AstNode node = request.target.containingNode;
+    LibraryElement libElem = request.libraryElement;
+    if (libElem == null) {
+      return EMPTY_LIST;
+    }
+
+    // Build the list of suggestions
+    if (node is ConstructorName) {
+      TypeName typeName = node.type;
+      if (typeName != null) {
+        DartType type = typeName.type;
+        if (type != null) {
+          Element classElem = type.element;
+          if (classElem is ClassElement) {
+            return _buildSuggestions(libElem, classElem);
+          }
+        }
+      }
+    }
+    return EMPTY_LIST;
+  }
+
+  List<CompletionSuggestion> _buildSuggestions(
+      LibraryElement libElem, ClassElement classElem) {
+    bool isLocalClassDecl = classElem.library == libElem;
+    List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+    for (ConstructorElement elem in classElem.constructors) {
+      if (isLocalClassDecl || !elem.isPrivate) {
+        String name = elem.name;
+        if (name != null) {
+          CompletionSuggestion s = createSuggestion(elem, completion: name);
+          if (s != null) {
+            suggestions.add(s);
+          }
+        }
+      }
+    }
+    return suggestions;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
new file mode 100644
index 0000000..d1d2816
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -0,0 +1,143 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.contributor.dart.static_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating static member invocation / access suggestions
+ * `completion.getSuggestions` request results.
+ */
+class StaticMemberContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a static method invocation,
+    // or a static property access
+    if (request.dotTarget is! Identifier || request.target.isCascade) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the expression and the containing library
+    await request.resolveExpression(request.dotTarget);
+
+    // Recompute the target since resolution may have changed it
+    Expression targetId = request.dotTarget;
+    if (targetId is Identifier && !request.target.isCascade) {
+      Element elem = targetId.bestElement;
+      if (elem is ClassElement) {
+        LibraryElement containingLibrary = request.libraryElement;
+        // Gracefully degrade if the library could not be determined
+        // e.g. detached part file or source change
+        if (containingLibrary == null) {
+          return EMPTY_LIST;
+        }
+
+        _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary);
+        elem.accept(builder);
+        return builder.suggestions;
+      }
+    }
+    return EMPTY_LIST;
+  }
+}
+
+/**
+ * This class visits elements in a class and provides suggestions based upon
+ * the visible static members in that class.
+ */
+class _SuggestionBuilder extends GeneralizingElementVisitor {
+  /**
+   * The library containing the unit in which the completion is requested.
+   */
+  final LibraryElement containingLibrary;
+
+  /**
+   * A collection of completion suggestions.
+   */
+  final List<CompletionSuggestion> suggestions = <CompletionSuggestion>[];
+
+  _SuggestionBuilder(this.containingLibrary);
+
+  @override
+  visitClassElement(ClassElement element) {
+    element.visitChildren(this);
+  }
+
+  @override
+  visitElement(Element element) {
+    // ignored
+  }
+
+  @override
+  visitFieldElement(FieldElement element) {
+    if (element.isStatic) {
+      _addSuggestion(element);
+    }
+  }
+
+  @override
+  visitMethodElement(MethodElement element) {
+    if (element.isStatic && !element.isOperator) {
+      _addSuggestion(element);
+    }
+  }
+
+  @override
+  visitPropertyAccessorElement(PropertyAccessorElement element) {
+    if (element.isStatic) {
+      _addSuggestion(element);
+    }
+  }
+
+  /**
+     * Add a suggestion based upon the given element.
+     */
+  void _addSuggestion(Element element) {
+    if (element.isPrivate) {
+      if (element.library != containingLibrary) {
+        // Do not suggest private members for imported libraries
+        return;
+      }
+    }
+    if (element.isSynthetic) {
+      if ((element is PropertyAccessorElement) ||
+          element is FieldElement && !_isSpecialEnumField(element)) {
+        return;
+      }
+    }
+    String completion = element.displayName;
+    if (completion == null || completion.length <= 0) {
+      return;
+    }
+    CompletionSuggestion suggestion =
+        createSuggestion(element, completion: completion);
+    if (suggestion != null) {
+      suggestions.add(suggestion);
+    }
+  }
+
+  /**
+     * Determine if the given element is one of the synthetic enum accessors
+     * for which we should generate a suggestion.
+     */
+  bool _isSpecialEnumField(FieldElement element) {
+    Element parent = element.enclosingElement;
+    if (parent is ClassElement && parent.isEnum) {
+      if (element.name == 'values') {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index fa0cf95..0e395fa 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -112,9 +112,9 @@
   CompletionSuggestionKind get kind;
 
   /**
-   * Return the request on which the builder is operating.
+   * Return the library in which the completion is requested.
    */
-  DartCompletionRequest get request;
+  LibraryElement get containingLibrary;
 
   /**
    * Add a suggestion based upon the given element.
@@ -122,13 +122,7 @@
   void addSuggestion(Element element,
       {String prefix, int relevance: DART_RELEVANCE_DEFAULT}) {
     if (element.isPrivate) {
-      LibraryElement elementLibrary = element.library;
-      CompilationUnitElement unitElem = request.target.unit.element;
-      if (unitElem == null) {
-        return;
-      }
-      LibraryElement unitLibrary = unitElem.library;
-      if (elementLibrary != unitLibrary) {
+      if (element.library != containingLibrary) {
         return;
       }
     }
@@ -173,18 +167,17 @@
 
 /**
  * This class visits elements in a library and provides suggestions based upon
- * the visible members in that library. Clients should call
- * [LibraryElementSuggestionBuilder.suggestionsFor].
+ * the visible members in that library.
  */
 class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
     with ElementSuggestionBuilder {
-  final DartCompletionRequest request;
+  final LibraryElement containingLibrary;
   final CompletionSuggestionKind kind;
   final bool typesOnly;
   final bool instCreation;
 
   LibraryElementSuggestionBuilder(
-      this.request, this.kind, this.typesOnly, this.instCreation);
+      this.containingLibrary, this.kind, this.typesOnly, this.instCreation);
 
   @override
   visitClassElement(ClassElement element) {
@@ -244,19 +237,4 @@
       addSuggestion(element);
     }
   }
-
-  /**
-   * Add suggestions for the visible members in the given library
-   */
-  static void suggestionsFor(
-      DartCompletionRequest request,
-      CompletionSuggestionKind kind,
-      LibraryElement library,
-      bool typesOnly,
-      bool instCreation) {
-    if (library != null) {
-      library.visitChildren(new LibraryElementSuggestionBuilder(
-          request, kind, typesOnly, instCreation));
-    }
-  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
new file mode 100644
index 0000000..8915a65
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/dart/type_member_contributor.dart
@@ -0,0 +1,412 @@
+// 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 services.completion.contributor.dart.type_member;
+
+import 'dart:async';
+import 'dart:collection';
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+
+import '../../../protocol_server.dart'
+    show CompletionSuggestion, CompletionSuggestionKind;
+
+/**
+ * A contributor for calculating instance invocation / access suggestions
+ * `completion.getSuggestions` request results.
+ */
+class TypeMemberContributor extends DartCompletionContributor {
+  @override
+  Future<List<CompletionSuggestion>> computeSuggestions(
+      DartCompletionRequest request) async {
+    // Determine if the target looks like a prefixed identifier,
+    // a method invocation, or a property access
+    Expression parsedExpression = request.dotTarget;
+    if (parsedExpression == null) {
+      return EMPTY_LIST;
+    }
+
+    // Resolve the expression and the containing library
+    await request.resolveExpression(parsedExpression);
+    LibraryElement containingLibrary = request.libraryElement;
+    // Gracefully degrade if the library element could not be resolved
+    // e.g. detached part file or source change
+    if (containingLibrary == null) {
+      return EMPTY_LIST;
+    }
+
+    // Recompute the target since resolution may have changed it
+    Expression expression = request.dotTarget;
+    if (expression == null || expression.isSynthetic) {
+      return EMPTY_LIST;
+    }
+    if (expression is Identifier) {
+      Element elem = expression.bestElement;
+      if (elem is ClassElement) {
+        // Suggestions provided by StaticMemberContributor
+        return EMPTY_LIST;
+      }
+      if (elem is PrefixElement) {
+        // Suggestions provided by LibraryMemberContributor
+        return EMPTY_LIST;
+      }
+    }
+
+    // Determine the target expression's type
+    DartType type = expression.bestType;
+    if (type.isDynamic) {
+      // If the expression does not provide a good type
+      // then attempt to get a better type from the element
+      if (expression is Identifier) {
+        Element elem = expression.bestElement;
+        if (elem is FunctionTypedElement) {
+          type = elem.returnType;
+        } else if (elem is ParameterElement) {
+          type = elem.type;
+        } else if (elem is LocalVariableElement) {
+          type = elem.type;
+        }
+        if (type.isDynamic && expression is SimpleIdentifier) {
+          // If the element does not provide a good type
+          // then attempt to get a better type from a local declaration
+          _LocalBestTypeVisitor visitor =
+              new _LocalBestTypeVisitor(expression.name, request.offset);
+          if (visitor.visit(expression) && visitor.typeFound != null) {
+            type = visitor.typeFound;
+          }
+        }
+      }
+    }
+    String containingMethodName;
+    if (expression is SuperExpression && type is InterfaceType) {
+      // Suggest members from superclass if target is "super"
+      type = (type as InterfaceType).superclass;
+      // Determine the name of the containing method because
+      // the most likely completion is a super expression with same name
+      MethodDeclaration containingMethod =
+          expression.getAncestor((p) => p is MethodDeclaration);
+      if (containingMethod != null) {
+        SimpleIdentifier id = containingMethod.name;
+        if (id != null) {
+          containingMethodName = id.name;
+        }
+      }
+    }
+    if (type.isDynamic) {
+      // Suggest members from object if target is "dynamic"
+      type = request.objectType;
+    }
+
+    // Build the suggestions
+    if (type is InterfaceType) {
+      _SuggestionBuilder builder = new _SuggestionBuilder(containingLibrary);
+      builder.buildSuggestions(type, containingMethodName);
+      return builder.suggestions.toList();
+    }
+    return EMPTY_LIST;
+  }
+}
+
+/**
+ * An [AstVisitor] which looks for a declaration with the given name
+ * and if found, tries to determine a type for that declaration.
+ */
+class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
+  /**
+   * The name for the declaration to be found.
+   */
+  final String targetName;
+
+  /**
+   * The best type for the found declaration,
+   * or `null` if no declaration found or failed to determine a type.
+   */
+  DartType typeFound;
+
+  /**
+   * Construct a new instance to search for a declaration
+   */
+  _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
+
+  @override
+  void declaredClass(ClassDeclaration declaration) {
+    if (declaration.name.name == targetName) {
+      // no type
+      finished();
+    }
+  }
+
+  @override
+  void declaredClassTypeAlias(ClassTypeAlias declaration) {
+    if (declaration.name.name == targetName) {
+      // no type
+      finished();
+    }
+  }
+
+  @override
+  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+    if (varDecl.name.name == targetName) {
+      // Type provided by the element in computeFull above
+      finished();
+    }
+  }
+
+  @override
+  void declaredFunction(FunctionDeclaration declaration) {
+    if (declaration.name.name == targetName) {
+      TypeName typeName = declaration.returnType;
+      if (typeName != null) {
+        typeFound = typeName.type;
+      }
+      finished();
+    }
+  }
+
+  @override
+  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
+    if (declaration.name.name == targetName) {
+      TypeName typeName = declaration.returnType;
+      if (typeName != null) {
+        typeFound = typeName.type;
+      }
+      finished();
+    }
+  }
+
+  @override
+  void declaredLabel(Label label, bool isCaseLabel) {
+    if (label.label.name == targetName) {
+      // no type
+      finished();
+    }
+  }
+
+  @override
+  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
+    if (name.name == targetName) {
+      typeFound = name.bestType;
+      finished();
+    }
+  }
+
+  @override
+  void declaredMethod(MethodDeclaration declaration) {
+    if (declaration.name.name == targetName) {
+      TypeName typeName = declaration.returnType;
+      if (typeName != null) {
+        typeFound = typeName.type;
+      }
+      finished();
+    }
+  }
+
+  @override
+  void declaredParam(SimpleIdentifier name, TypeName type) {
+    if (name.name == targetName) {
+      // Type provided by the element in computeFull above
+      finished();
+    }
+  }
+
+  @override
+  void declaredTopLevelVar(
+      VariableDeclarationList varList, VariableDeclaration varDecl) {
+    if (varDecl.name.name == targetName) {
+      // Type provided by the element in computeFull above
+      finished();
+    }
+  }
+}
+
+/**
+ * This class provides suggestions based upon the visible instance members in
+ * an interface type.
+ */
+class _SuggestionBuilder {
+  /**
+   * Enumerated value indicating that we have not generated any completions for
+   * a given identifier yet.
+   */
+  static const int _COMPLETION_TYPE_NONE = 0;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * getter.
+   */
+  static const int _COMPLETION_TYPE_GETTER = 1;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * setter.
+   */
+  static const int _COMPLETION_TYPE_SETTER = 2;
+
+  /**
+   * Enumerated value indicating that we have generated a completion for a
+   * field, a method, or a getter/setter pair.
+   */
+  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
+
+  /**
+   * The library containing the unit in which the completion is requested.
+   */
+  final LibraryElement containingLibrary;
+
+  /**
+   * Map indicating, for each possible completion identifier, whether we have
+   * already generated completions for a getter, setter, or both.  The "both"
+   * case also handles the case where have generated a completion for a method
+   * or a field.
+   *
+   * Note: the enumerated values stored in this map are intended to be bitwise
+   * compared.
+   */
+  Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
+
+  /**
+   * Map from completion identifier to completion suggestion
+   */
+  Map<String, CompletionSuggestion> _suggestionMap =
+      <String, CompletionSuggestion>{};
+
+  _SuggestionBuilder(this.containingLibrary);
+
+  Iterable<CompletionSuggestion> get suggestions => _suggestionMap.values;
+
+  /**
+   * Add a suggestion based upon the given element, provided that it is not
+   * shadowed by a previously added suggestion.
+   */
+  void _addSuggestion(Element element,
+      {int relevance: DART_RELEVANCE_DEFAULT}) {
+    if (element.isPrivate) {
+      if (element.library != containingLibrary) {
+        // Do not suggest private members for imported libraries
+        return;
+      }
+    }
+    String identifier = element.displayName;
+    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
+        identifier, () => _COMPLETION_TYPE_NONE);
+    if (element is MethodElement) {
+      // Anything shadows a method.
+      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else if (element is PropertyAccessorElement) {
+      if (element.isGetter) {
+        // Getters, fields, and methods shadow a getter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
+      } else {
+        // Setters, fields, and methods shadow a setter.
+        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
+          return;
+        }
+        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
+      }
+    } else if (element is FieldElement) {
+      // Fields and methods shadow a field.  A getter/setter pair shadows a
+      // field, but a getter or setter by itself doesn't.
+      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
+        return;
+      }
+      _completionTypesGenerated[identifier] =
+          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
+    } else {
+      // Unexpected element type; skip it.
+      assert(false);
+      return;
+    }
+    CompletionSuggestion suggestion =
+        createSuggestion(element, relevance: relevance);
+    if (suggestion != null) {
+      _suggestionMap[suggestion.completion] = suggestion;
+    }
+  }
+
+  /**
+   * Return completion suggestions for 'dot' completions on the given [type].
+   * If the 'dot' completion is a super expression, then [containingMethodName]
+   * is the name of the method in which the completion is requested.
+   */
+  void buildSuggestions(InterfaceType type, String containingMethodName) {
+    // Visit all of the types in the class hierarchy, collecting possible
+    // completions.  If multiple elements are found that complete to the same
+    // identifier, addSuggestion will discard all but the first (with a few
+    // exceptions to handle getter/setter pairs).
+    List<InterfaceType> types = _getTypeOrdering(type);
+    for (InterfaceType targetType in types) {
+      for (MethodElement method in targetType.methods) {
+        // Exclude static methods when completion on an instance
+        if (!method.isStatic) {
+          // Boost the relevance of a super expression
+          // calling a method of the same name as the containing method
+          _addSuggestion(method,
+              relevance: method.name == containingMethodName
+                  ? DART_RELEVANCE_HIGH
+                  : DART_RELEVANCE_DEFAULT);
+        }
+      }
+      for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
+        if (!propertyAccessor.isStatic) {
+          if (propertyAccessor.isSynthetic) {
+            // Avoid visiting a field twice
+            if (propertyAccessor.isGetter) {
+              _addSuggestion(propertyAccessor.variable);
+            }
+          } else {
+            _addSuggestion(propertyAccessor);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Get a list of [InterfaceType]s that should be searched to find the
+   * possible completions for an object having type [type].
+   */
+  List<InterfaceType> _getTypeOrdering(InterfaceType type) {
+    // Candidate completions can come from [type] as well as any types above it
+    // in the class hierarchy (including mixins, superclasses, and interfaces).
+    // If a given completion identifier shows up in multiple types, we should
+    // use the element that is nearest in the superclass chain, so we will
+    // visit [type] first, then its mixins, then its superclass, then its
+    // superclass's mixins, etc., and only afterwards visit interfaces.
+    //
+    // We short-circuit loops in the class hierarchy by keeping track of the
+    // classes seen (not the interfaces) so that we won't be fooled by nonsense
+    // like "class C<T> extends C<List<T>> {}"
+    List<InterfaceType> result = <InterfaceType>[];
+    Set<ClassElement> classesSeen = new HashSet<ClassElement>();
+    List<InterfaceType> typesToVisit = <InterfaceType>[type];
+    while (typesToVisit.isNotEmpty) {
+      InterfaceType nextType = typesToVisit.removeLast();
+      if (!classesSeen.add(nextType.element)) {
+        // Class had already been seen, so ignore this type.
+        continue;
+      }
+      result.add(nextType);
+      // typesToVisit is a stack, so push on the interfaces first, then the
+      // superclass, then the mixins.  This will ensure that they are visited
+      // in the reverse order.
+      typesToVisit.addAll(nextType.interfaces);
+      if (nextType.superclass != null) {
+        typesToVisit.add(nextType.superclass);
+      }
+      typesToVisit.addAll(nextType.mixins);
+    }
+    return result;
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
index ebf87fe..7e849b1 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
@@ -116,10 +116,19 @@
     if (resContext.isRelative(dirPath)) {
       String sourceDirPath = resContext.dirname(source.fullName);
       if (resContext.isAbsolute(sourceDirPath)) {
-        dirPath = resContext.join(sourceDirPath, dirPath);
+        dirPath = resContext.normalize(resContext.join(sourceDirPath, dirPath));
       } else {
         return;
       }
+      // Do not suggest relative paths reaching outside the 'lib' directory.
+      bool srcInLib = resContext.split(sourceDirPath).contains('lib');
+      bool dstInLib = resContext.split(dirPath).contains('lib');
+      if (srcInLib && !dstInLib) {
+        return;
+      }
+    }
+    if (dirPath.endsWith('\\.')) {
+      dirPath = dirPath.substring(0, dirPath.length - 1);
     }
 
     Resource dir = resProvider.getResource(dirPath);
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
index 2fbe91e..be84372 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
@@ -31,12 +31,6 @@
   String _importKey;
 
   /**
-   * Library prefix suggestions based upon imports,
-   * or `null` if nothing has been cached.
-   */
-  List<CompletionSuggestion> libraryPrefixSuggestions;
-
-  /**
    * Type suggestions based upon imports,
    * or `null` if nothing has been cached.
    */
@@ -114,7 +108,6 @@
   Future<bool> computeImportInfo(CompilationUnit unit,
       SearchEngine searchEngine, bool shouldWaitForLowPrioritySuggestions) {
     importedTypeSuggestions = <CompletionSuggestion>[];
-    libraryPrefixSuggestions = <CompletionSuggestion>[];
     otherImportedSuggestions = <CompletionSuggestion>[];
     importedConstructorSuggestions = <CompletionSuggestion>[];
     importedVoidReturnSuggestions = <CompletionSuggestion>[];
@@ -240,8 +233,9 @@
             } else {
               // Exclude elements from prefixed imports
               // because they are provided by PrefixedElementContributor
-              _addLibraryPrefixSuggestion(importElem);
-              excludedLibs.add(importElem.importedLibrary);
+              // Suggested by LibraryPrefixContributor
+              // _addLibraryPrefixSuggestion(importElem);
+              // excludedLibs.add(importElem.importedLibrary);
             }
           }
         } else if (directive is PartDirective) {
@@ -257,27 +251,6 @@
     }
   }
 
-  void _addLibraryPrefixSuggestion(ImportElement importElem) {
-    CompletionSuggestion suggestion = null;
-    String completion = importElem.prefix.displayName;
-    if (completion != null && completion.length > 0) {
-      suggestion = new CompletionSuggestion(
-          CompletionSuggestionKind.INVOCATION,
-          DART_RELEVANCE_DEFAULT,
-          completion,
-          completion.length,
-          0,
-          importElem.isDeprecated,
-          false);
-      LibraryElement lib = importElem.importedLibrary;
-      if (lib != null) {
-        suggestion.element = convertElement(lib);
-      }
-      libraryPrefixSuggestions.add(suggestion);
-      _importedCompletions.add(suggestion.completion);
-    }
-  }
-
   /**
    * Add suggestions for all top level elements in the context
    * excluding those elemnents for which suggestions have already been added.
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
index 06bbe66..4f793ec 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_manager.dart
@@ -18,11 +18,10 @@
 import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
 import 'package:analysis_server/src/services/completion/local_reference_contributor.dart';
 import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
 
@@ -99,7 +98,7 @@
         //new KeywordContributor(),
         //new ArgListContributor(),
         // new CombinatorContributor(),
-        new PrefixedElementContributor(),
+        // new PrefixedElementContributor(),
         //new UriContributor(),
         // TODO(brianwilkerson) Use the completion contributor extension point
         // to add the contributor below (and eventually, all the contributors).
diff --git a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
index b283ce9..f2a9cfa 100644
--- a/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/imported_reference_contributor.dart
@@ -143,7 +143,6 @@
     }
     DartCompletionCache cache = request.cache;
     _addFilteredSuggestions(filterText, cache.importedConstructorSuggestions);
-    _addFilteredSuggestions(filterText, cache.libraryPrefixSuggestions);
   }
 
   /**
@@ -258,7 +257,6 @@
     DartCompletionCache cache = request.cache;
     if (optype.includeTypeNameSuggestions) {
       _addFilteredSuggestions(filterText, cache.importedTypeSuggestions);
-      _addFilteredSuggestions(filterText, cache.libraryPrefixSuggestions);
     }
     if (optype.includeReturnValueSuggestions) {
       _addFilteredSuggestions(filterText, cache.otherImportedSuggestions);
diff --git a/pkg/analysis_server/lib/src/services/completion/optype.dart b/pkg/analysis_server/lib/src/services/completion/optype.dart
index 3408e96..768b0d3 100644
--- a/pkg/analysis_server/lib/src/services/completion/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/optype.dart
@@ -129,6 +129,14 @@
     }
   }
 
+@override
+  void visitAssertStatement(AssertStatement node) {
+    if (identical(entity, node.condition)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
   void visitAssignmentExpression(AssignmentExpression node) {
     if (identical(entity, node.rightHandSide)) {
       optype.includeReturnValueSuggestions = true;
diff --git a/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart b/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
deleted file mode 100644
index b6fe585..0000000
--- a/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
+++ /dev/null
@@ -1,370 +0,0 @@
-// 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 services.completion.contributor.dart.invocation;
-
-import 'dart:async';
-
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/local_declaration_visitor.dart';
-import 'package:analysis_server/src/services/completion/local_suggestion_builder.dart'
-    hide createSuggestion;
-import 'package:analysis_server/src/services/completion/optype.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
-import 'package:analysis_server/src/services/completion/suggestion_builder.dart'
-    show createSuggestion;
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-
-import '../../protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
-
-/**
- * A contributor for calculating invocation / access suggestions
- * `completion.getSuggestions` request results.
- */
-class PrefixedElementContributor extends DartCompletionContributor {
-  SuggestionBuilder builder;
-
-  @override
-  bool computeFast(DartCompletionRequest request) {
-    OpType optype = request.optype;
-    if (optype.isPrefixed) {
-      builder = request.target.containingNode
-          .accept(new _InvocationAstVisitor(request));
-      if (builder != null) {
-        return builder.computeFast(request.target.containingNode);
-      }
-    }
-
-    return true;
-  }
-
-  @override
-  Future<bool> computeFull(DartCompletionRequest request) {
-    if (builder != null) {
-      return builder.computeFull(request.target.containingNode);
-    }
-    return new Future.value(false);
-  }
-}
-
-class _ExpressionSuggestionBuilder implements SuggestionBuilder {
-  final DartCompletionRequest request;
-
-  _ExpressionSuggestionBuilder(this.request);
-
-  @override
-  bool computeFast(AstNode node) {
-    return false;
-  }
-
-  @override
-  Future<bool> computeFull(AstNode node) {
-    if (node is MethodInvocation) {
-      node = (node as MethodInvocation).realTarget;
-    } else if (node is PropertyAccess) {
-      node = (node as PropertyAccess).realTarget;
-    }
-    if (node is Identifier) {
-      Element elem = node.bestElement;
-      if (elem is ClassElement || elem is PrefixElement) {
-        elem.accept(new _PrefixedIdentifierSuggestionBuilder(request));
-        return new Future.value(true);
-      }
-    }
-    if (node is Expression) {
-      String containingMethodName;
-      bool isSuper = node is SuperExpression;
-      if (isSuper) {
-        MethodDeclaration containingMethod =
-            node.getAncestor((p) => p is MethodDeclaration);
-        if (containingMethod != null) {
-          SimpleIdentifier id = containingMethod.name;
-          if (id != null) {
-            containingMethodName = id.name;
-          }
-        }
-      }
-      InterfaceTypeSuggestionBuilder.suggestionsFor(request, node.bestType,
-          isSuper: isSuper, containingMethodName: containingMethodName);
-      return new Future.value(true);
-    }
-    return new Future.value(false);
-  }
-}
-
-/**
- * An [AstNode] vistor for determining which suggestion builder
- * should be used to build invocation/access suggestions.
- */
-class _InvocationAstVisitor extends GeneralizingAstVisitor<SuggestionBuilder> {
-  final DartCompletionRequest request;
-
-  _InvocationAstVisitor(this.request);
-
-  @override
-  SuggestionBuilder visitConstructorName(ConstructorName node) {
-    // some PrefixedIdentifier nodes are transformed into
-    // ConstructorName nodes during the resolution process.
-    return new _PrefixedIdentifierSuggestionBuilder(request);
-  }
-
-  @override
-  SuggestionBuilder visitMethodInvocation(MethodInvocation node) {
-    return new _ExpressionSuggestionBuilder(request);
-  }
-
-  @override
-  SuggestionBuilder visitNode(AstNode node) {
-    return null;
-  }
-
-  @override
-  SuggestionBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
-    // some PrefixedIdentifier nodes are transformed into
-    // ConstructorName nodes during the resolution process.
-    return new _PrefixedIdentifierSuggestionBuilder(request);
-  }
-
-  @override
-  SuggestionBuilder visitPropertyAccess(PropertyAccess node) {
-    return new _ExpressionSuggestionBuilder(request);
-  }
-}
-
-/**
- * An [AstVisitor] which looks for a declaration with the given name
- * and if found, tries to determine a type for that declaration.
- */
-class _LocalBestTypeVisitor extends LocalDeclarationVisitor {
-  /**
-   * The name for the declaration to be found.
-   */
-  final String targetName;
-
-  /**
-   * The best type for the found declaration,
-   * or `null` if no declaration found or failed to determine a type.
-   */
-  DartType typeFound;
-
-  /**
-   * Construct a new instance to search for a declaration
-   */
-  _LocalBestTypeVisitor(this.targetName, int offset) : super(offset);
-
-  @override
-  void declaredClass(ClassDeclaration declaration) {
-    if (declaration.name.name == targetName) {
-      // no type
-      finished();
-    }
-  }
-
-  @override
-  void declaredClassTypeAlias(ClassTypeAlias declaration) {
-    if (declaration.name.name == targetName) {
-      // no type
-      finished();
-    }
-  }
-
-  @override
-  void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
-    if (varDecl.name.name == targetName) {
-      // Type provided by the element in computeFull above
-      finished();
-    }
-  }
-
-  @override
-  void declaredFunction(FunctionDeclaration declaration) {
-    if (declaration.name.name == targetName) {
-      TypeName typeName = declaration.returnType;
-      if (typeName != null) {
-        typeFound = typeName.type;
-      }
-      finished();
-    }
-  }
-
-  @override
-  void declaredFunctionTypeAlias(FunctionTypeAlias declaration) {
-    if (declaration.name.name == targetName) {
-      TypeName typeName = declaration.returnType;
-      if (typeName != null) {
-        typeFound = typeName.type;
-      }
-      finished();
-    }
-  }
-
-  @override
-  void declaredLabel(Label label, bool isCaseLabel) {
-    if (label.label.name == targetName) {
-      // no type
-      finished();
-    }
-  }
-
-  @override
-  void declaredLocalVar(SimpleIdentifier name, TypeName type) {
-    if (name.name == targetName) {
-      typeFound = name.bestType;
-      finished();
-    }
-  }
-
-  @override
-  void declaredMethod(MethodDeclaration declaration) {
-    if (declaration.name.name == targetName) {
-      TypeName typeName = declaration.returnType;
-      if (typeName != null) {
-        typeFound = typeName.type;
-      }
-      finished();
-    }
-  }
-
-  @override
-  void declaredParam(SimpleIdentifier name, TypeName type) {
-    if (name.name == targetName) {
-      // Type provided by the element in computeFull above
-      finished();
-    }
-  }
-
-  @override
-  void declaredTopLevelVar(
-      VariableDeclarationList varList, VariableDeclaration varDecl) {
-    if (varDecl.name.name == targetName) {
-      // Type provided by the element in computeFull above
-      finished();
-    }
-  }
-}
-
-/**
- * An [Element] visitor for determining the appropriate invocation/access
- * suggestions based upon the element for which the completion is requested.
- */
-class _PrefixedIdentifierSuggestionBuilder
-    extends GeneralizingElementVisitor<Future<bool>>
-    implements SuggestionBuilder {
-  final DartCompletionRequest request;
-
-  _PrefixedIdentifierSuggestionBuilder(this.request);
-
-  @override
-  bool computeFast(AstNode node) {
-    return false;
-  }
-
-  @override
-  Future<bool> computeFull(AstNode node) {
-    if (node is ConstructorName) {
-      // some PrefixedIdentifier nodes are transformed into
-      // ConstructorName nodes during the resolution process.
-      return new NamedConstructorSuggestionBuilder(request).computeFull(node);
-    }
-    if (node is PrefixedIdentifier) {
-      SimpleIdentifier prefix = node.prefix;
-      if (prefix != null) {
-        Element element = prefix.bestElement;
-        DartType type = prefix.bestType;
-        if (element is! ClassElement) {
-          if (type == null || type.isDynamic) {
-            //
-            // Given `g. int y = 0;`, the parser interprets `g` as a prefixed
-            // identifier with no type.
-            // If the user is requesting completions for `g`,
-            // then check for a function, getter, or similar with a type.
-            //
-            _LocalBestTypeVisitor visitor =
-                new _LocalBestTypeVisitor(prefix.name, request.offset);
-            if (visitor.visit(prefix)) {
-              type = visitor.typeFound;
-            }
-          }
-          if (type != null && !type.isDynamic) {
-            InterfaceTypeSuggestionBuilder.suggestionsFor(request, type);
-            return new Future.value(true);
-          }
-        }
-        if (element != null) {
-          return element.accept(this);
-        }
-      }
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitClassElement(ClassElement element) {
-    if (element != null) {
-      InterfaceType type = element.type;
-      if (type != null) {
-        StaticClassElementSuggestionBuilder.suggestionsFor(
-            request, type.element);
-      }
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitElement(Element element) {
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitPrefixElement(PrefixElement element) {
-    bool modified = false;
-    // Find the import directive with the given prefix
-    for (Directive directive in request.unit.directives) {
-      if (directive is ImportDirective) {
-        if (directive.prefix != null) {
-          if (directive.prefix.name == element.name) {
-            // Suggest elements from the imported library
-            LibraryElement library = directive.uriElement;
-            AstNode node = request.target.containingNode;
-            bool typesOnly = node.parent is TypeName;
-            bool instCreation =
-                typesOnly && node.parent.parent is ConstructorName;
-            LibraryElementSuggestionBuilder.suggestionsFor(
-                request,
-                CompletionSuggestionKind.INVOCATION,
-                library,
-                typesOnly,
-                instCreation);
-            modified = true;
-            if (directive.deferredKeyword != null) {
-              FunctionElement loadLibFunct = library.loadLibraryFunction;
-              request.addSuggestion(createSuggestion(loadLibFunct));
-            }
-          }
-        }
-      }
-    }
-    return new Future.value(modified);
-  }
-
-  @override
-  Future<bool> visitPropertyAccessorElement(PropertyAccessorElement element) {
-    if (element != null) {
-      PropertyInducingElement elemVar = element.variable;
-      if (elemVar != null) {
-        InterfaceTypeSuggestionBuilder.suggestionsFor(request, elemVar.type);
-      }
-      return new Future.value(true);
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  Future<bool> visitVariableElement(VariableElement element) {
-    InterfaceTypeSuggestionBuilder.suggestionsFor(request, element.type);
-    return new Future.value(true);
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
index 573dc4b..4379e7f 100644
--- a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
@@ -5,7 +5,6 @@
 library services.completion.suggestion.builder;
 
 import 'dart:async';
-import 'dart:collection';
 
 import 'package:analysis_server/src/protocol_server.dart'
     hide Element, ElementKind;
@@ -14,7 +13,6 @@
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' as engine;
 
 export 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
     show createSuggestion;
@@ -174,421 +172,6 @@
 }
 
 /**
- * This class provides suggestions based upon the visible instance members in
- * an interface type.  Clients should call
- * [InterfaceTypeSuggestionBuilder.suggestionsFor].
- */
-class InterfaceTypeSuggestionBuilder {
-  /**
-   * Enumerated value indicating that we have not generated any completions for
-   * a given identifier yet.
-   */
-  static const int _COMPLETION_TYPE_NONE = 0;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * getter.
-   */
-  static const int _COMPLETION_TYPE_GETTER = 1;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * setter.
-   */
-  static const int _COMPLETION_TYPE_SETTER = 2;
-
-  /**
-   * Enumerated value indicating that we have generated a completion for a
-   * field, a method, or a getter/setter pair.
-   */
-  static const int _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET = 3;
-
-  final DartCompletionRequest request;
-
-  /**
-   * Map indicating, for each possible completion identifier, whether we have
-   * already generated completions for a getter, setter, or both.  The "both"
-   * case also handles the case where have generated a completion for a method
-   * or a field.
-   *
-   * Note: the enumerated values stored in this map are intended to be bitwise
-   * compared.
-   */
-  Map<String, int> _completionTypesGenerated = new HashMap<String, int>();
-
-  InterfaceTypeSuggestionBuilder(this.request);
-
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  /**
-   * Add a suggestion based upon the given element, provided that it is not
-   * shadowed by a previously added suggestion.
-   */
-  void addSuggestion(Element element, {int relevance: DART_RELEVANCE_DEFAULT}) {
-    if (element.isPrivate) {
-      LibraryElement elementLibrary = element.library;
-      LibraryElement unitLibrary = request.unit.element.library;
-      if (elementLibrary != unitLibrary) {
-        return;
-      }
-    }
-    String identifier = element.displayName;
-    int alreadyGenerated = _completionTypesGenerated.putIfAbsent(
-        identifier, () => _COMPLETION_TYPE_NONE);
-    if (element is MethodElement) {
-      // Anything shadows a method.
-      if (alreadyGenerated != _COMPLETION_TYPE_NONE) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else if (element is PropertyAccessorElement) {
-      if (element.isGetter) {
-        // Getters, fields, and methods shadow a getter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_GETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_GETTER;
-      } else {
-        // Setters, fields, and methods shadow a setter.
-        if ((alreadyGenerated & _COMPLETION_TYPE_SETTER) != 0) {
-          return;
-        }
-        _completionTypesGenerated[identifier] |= _COMPLETION_TYPE_SETTER;
-      }
-    } else if (element is FieldElement) {
-      // Fields and methods shadow a field.  A getter/setter pair shadows a
-      // field, but a getter or setter by itself doesn't.
-      if (alreadyGenerated == _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET) {
-        return;
-      }
-      _completionTypesGenerated[identifier] =
-          _COMPLETION_TYPE_FIELD_OR_METHOD_OR_GETSET;
-    } else {
-      // Unexpected element type; skip it.
-      assert(false);
-      return;
-    }
-    CompletionSuggestion suggestion =
-        createSuggestion(element, kind: kind, relevance: relevance);
-    if (suggestion != null) {
-      request.addSuggestion(suggestion);
-    }
-  }
-
-  void _buildSuggestions(InterfaceType type, LibraryElement library,
-      bool isSuper, String containingMethodName) {
-    if (isSuper) {
-      // Suggest members from superclass if the target is "super"
-      type = type.superclass;
-      if (type == null) {
-        return;
-      }
-    }
-    // Visit all of the types in the class hierarchy, collecting possible
-    // completions.  If multiple elements are found that complete to the same
-    // identifier, addSuggestion will discard all but the first (with a few
-    // exceptions to handle getter/setter pairs).
-    List<InterfaceType> types = _getTypeOrdering(type);
-    for (InterfaceType targetType in types) {
-      for (MethodElement method in targetType.methods) {
-        // Exclude static methods when completion on an instance
-        if (!method.isStatic) {
-          addSuggestion(method,
-              relevance: method.name == containingMethodName
-                  ? DART_RELEVANCE_HIGH
-                  : DART_RELEVANCE_DEFAULT);
-        }
-      }
-      for (PropertyAccessorElement propertyAccessor in targetType.accessors) {
-        if (!propertyAccessor.isStatic) {
-          if (propertyAccessor.isSynthetic) {
-            // Avoid visiting a field twice
-            if (propertyAccessor.isGetter) {
-              addSuggestion(propertyAccessor.variable);
-            }
-          } else {
-            addSuggestion(propertyAccessor);
-          }
-        }
-      }
-    }
-  }
-
-  /**
-   * Get a list of [InterfaceType]s that should be searched to find the
-   * possible completions for an object having type [type].
-   */
-  List<InterfaceType> _getTypeOrdering(InterfaceType type) {
-    // Candidate completions can come from [type] as well as any types above it
-    // in the class hierarchy (including mixins, superclasses, and interfaces).
-    // If a given completion identifier shows up in multiple types, we should
-    // use the element that is nearest in the superclass chain, so we will
-    // visit [type] first, then its mixins, then its superclass, then its
-    // superclass's mixins, etc., and only afterwards visit interfaces.
-    //
-    // We short-circuit loops in the class hierarchy by keeping track of the
-    // classes seen (not the interfaces) so that we won't be fooled by nonsense
-    // like "class C<T> extends C<List<T>> {}"
-    List<InterfaceType> result = <InterfaceType>[];
-    Set<ClassElement> classesSeen = new HashSet<ClassElement>();
-    List<InterfaceType> typesToVisit = <InterfaceType>[type];
-    while (typesToVisit.isNotEmpty) {
-      InterfaceType nextType = typesToVisit.removeLast();
-      if (!classesSeen.add(nextType.element)) {
-        // Class had already been seen, so ignore this type.
-        continue;
-      }
-      result.add(nextType);
-      // typesToVisit is a stack, so push on the interfaces first, then the
-      // superclass, then the mixins.  This will ensure that they are visited
-      // in the reverse order.
-      typesToVisit.addAll(nextType.interfaces);
-      if (nextType.superclass != null) {
-        typesToVisit.add(nextType.superclass);
-      }
-      typesToVisit.addAll(nextType.mixins);
-    }
-    return result;
-  }
-
-  /**
-   * Add suggestions for the visible members in the given interface
-   */
-  static void suggestionsFor(DartCompletionRequest request, DartType type,
-      {bool isSuper: false, String containingMethodName: null}) {
-    CompilationUnit compilationUnit =
-        request.target.containingNode.getAncestor((n) => n is CompilationUnit);
-    CompilationUnitElement unitElem = compilationUnit.element;
-    if (unitElem == null) {
-      engine.AnalysisEngine.instance.logger
-          .logInformation('Completion expected resolved AST');
-      return;
-    }
-    LibraryElement library = unitElem.library;
-    if (type is DynamicTypeImpl) {
-      type = request.cache.objectClassElement.type;
-    }
-    if (type is InterfaceType) {
-      new InterfaceTypeSuggestionBuilder(request)
-          ._buildSuggestions(type, library, isSuper, containingMethodName);
-    }
-  }
-}
-
-/**
- * This class visits elements in a library and provides suggestions based upon
- * the visible members in that library. Clients should call
- * [LibraryElementSuggestionBuilder.suggestionsFor].
- */
-class LibraryElementSuggestionBuilder extends GeneralizingElementVisitor
-    with ElementSuggestionBuilder {
-  final DartCompletionRequest request;
-  final CompletionSuggestionKind kind;
-  final bool typesOnly;
-  final bool instCreation;
-
-  LibraryElementSuggestionBuilder(
-      this.request, this.kind, this.typesOnly, this.instCreation);
-
-  @override
-  visitClassElement(ClassElement element) {
-    if (instCreation) {
-      element.visitChildren(this);
-    } else {
-      addSuggestion(element);
-    }
-  }
-
-  @override
-  visitCompilationUnitElement(CompilationUnitElement element) {
-    element.visitChildren(this);
-    LibraryElement containingLibrary = element.library;
-    if (containingLibrary != null) {
-      for (var lib in containingLibrary.exportedLibraries) {
-        lib.visitChildren(this);
-      }
-    }
-  }
-
-  @override
-  visitConstructorElement(ConstructorElement element) {
-    if (instCreation) {
-      ClassElement classElem = element.enclosingElement;
-      if (classElem != null) {
-        String prefix = classElem.name;
-        if (prefix != null && prefix.length > 0) {
-          addSuggestion(element, prefix: prefix);
-        }
-      }
-    }
-  }
-
-  @override
-  visitElement(Element element) {
-    // ignored
-  }
-
-  @override
-  visitFunctionElement(FunctionElement element) {
-    if (!typesOnly) {
-      addSuggestion(element);
-    }
-  }
-
-  @override
-  visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
-    if (!instCreation) {
-      addSuggestion(element);
-    }
-  }
-
-  @override
-  visitTopLevelVariableElement(TopLevelVariableElement element) {
-    if (!typesOnly) {
-      addSuggestion(element);
-    }
-  }
-
-  /**
-   * Add suggestions for the visible members in the given library
-   */
-  static void suggestionsFor(
-      DartCompletionRequest request,
-      CompletionSuggestionKind kind,
-      LibraryElement library,
-      bool typesOnly,
-      bool instCreation) {
-    if (library != null) {
-      library.visitChildren(new LibraryElementSuggestionBuilder(
-          request, kind, typesOnly, instCreation));
-    }
-  }
-}
-
-/**
- * This class visits elements in a class and provides suggestions based upon
- * the visible named constructors in that class.
- */
-class NamedConstructorSuggestionBuilder extends GeneralizingElementVisitor
-    with ElementSuggestionBuilder
-    implements SuggestionBuilder {
-  final DartCompletionRequest request;
-
-  NamedConstructorSuggestionBuilder(this.request);
-
-  @override
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  @override
-  bool computeFast(AstNode node) {
-    return false;
-  }
-
-  @override
-  Future<bool> computeFull(AstNode node) {
-    if (node is SimpleIdentifier) {
-      node = node.parent;
-    }
-    if (node is ConstructorName) {
-      TypeName typeName = node.type;
-      if (typeName != null) {
-        DartType type = typeName.type;
-        if (type != null) {
-          if (type.element is ClassElement) {
-            type.element.accept(this);
-          }
-          return new Future.value(true);
-        }
-      }
-    }
-    return new Future.value(false);
-  }
-
-  @override
-  visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-  }
-
-  @override
-  visitConstructorElement(ConstructorElement element) {
-    addSuggestion(element);
-  }
-
-  @override
-  visitElement(Element element) {
-    // ignored
-  }
-}
-
-/**
- * This class visits elements in a class and provides suggestions based upon
- * the visible static members in that class. Clients should call
- * [StaticClassElementSuggestionBuilder.suggestionsFor].
- */
-class StaticClassElementSuggestionBuilder extends GeneralizingElementVisitor
-    with ElementSuggestionBuilder {
-  final DartCompletionRequest request;
-
-  StaticClassElementSuggestionBuilder(this.request);
-
-  @override
-  CompletionSuggestionKind get kind => CompletionSuggestionKind.INVOCATION;
-
-  @override
-  visitClassElement(ClassElement element) {
-    element.visitChildren(this);
-    element.allSupertypes.forEach((InterfaceType type) {
-      type.element.visitChildren(this);
-    });
-  }
-
-  @override
-  visitElement(Element element) {
-    // ignored
-  }
-
-  @override
-  visitFieldElement(FieldElement element) {
-    if (!element.isStatic) {
-      return;
-    }
-    addSuggestion(element);
-  }
-
-  @override
-  visitMethodElement(MethodElement element) {
-    if (!element.isStatic) {
-      return;
-    }
-    if (element.isOperator) {
-      return;
-    }
-    addSuggestion(element);
-  }
-
-  @override
-  visitPropertyAccessorElement(PropertyAccessorElement element) {
-    if (!element.isStatic) {
-      return;
-    }
-    addSuggestion(element);
-  }
-
-  /**
-   * Add suggestions for the visible members in the given class
-   */
-  static void suggestionsFor(DartCompletionRequest request, Element element) {
-    if (element == DynamicElementImpl.instance) {
-      element = request.cache.objectClassElement;
-    }
-    if (element is ClassElement) {
-      return element.accept(new StaticClassElementSuggestionBuilder(request));
-    }
-  }
-}
-
-/**
  * Common interface implemented by suggestion builders.
  */
 abstract class SuggestionBuilder {
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index c6f1c02..00c48a3 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -413,8 +413,8 @@
         if (token is DocumentationCommentToken &&
             token.type == TokenType.SINGLE_LINE_COMMENT) {
           sb.append(prefix);
-          sb.append(' * ');
-          sb.append(token.lexeme.substring('/// '.length));
+          sb.append(' *');
+          sb.append(token.lexeme.substring('///'.length));
           sb.append(eol);
         } else {
           return;
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index f068b3b..18465d0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -453,11 +453,7 @@
       PartDirective directive = node.parent;
       Source partSource = directive.source;
       CompilationUnit partUnit;
-      if (AnalysisEngine.instance.useTaskModel) {
-        partUnit = context.getResolvedCompilationUnit2(partSource, partSource);
-      } else {
-        partUnit = context.getResolvedCompilationUnit2(partSource, unitSource);
-      }
+      partUnit = context.getResolvedCompilationUnit2(partSource, partSource);
       if (partUnit != null) {
         CorrectionUtils partUtils = new CorrectionUtils(partUnit);
         CorrectionUtils_InsertDesc desc = partUtils.getInsertDescTop();
diff --git a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
index ad42a6e..f238cd5 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/extract_local.dart
@@ -59,6 +59,7 @@
     unitElement = unit.element;
     selectionRange = new SourceRange(selectionOffset, selectionLength);
     utils = new CorrectionUtils(unit);
+    file = unitElement.source.fullName;
   }
 
   @override
@@ -117,6 +118,7 @@
     } else {
       occurrences = [selectionRange];
     }
+    occurrences.sort((a, b) => a.offset - b.offset);
     // If the whole expression of a statement is selected, like '1 + 2',
     // then convert it into a variable declaration statement.
     if (wholeStatementExpression && occurrences.length == 1) {
@@ -127,36 +129,53 @@
       doSourceChange_addElementEdit(change, unitElement, edit);
       return new Future.value(change);
     }
+    // prepare positions
+    List<Position> positions = <Position>[];
+    int occurrencesShift = 0;
+    void addPosition(int offset) {
+      positions.add(new Position(file, offset));
+    }
     // add variable declaration
     {
-      String declarationSource;
+      String declarationCode;
+      int nameOffsetInDeclarationCode;
       if (stringLiteralPart != null) {
-        declarationSource = "var $name = '$stringLiteralPart';";
+        declarationCode = 'var ';
+        nameOffsetInDeclarationCode = declarationCode.length;
+        declarationCode += "$name = '$stringLiteralPart';";
       } else {
         String keyword = _declarationKeyword;
-        String initializerSource = utils.getRangeText(selectionRange);
-        declarationSource = "$keyword $name = $initializerSource;";
+        String initializerCode = utils.getRangeText(selectionRange);
+        declarationCode = '$keyword ';
+        nameOffsetInDeclarationCode = declarationCode.length;
+        declarationCode += '$name = $initializerCode;';
       }
-      String eol = utils.endOfLine;
       // prepare location for declaration
       AstNode target = _findDeclarationTarget(occurrences);
+      String eol = utils.endOfLine;
       // insert variable declaration
       if (target is Statement) {
         String prefix = utils.getNodePrefix(target);
         SourceEdit edit =
-            new SourceEdit(target.offset, 0, declarationSource + eol + prefix);
+            new SourceEdit(target.offset, 0, declarationCode + eol + prefix);
         doSourceChange_addElementEdit(change, unitElement, edit);
+        addPosition(edit.offset + nameOffsetInDeclarationCode);
+        occurrencesShift = edit.replacement.length;
       } else if (target is ExpressionFunctionBody) {
         String prefix = utils.getNodePrefix(target.parent);
         String indent = utils.getIndent(1);
-        String declStatement = prefix + indent + declarationSource + eol;
-        String exprStatement = prefix + indent + 'return ';
         Expression expr = target.expression;
-        doSourceChange_addElementEdit(
-            change,
-            unitElement,
-            new SourceEdit(target.offset, expr.offset - target.offset,
-                '{' + eol + declStatement + exprStatement));
+        {
+          String code = '{' + eol + prefix + indent;
+          addPosition(
+              target.offset + code.length + nameOffsetInDeclarationCode);
+          code += declarationCode + eol;
+          code += prefix + indent + 'return ';
+          SourceEdit edit =
+              new SourceEdit(target.offset, expr.offset - target.offset, code);
+          occurrencesShift = target.offset + code.length - expr.offset;
+          doSourceChange_addElementEdit(change, unitElement, edit);
+        }
         doSourceChange_addElementEdit(change, unitElement,
             new SourceEdit(expr.end, 0, ';' + eol + prefix + '}'));
       }
@@ -165,12 +184,23 @@
     String occurrenceReplacement = name;
     if (stringLiteralPart != null) {
       occurrenceReplacement = "\${$name}";
+      occurrencesShift += 2;
     }
     // replace occurrences with variable reference
     for (SourceRange range in occurrences) {
       SourceEdit edit = newSourceEdit_range(range, occurrenceReplacement);
+      addPosition(range.offset + occurrencesShift);
+      occurrencesShift += name.length - range.length;
       doSourceChange_addElementEdit(change, unitElement, edit);
     }
+    // add the linked group
+    change.addLinkedEditGroup(new LinkedEditGroup(
+        positions,
+        name.length,
+        names
+            .map((name) => new LinkedEditSuggestion(
+                name, LinkedEditSuggestionKind.VARIABLE))
+            .toList()));
     // done
     return new Future.value(change);
   }
@@ -194,8 +224,9 @@
       selectionRange = new SourceRange(offset, end - offset);
     }
     // get covering node
-    AstNode coveringNode = new NodeLocator(
-        selectionRange.offset, selectionRange.end).searchWithin(unit);
+    AstNode coveringNode =
+        new NodeLocator(selectionRange.offset, selectionRange.end)
+            .searchWithin(unit);
     // compute covering expressions
     for (AstNode node = coveringNode;
         node is Expression || node is ArgumentList;
diff --git a/pkg/analysis_server/lib/src/status/element_writer.dart b/pkg/analysis_server/lib/src/status/element_writer.dart
index fd73cef..24c922d 100644
--- a/pkg/analysis_server/lib/src/status/element_writer.dart
+++ b/pkg/analysis_server/lib/src/status/element_writer.dart
@@ -7,7 +7,7 @@
 import 'dart:collection';
 import 'dart:convert';
 
-import 'package:analysis_server/src/get_handler.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
 import 'package:analysis_server/src/status/tree_writer.dart';
 import 'package:analyzer/src/generated/element.dart';
 
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 05937c0..23126f9 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -24,14 +24,15 @@
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analysis_server/src/status/ast_writer.dart';
 import 'package:analysis_server/src/status/element_writer.dart';
+import 'package:analysis_server/src/status/validator.dart';
 import 'package:analysis_server/src/utilities/average.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisCache, AnalysisContextImpl, AnalysisTask;
+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';
@@ -93,6 +94,17 @@
   static const String COMMUNICATION_PERFORMANCE_PATH = '/perf/communication';
 
   /**
+   * The path used to request diagnostic information for a single context.
+   */
+  static const String CONTEXT_DIAGNOSTICS_PATH = '/diagnostic/context';
+
+  /**
+   * The path used to request running a validation report for a single context.
+   */
+  static const String CONTEXT_VALIDATION_DIAGNOSTICS_PATH =
+      '/diagnostic/contextValidation';
+
+  /**
    * The path used to request information about a specific context.
    */
   static const String CONTEXT_PATH = '/context';
@@ -221,7 +233,7 @@
    */
   void handleGetRequest(HttpRequest request) {
     String path = request.uri.path;
-    if (path == STATUS_PATH) {
+    if (path == '/' || path == STATUS_PATH) {
       _returnServerStatus(request);
     } else if (path == ANALYSIS_PERFORMANCE_PATH) {
       _returnAnalysisPerformance(request);
@@ -235,6 +247,10 @@
       _returnCompletionInfo(request);
     } else if (path == COMMUNICATION_PERFORMANCE_PATH) {
       _returnCommunicationPerformance(request);
+    } else if (path == CONTEXT_DIAGNOSTICS_PATH) {
+      _returnContextDiagnostics(request);
+    } else if (path == CONTEXT_VALIDATION_DIAGNOSTICS_PATH) {
+      _returnContextValidationDiagnostics(request);
     } else if (path == CONTEXT_PATH) {
       _returnContextInfo(request);
     } else if (path == DIAGNOSTIC_PATH) {
@@ -973,6 +989,34 @@
   }
 
   /**
+   * Return a response displaying diagnostic information for a single context.
+   */
+  void _returnContextDiagnostics(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Context Diagnostics',
+          ['Context: $contextFilter'], (StringBuffer buffer) {
+        _writeContextDiagnostics(buffer, context);
+      });
+    });
+  }
+
+  /**
    * Return a response containing information about a single source file in the
    * cache.
    */
@@ -1032,9 +1076,6 @@
     explicitNames.sort();
     implicitNames.sort();
 
-    AnalysisDriver driver = (context as AnalysisContextImpl).driver;
-    List<WorkItem> workItems = driver.currentWorkOrder?.workItems;
-
     _overlayContents.clear();
     context.visitContentCache((String fullName, int stamp, String contents) {
       _overlayContents[fullName] = contents;
@@ -1065,69 +1106,54 @@
       _writePage(
           buffer, 'Analysis Server - Context', ['Context: $contextFilter'],
           (StringBuffer buffer) {
-        buffer.write('<h3>Most Recently Perfomed Tasks</h3>');
-        AnalysisTask.LAST_TASKS.forEach((String description) {
-          buffer.write('<p>$description</p>');
-        });
-
-        String _describe(WorkItem item) {
-          if (item == null) {
-            return 'None';
-          }
-          return '${item.descriptor?.name} computing ${item.spawningResult?.name} for ${item.target?.toString()}';
-        }
-
-        buffer.write('<h3>Work Items</h3>');
-        buffer.write(
-            '<p><b>Current:</b> ${_describe(driver.currentWorkOrder?.current)}</p>');
-        if (workItems != null) {
-          buffer.writeAll(workItems.reversed
-              .map((item) => '<p>${_describe(item)}</p>')
-              ?.toList());
-        }
-
         buffer.write('<h3>Configuration</h3>');
 
-        AnalysisOptionsImpl options = context.analysisOptions;
-        buffer.write('<p><b>Options</b></p>');
-        buffer.write('<p>');
-        _writeOption(
-            buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
-        _writeOption(buffer, 'Cache size', options.cacheSize);
-        _writeOption(
-            buffer, 'Enable generic methods', options.enableGenericMethods);
-        _writeOption(buffer, 'Enable strict call checks',
-            options.enableStrictCallChecks);
-        _writeOption(buffer, 'Enable super mixins', options.enableSuperMixins);
-        _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
-        _writeOption(buffer, 'Generate errors in implicit files',
-            options.generateImplicitErrors);
-        _writeOption(
-            buffer, 'Generate errors in SDK files', options.generateSdkErrors);
-        _writeOption(buffer, 'Generate hints', options.hint);
-        _writeOption(buffer, 'Incremental resolution', options.incremental);
-        _writeOption(buffer, 'Incremental resolution with API changes',
-            options.incrementalApi);
-        _writeOption(buffer, 'Preserve comments', options.preserveComments);
-        _writeOption(buffer, 'Strong mode', options.strongMode);
-        _writeOption(buffer, 'Strong mode hints', options.strongModeHints,
-            last: true);
-        buffer.write('</p>');
-
-        List<Linter> lints = context.getConfigurationData(CONFIGURED_LINTS_KEY);
-        buffer.write('<p><b>Lints</b></p>');
-        if (lints.isEmpty) {
-          buffer.write('<p><none></p>');
-        } else {
-          for (Linter lint in lints) {
-            buffer.write('<p> ${lint.runtimeType}</p>');
+        _writeTwoColumns(buffer, (StringBuffer buffer) {
+          AnalysisOptionsImpl options = context.analysisOptions;
+          buffer.write('<p><b>Options</b></p>');
+          buffer.write('<p>');
+          _writeOption(
+              buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
+          _writeOption(buffer, 'Cache size', options.cacheSize);
+          _writeOption(
+              buffer, 'Enable generic methods', options.enableGenericMethods);
+          _writeOption(buffer, 'Enable strict call checks',
+              options.enableStrictCallChecks);
+          _writeOption(
+              buffer, 'Enable super mixins', options.enableSuperMixins);
+          _writeOption(buffer, 'Generate dart2js hints', options.dart2jsHint);
+          _writeOption(buffer, 'Generate errors in implicit files',
+              options.generateImplicitErrors);
+          _writeOption(buffer, 'Generate errors in SDK files',
+              options.generateSdkErrors);
+          _writeOption(buffer, 'Generate hints', options.hint);
+          _writeOption(buffer, 'Incremental resolution', options.incremental);
+          _writeOption(buffer, 'Incremental resolution with API changes',
+              options.incrementalApi);
+          _writeOption(buffer, 'Preserve comments', options.preserveComments);
+          _writeOption(buffer, 'Strong mode', options.strongMode);
+          _writeOption(buffer, 'Strong mode hints', options.strongModeHints,
+              last: true);
+          buffer.write('</p>');
+        }, (StringBuffer buffer) {
+          List<Linter> lints =
+              context.getConfigurationData(CONFIGURED_LINTS_KEY);
+          buffer.write('<p><b>Lints</b></p>');
+          if (lints.isEmpty) {
+            buffer.write('<p>none</p>');
+          } else {
+            for (Linter lint in lints) {
+              buffer.write('<p>');
+              buffer.write(lint.runtimeType);
+              buffer.write('</p>');
+            }
           }
-        }
 
-        List<ErrorFilter> errorFilters =
-            context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-        int filterCount = errorFilters?.length ?? 0;
-        buffer.write('<p><b>Error Filter count</b>: $filterCount</p>');
+          List<ErrorProcessor> errorProcessors =
+              context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+          int processorCount = errorProcessors?.length ?? 0;
+          buffer.write('<p><b>Error Processor count</b>: $processorCount</p>');
+        });
 
         _writeFiles(buffer, 'Priority Files', priorityNames);
         _writeFiles(buffer, 'Explicitly Analyzed Files', explicitNames);
@@ -1135,12 +1161,59 @@
 
         buffer.write('<h3>Exceptions</h3>');
         if (exceptions.isEmpty) {
-          buffer.write('<p>None</p>');
+          buffer.write('<p>none</p>');
         } else {
           exceptions.forEach((CaughtException exception) {
             _writeException(buffer, exception);
           });
         }
+
+        buffer.write('<h3>Targets Without Entries</h3>');
+        bool foundEntry = false;
+        MapIterator<AnalysisTarget, CacheEntry> iterator =
+            context.analysisCache.iterator(context: context);
+        while (iterator.moveNext()) {
+          if (iterator.value == null) {
+            foundEntry = true;
+            buffer.write('<p>');
+            buffer.write(iterator.key.toString());
+            buffer.write(' (');
+            buffer.write(iterator.key.runtimeType.toString());
+            buffer.write(')</p>');
+          }
+        }
+        if (!foundEntry) {
+          buffer.write('<p>none</p>');
+        }
+      });
+    });
+  }
+
+  /**
+   * Return a response displaying the results of running a validation report on
+   * a single context.
+   */
+  void _returnContextValidationDiagnostics(HttpRequest request) {
+    AnalysisServer analysisServer = _server.analysisServer;
+    if (analysisServer == null) {
+      return _returnFailure(request, 'Analysis server is not running');
+    }
+    String contextFilter = request.uri.queryParameters[CONTEXT_QUERY_PARAM];
+    if (contextFilter == null) {
+      return _returnFailure(
+          request, 'Query parameter $CONTEXT_QUERY_PARAM required');
+    }
+    Folder folder = _findFolder(analysisServer, contextFilter);
+    if (folder == null) {
+      return _returnFailure(request, 'Invalid context: $contextFilter');
+    }
+
+    InternalAnalysisContext context = analysisServer.folderMap[folder];
+
+    _writeResponse(request, (StringBuffer buffer) {
+      _writePage(buffer, 'Analysis Server - Context Validation Diagnostics',
+          ['Context: $contextFilter'], (StringBuffer buffer) {
+        _writeContextValidationDiagnostics(buffer, context);
       });
     });
   }
@@ -1149,8 +1222,6 @@
    * Return a response displaying diagnostic information.
    */
   void _returnDiagnosticInfo(HttpRequest request) {
-    String value = request.requestedUri.queryParameters['index'];
-    int index = value != null ? int.parse(value, onError: (_) => 0) : 0;
     _writeResponse(request, (StringBuffer buffer) {
       _writePage(buffer, 'Analysis Server - Diagnostic info', [],
           (StringBuffer buffer) {
@@ -1332,23 +1403,19 @@
   void _returnUnknownRequest(HttpRequest request) {
     _writeResponse(request, (StringBuffer buffer) {
       _writePage(buffer, 'Analysis Server', [], (StringBuffer buffer) {
-        buffer.write('<h3>Pages</h3>');
-        buffer.write('<p>');
-        buffer.write(makeLink(COMPLETION_PATH, {}, 'Completion data'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer
-            .write(makeLink(COMMUNICATION_PERFORMANCE_PATH, {}, 'Performance'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(STATUS_PATH, {}, 'Server status'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(OVERLAYS_PATH, {}, 'File overlays'));
-        buffer.write('</p>');
-        buffer.write('<p>');
-        buffer.write(makeLink(DIAGNOSTIC_PATH, {}, 'Diagnostic info'));
-        buffer.write('</p>');
+        buffer.write('<h3>Unknown page: ');
+        buffer.write(request.uri.path);
+        buffer.write('</h3>');
+        buffer.write('''
+        <p>
+        You have reached an un-recognized page. If you reached this page by
+        following a link from a status page, please report the broken link to
+        the Dart analyzer team:
+        <a>https://github.com/dart-lang/sdk/issues/new</a>.
+        </p><p>
+        If you mistyped the URL, you can correct it or return to
+        ${makeLink(STATUS_PATH, {}, 'the main status page')}.
+        </p>''');
       });
     });
   }
@@ -1374,7 +1441,6 @@
     List<Folder> folders = folderMap.keys.toList();
     folders.sort((Folder first, Folder second) =>
         first.shortName.compareTo(second.shortName));
-    AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
     ServerOperationQueue operationQueue = analysisServer.operationQueue;
 
     buffer.write('<h3>Analysis Domain</h3>');
@@ -1394,6 +1460,9 @@
           buffer.write('<p>Status: Analyzing</p>');
         }
       }
+      buffer.write('<p>');
+      buffer.write(makeLink(OVERLAYS_PATH, {}, 'All overlay information'));
+      buffer.write('</p>');
 
       buffer.write('<p><b>Analysis Contexts</b></p>');
       buffer.write('<p>');
@@ -1407,8 +1476,12 @@
         String key = folder.shortName;
         buffer.write(makeLink(CONTEXT_PATH, {CONTEXT_QUERY_PARAM: folder.path},
             key, _hasException(folderMap[folder])));
+        buffer.write(' <small><b>[');
+        buffer.write(makeLink(CONTEXT_DIAGNOSTICS_PATH,
+            {CONTEXT_QUERY_PARAM: folder.path}, 'diagnostics'));
+        buffer.write(']</b></small>');
         if (!folder.getChild('.packages').exists) {
-          buffer.write(' <b>[No .packages file]</b>');
+          buffer.write(' <small>[no .packages file]</small>');
         }
       });
       // TODO(brianwilkerson) Add items for the SDK contexts (currently only one).
@@ -1416,9 +1489,9 @@
 
       int freq = AnalysisServer.performOperationDelayFreqency;
       String delay = freq > 0 ? '1 ms every $freq ms' : 'off';
-      buffer.write('<p><b>perform operation delay:</b> $delay</p>');
 
       buffer.write('<p><b>Performance Data</b></p>');
+      buffer.write('<p>Perform operation delay: $delay</p>');
       buffer.write('<p>');
       buffer.write(makeLink(ANALYSIS_PERFORMANCE_PATH, {}, 'Task data'));
       buffer.write('</p>');
@@ -1531,6 +1604,70 @@
   }
 
   /**
+   * Write diagnostic information about the given [context] to the given
+   * [buffer].
+   */
+  void _writeContextDiagnostics(
+      StringBuffer buffer, InternalAnalysisContext context) {
+    AnalysisDriver driver = (context as AnalysisContextImpl).driver;
+    List<WorkItem> workItems = driver.currentWorkOrder?.workItems;
+
+    buffer.write('<p>');
+    buffer.write(makeLink(CONTEXT_VALIDATION_DIAGNOSTICS_PATH,
+        {CONTEXT_QUERY_PARAM: context.name}, 'Run validation'));
+    buffer.write('</p>');
+
+    buffer.write('<h3>Most Recently Perfomed Tasks</h3>');
+    AnalysisTask.LAST_TASKS.forEach((String description) {
+      buffer.write('<p>');
+      buffer.write(description);
+      buffer.write('</p>');
+    });
+
+    void writeWorkItem(StringBuffer buffer, WorkItem item) {
+      if (item == null) {
+        buffer.write('none');
+      } else {
+        buffer.write(item.descriptor?.name);
+        buffer.write(' computing ');
+        buffer.write(item.spawningResult?.name);
+        buffer.write(' for ');
+        buffer.write(item.target);
+      }
+    }
+
+    buffer.write('<h3>Work Items</h3>');
+    buffer.write('<p><b>Current:</b> ');
+    writeWorkItem(buffer, driver.currentWorkOrder?.current);
+    buffer.write('</p>');
+    if (workItems != null) {
+      workItems.reversed.forEach((WorkItem item) {
+        buffer.write('<p>');
+        writeWorkItem(buffer, item);
+        buffer.write('</p>');
+      });
+    }
+  }
+
+  /**
+   * Write diagnostic information about the given [context] to the given
+   * [buffer].
+   */
+  void _writeContextValidationDiagnostics(
+      StringBuffer buffer, InternalAnalysisContext context) {
+    Stopwatch stopwatch = new Stopwatch();
+    stopwatch.start();
+    ValidationResults results = new ValidationResults(context);
+    stopwatch.stop();
+
+    buffer.write('<h3>Validation Results</h3>');
+    buffer.write('<p>Re-analysis took ');
+    buffer.write(stopwatch.elapsedMilliseconds);
+    buffer.write(' ms</p>');
+    results.writeOn(buffer);
+  }
+
+  /**
    * Write the status of the diagnostic domain to the given [buffer].
    */
   void _writeDiagnosticStatus(StringBuffer buffer) {
@@ -1546,28 +1683,32 @@
 
     buffer.write('<h3>Timing</h3>');
 
-    buffer.write('<p>');
-    buffer.write('getDiagnostic (last call): $elapsedMs (ms)');
-    buffer.write('<p>');
-    buffer.write('getDiagnostic (rolling average): '
-        '${_diagnosticCallAverage.value} (ms)');
-    buffer.write('<p>&nbsp;');
+    buffer.write('<p>getDiagnostic (last call): ');
+    buffer.write(elapsedMs);
+    buffer.write(' (ms)</p>');
+    buffer.write('<p>getDiagnostic (rolling average): ');
+    buffer.write(_diagnosticCallAverage.value);
+    buffer.write(' (ms)</p>&nbsp;');
 
     var json = response.toJson()[Response.RESULT];
     List contexts = json['contexts'];
+    contexts.sort((first, second) => first['name'].compareTo(second['name']));
     for (var context in contexts) {
-      buffer.write('<p>');
-      buffer.write('<h3>${context["name"]}</h3>');
-      buffer.write('<p>');
-      buffer.write('explicitFileCount: ${context["explicitFileCount"]}');
-      buffer.write('<p>');
-      buffer.write('implicitFileCount: ${context["implicitFileCount"]}');
-      buffer.write('<p>');
-      buffer.write('workItemQueueLength: ${context["workItemQueueLength"]}');
-      buffer.write('<p>');
-      buffer.write('workItemQueueLengthAverage: '
-          '${context["workItemQueueLengthAverage"]}');
-      buffer.write('<p>&nbsp;');
+      buffer.write('<p><h3>');
+      buffer.write(context['name']);
+      buffer.write('</h3></p>');
+      buffer.write('<p>explicitFileCount: ');
+      buffer.write(context['explicitFileCount']);
+      buffer.write('</p>');
+      buffer.write('<p>implicitFileCount: ');
+      buffer.write(context['implicitFileCount']);
+      buffer.write('</p>');
+      buffer.write('<p>workItemQueueLength: ');
+      buffer.write(context['workItemQueueLength']);
+      buffer.write('</p>');
+      buffer.write('<p>workItemQueueLengthAverage: ');
+      buffer.write(context['workItemQueueLengthAverage']);
+      buffer.write('</p>');
     }
   }
 
@@ -1708,6 +1849,8 @@
     buffer.write(
         'h3 {background-color: #DDDDDD; margin-top: 0em; margin-bottom: 0em;}');
     buffer.write('p {margin-top: 0.5em; margin-bottom: 0.5em;}');
+    buffer.write(
+        'p.commentary {margin-top: 1em; margin-bottom: 1em; margin-left: 2em; font-style: italic;}');
 //    response.write('span.error {text-decoration-line: underline; text-decoration-color: red; text-decoration-style: wavy;}');
     buffer.write(
         'table.column {border: 0px solid black; width: 100%; table-layout: fixed;}');
@@ -1868,6 +2011,9 @@
       buffer.write(makeLink(
           COMMUNICATION_PERFORMANCE_PATH, {}, 'Communication performance'));
       buffer.write('</p>');
+      buffer.write('<p>');
+      buffer.write(makeLink(DIAGNOSTIC_PATH, {}, 'General diagnostics'));
+      buffer.write('</p>');
     }, (StringBuffer buffer) {
       _writeSubscriptionList(buffer, ServerService.VALUES, services);
     });
diff --git a/pkg/analysis_server/lib/src/status/tree_writer.dart b/pkg/analysis_server/lib/src/status/tree_writer.dart
index 4b5b3a4..c862a8b 100644
--- a/pkg/analysis_server/lib/src/status/tree_writer.dart
+++ b/pkg/analysis_server/lib/src/status/tree_writer.dart
@@ -2,11 +2,11 @@
 // 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 analysis_server.src.status.ast_writer;
+library analysis_server.src.status.tree_writer;
 
 import 'dart:convert';
 
-import 'package:analysis_server/src/get_handler.dart';
+import 'package:analysis_server/src/status/get_handler.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
diff --git a/pkg/analysis_server/lib/src/status/validator.dart b/pkg/analysis_server/lib/src/status/validator.dart
new file mode 100644
index 0000000..dccf996
--- /dev/null
+++ b/pkg/analysis_server/lib/src/status/validator.dart
@@ -0,0 +1,1787 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analysis_server.src.status.validator;
+
+import 'dart:collection';
+
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisEngine, AnalysisResult, CacheState, ChangeSet;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.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/model.dart';
+import 'package:html/dom.dart' as html;
+
+/**
+ * A class used to compare two element models for equality.
+ */
+class ElementComparator {
+  /**
+   * The buffer to which any discovered differences will be recorded.
+   */
+  final StringBuffer _buffer = new StringBuffer();
+
+  /**
+   * A flag indicating whether a line break should be added the next time data
+   * is written to the [_buffer].
+   */
+  bool _needsLineBreak = false;
+
+  /**
+   * Initialize a newly created comparator.
+   */
+  ElementComparator();
+
+  /**
+   * A textual description of the differences that were found.
+   */
+  String get description => _buffer.toString();
+
+  /**
+   * Return `true` if at least one difference was found between the expected and
+   * actual elements.
+   */
+  bool get hasDifference => _buffer.length > 0;
+
+  /**
+   * Compare the [expected] and [actual] elements. The results of the comparison
+   * can be accessed via the [hasDifference] and [description] getters.
+   */
+  void compareElements(Element expected, Element actual) {
+    if (expected == null) {
+      if (actual != null) {
+        _writeMismatch(expected, actual, (Element element) {
+          return element == null ? 'null' : 'non null ${element.runtimeType}';
+        });
+      }
+    } else if (actual == null) {
+      _writeMismatch(expected, actual, (Element element) {
+        return element == null ? 'null' : 'non null ${element.runtimeType}';
+      });
+    } else if (expected is ClassElement && actual is ClassElement) {
+      _compareClassElements(expected, actual);
+    } else if (expected is CompilationUnitElement &&
+        actual is CompilationUnitElement) {
+      _compareCompilationUnitElements(expected, actual);
+    } else if (expected is ConstructorElement && actual is ConstructorElement) {
+      _compareConstructorElements(expected, actual);
+    } else if (expected is ExportElement && actual is ExportElement) {
+      _compareExportElements(expected, actual);
+    } else if (expected is FieldElement && actual is FieldElement) {
+      _compareFieldElements(expected, actual);
+    } else if (expected is FieldFormalParameterElement &&
+        actual is FieldFormalParameterElement) {
+      _compareFieldFormalParameterElements(expected, actual);
+    } else if (expected is FunctionElement && actual is FunctionElement) {
+      _compareFunctionElements(expected, actual);
+    } else if (expected is FunctionTypeAliasElement &&
+        actual is FunctionTypeAliasElement) {
+      _compareFunctionTypeAliasElements(expected, actual);
+    } else if (expected is ImportElement && actual is ImportElement) {
+      _compareImportElements(expected, actual);
+    } else if (expected is LabelElement && actual is LabelElement) {
+      _compareLabelElements(expected, actual);
+    } else if (expected is LibraryElement && actual is LibraryElement) {
+      _compareLibraryElements(expected, actual);
+    } else if (expected is LocalVariableElement &&
+        actual is LocalVariableElement) {
+      _compareLocalVariableElements(expected, actual);
+    } else if (expected is MethodElement && actual is MethodElement) {
+      _compareMethodElements(expected, actual);
+    } else if (expected is MultiplyDefinedElement &&
+        actual is MultiplyDefinedElement) {
+      _compareMultiplyDefinedElements(expected, actual);
+    } else if (expected is ParameterElement && actual is ParameterElement) {
+      _compareParameterElements(expected, actual);
+    } else if (expected is PrefixElement && actual is PrefixElement) {
+      _comparePrefixElements(expected, actual);
+    } else if (expected is PropertyAccessorElement &&
+        actual is PropertyAccessorElement) {
+      _comparePropertyAccessorElements(expected, actual);
+    } else if (expected is TopLevelVariableElement &&
+        actual is TopLevelVariableElement) {
+      _compareTopLevelVariableElements(expected, actual);
+    } else if (expected is TypeParameterElement &&
+        actual is TypeParameterElement) {
+      _compareTypeParameterElements(expected, actual);
+    } else {
+      _write('Expected an instance of ');
+      _write(expected.runtimeType);
+      _write('; found an instance of ');
+      _writeln(actual.runtimeType);
+    }
+  }
+
+  void _compareClassElements(ClassElement expected, ClassElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.hasReferenceToSuper != actual.hasReferenceToSuper) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) => element.hasReferenceToSuper
+              ? 'a class that references super'
+              : 'a class that does not reference super');
+    }
+    if (expected.isAbstract != actual.isAbstract) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) =>
+              element.isAbstract ? 'an abstract class' : 'a concrete class');
+    }
+    if (expected.isEnum != actual.isEnum ||
+        expected.isMixinApplication != actual.isMixinApplication) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) => element.isEnum
+              ? 'an enum'
+              : (element.isMixinApplication
+                  ? 'a mixin application'
+                  : 'a class'));
+    }
+    if (expected.isOrInheritsProxy != actual.isOrInheritsProxy) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) => element.isOrInheritsProxy
+              ? 'a class that is marked as a proxy'
+              : 'a class that is not marked as a proxy');
+    }
+    if (expected.isValidMixin != actual.isValidMixin) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ClassElement element) =>
+              element.isValidMixin ? 'a valid mixin' : 'an invalid mixin');
+    }
+    _compareTypes('supertype', expected.supertype, actual.supertype);
+    _compareTypeLists('mixin', expected.mixins, actual.mixins);
+    _compareTypeLists('interface', expected.interfaces, actual.interfaces);
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.accessors, actual.accessors);
+    _compareElementLists(expected.constructors, actual.constructors);
+    _compareElementLists(expected.fields, actual.fields);
+    _compareElementLists(expected.methods, actual.methods);
+    _compareElementLists(expected.typeParameters, actual.typeParameters);
+  }
+
+  void _compareCompilationUnitElements(
+      CompilationUnitElement expected, CompilationUnitElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.accessors, actual.accessors);
+    _compareElementLists(expected.enums, actual.enums);
+    _compareElementLists(expected.functions, actual.functions);
+    _compareElementLists(
+        expected.functionTypeAliases, actual.functionTypeAliases);
+    _compareElementLists(expected.topLevelVariables, actual.topLevelVariables);
+    _compareElementLists(expected.types, actual.types);
+  }
+
+  void _compareConstructorElements(
+      ConstructorElement expected, ConstructorElement actual) {
+    _compareExecutableElements(expected, actual, 'constructor');
+    //
+    // Compare attributes.
+    //
+    if (expected.isConst != actual.isConst) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ConstructorElement element) => element.isConst
+              ? 'a const constructor'
+              : 'a non-const constructor');
+    }
+    if (expected.isFactory != actual.isFactory) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ConstructorElement element) => element.isFactory
+              ? 'a factory constructor'
+              : 'a non-factory constructor');
+    }
+    if (expected.periodOffset != actual.periodOffset) {
+      _write('Expected a period offset of ');
+      _write(expected.periodOffset);
+      _write('; found ');
+      _writeln(actual.periodOffset);
+    }
+    if ((expected.redirectedConstructor == null) !=
+        (actual.redirectedConstructor == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ConstructorElement element) => element.redirectedConstructor == null
+              ? 'a redirecting constructor'
+              : 'a non-redirecting constructor');
+    }
+  }
+
+  void _compareElementLists(List expected, List actual) {
+    Set<Element> extraElements = new HashSet<Element>();
+    Map<Element, Element> commonElements = new HashMap<Element, Element>();
+
+    Map<String, Element> expectedElements = new HashMap<String, Element>();
+    for (Element expectedElement in expected) {
+      expectedElements[expectedElement.name] = expectedElement;
+    }
+    for (Element actualElement in actual) {
+      String name = actualElement.name;
+      Element expectedElement = expectedElements[name];
+      if (expectedElement == null) {
+        extraElements.add(actualElement);
+      } else {
+        commonElements[expectedElement] = actualElement;
+        expectedElements.remove(name);
+      }
+    }
+
+    commonElements.forEach((Element expected, Element actual) {
+      compareElements(expected, actual);
+    });
+    void writeElement(Element element) {
+      _write('an instance of ');
+      _write(element.runtimeType);
+      if (element.name == null) {
+        _write(' with no name');
+      } else {
+        _write(' named ');
+        _write(element.name);
+      }
+    }
+    expectedElements.forEach((String name, Element element) {
+      _write('Expected ');
+      writeElement(element);
+      _writeln('; found no match');
+    });
+    extraElements.forEach((Element element) {
+      _write('Expected nothing; found ');
+      writeElement(element);
+    });
+  }
+
+  void _compareExecutableElements(
+      ExecutableElement expected, ExecutableElement actual, String kind) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.hasImplicitReturnType != actual.hasImplicitReturnType) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.hasImplicitReturnType
+              ? 'an implicit return type'
+              : 'an explicit return type');
+    }
+    if (expected.isAbstract != actual.isAbstract) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) =>
+              element.isAbstract ? 'an abstract $kind' : 'a concrete $kind');
+    }
+    if (expected.isAsynchronous != actual.isAsynchronous) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.isAsynchronous
+              ? 'an asynchronous $kind'
+              : 'a synchronous $kind');
+    }
+    if (expected.isExternal != actual.isExternal) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.isExternal
+              ? 'an external $kind'
+              : 'a non-external $kind');
+    }
+    if (expected.isGenerator != actual.isGenerator) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.isGenerator
+              ? 'a generator $kind'
+              : 'a non-generator $kind');
+    }
+    if (expected.isOperator != actual.isOperator) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) =>
+              element.isOperator ? 'an operator' : 'a non-operator $kind');
+    }
+    if (expected.isStatic != actual.isStatic) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) =>
+              element.isStatic ? 'a static $kind' : 'an instance $kind');
+    }
+    if ((expected.returnType == null) != (actual.returnType == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ExecutableElement element) => element.returnType == null
+              ? 'a $kind with no return type'
+              : 'a $kind with a return type');
+    } else {
+      _compareTypes('return type', expected.returnType, actual.returnType);
+    }
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.functions, actual.functions);
+    _compareElementLists(expected.labels, actual.labels);
+    _compareElementLists(expected.localVariables, actual.localVariables);
+    _compareElementLists(expected.parameters, actual.parameters);
+    _compareElementLists(expected.typeParameters, actual.typeParameters);
+  }
+
+  void _compareExportElements(ExportElement expected, ExportElement actual) {
+    _compareUriReferencedElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if ((expected.exportedLibrary == null) !=
+        (actual.exportedLibrary == null)) {
+      // TODO(brianwilkerson) Check for more than existence?
+      _writeMismatch(
+          expected,
+          actual,
+          (ExportElement element) => element.exportedLibrary == null
+              ? 'unresolved uri'
+              : 'uri resolved to ${element.exportedLibrary.source.fullName}');
+    }
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.combinators, actual.combinators);
+  }
+
+  void _compareFieldElements(FieldElement expected, FieldElement actual) {
+    _comparePropertyInducingElements(expected, actual, 'field');
+    //
+    // Compare attributes.
+    //
+    if (expected.isEnumConstant != actual.isEnumConstant) {
+      _writeMismatch(
+          expected,
+          actual,
+          (FieldElement element) =>
+              element.isEnumConstant ? 'an enum constant' : 'a normal field');
+    }
+  }
+
+  void _compareFieldFormalParameterElements(
+      FieldFormalParameterElement expected,
+      FieldFormalParameterElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareFunctionElements(
+      FunctionElement expected, FunctionElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareFunctionTypeAliasElements(
+      FunctionTypeAliasElement expected, FunctionTypeAliasElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareGenericElements(Element expected, Element actual) {
+    _compareMetadata(expected.metadata, actual.metadata);
+    if (expected.nameOffset != actual.nameOffset) {
+      _write('Expected name offset of ');
+      _write(expected.nameOffset);
+      _write('; found ');
+      _writeln(actual.nameOffset);
+    }
+    SourceRange expectedRange = expected.docRange;
+    SourceRange actualRange = actual.docRange;
+    if (expectedRange.offset != actualRange.offset ||
+        expectedRange.length != actualRange.length) {
+      _write('Expected documentation range of ');
+      _write(expectedRange);
+      _write('; found ');
+      _writeln(actualRange);
+    }
+  }
+
+  void _compareImportElements(ImportElement expected, ImportElement actual) {
+    _compareUriReferencedElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.isDeferred != actual.isDeferred) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ImportElement element) => element.isDeferred
+              ? 'a deferred import'
+              : 'a non-deferred import');
+    }
+    if ((expected.importedLibrary == null) !=
+        (actual.importedLibrary == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ImportElement element) => element.importedLibrary == null
+              ? 'unresolved uri'
+              : 'uri resolved to ${element.importedLibrary.source.fullName}');
+    }
+    if ((expected.prefix == null) != (actual.prefix == null)) {
+      _writeMismatch(
+          expected,
+          actual,
+          (ImportElement element) => element.prefix == null
+              ? 'no prefix'
+              : 'a prefix named ${element.prefix.name}');
+    }
+    if (expected.prefixOffset != actual.prefixOffset) {
+      _write('Expected a prefix offset of ');
+      _write(expected.prefixOffset);
+      _write('; found ');
+      _writeln(actual.prefixOffset);
+    }
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.combinators, actual.combinators);
+  }
+
+  void _compareLabelElements(LabelElement expected, LabelElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareLibraryElements(LibraryElement expected, LibraryElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    // TODO(brianwilkerson) Implement this
+    expected.hasLoadLibraryFunction;
+    expected.name;
+    expected.source;
+    //
+    // Compare children.
+    //
+    _compareElementLists(expected.imports, actual.imports);
+    _compareElementLists(expected.exports, actual.exports);
+    _compareElementLists(expected.units, actual.units);
+  }
+
+  void _compareLocalVariableElements(
+      LocalVariableElement expected, LocalVariableElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareMetadata(
+      List<ElementAnnotation> expected, List<ElementAnnotation> actual) {
+    // TODO(brianwilkerson) Implement this
+  }
+
+  void _compareMethodElements(MethodElement expected, MethodElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareExecutableElements(expected, actual, 'method');
+    //
+    // Compare attributes.
+    //
+    if (expected.isStatic != actual.isStatic) {
+      _writeMismatch(
+          expected,
+          actual,
+          (FieldElement element) =>
+              element.isStatic ? 'a static field' : 'an instance field');
+    }
+  }
+
+  void _compareMultiplyDefinedElements(
+      MultiplyDefinedElement expected, MultiplyDefinedElement actual) {
+    // TODO(brianwilkerson) Implement this
+  }
+
+  void _compareParameterElements(
+      ParameterElement expected, ParameterElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _comparePrefixElements(PrefixElement expected, PrefixElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _comparePropertyAccessorElements(
+      PropertyAccessorElement expected, PropertyAccessorElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _comparePropertyInducingElements(PropertyInducingElement expected,
+      PropertyInducingElement actual, String kind) {
+    _compareVariableElements(expected, actual, kind);
+  }
+
+  void _compareTopLevelVariableElements(
+      TopLevelVariableElement expected, TopLevelVariableElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+  }
+
+  void _compareTypeLists(String descriptor, List<InterfaceType> expected,
+      List<InterfaceType> actual) {
+    int expectedLength = expected.length;
+    if (expectedLength != actual.length) {
+      _write('Expected ');
+      _write(expectedLength);
+      _write(' ');
+      _write(descriptor);
+      _write('s; found ');
+      _write(actual.length);
+    } else {
+      for (int i = 0; i < expectedLength; i++) {
+        _compareTypes(descriptor, expected[i], actual[i]);
+      }
+    }
+  }
+
+  void _compareTypeParameterElements(
+      TypeParameterElement expected, TypeParameterElement actual) {
+    // TODO(brianwilkerson) Implement this
+    _compareGenericElements(expected, actual);
+    expected.bound;
+  }
+
+  void _compareTypes(String descriptor, DartType expected, DartType actual) {
+    void compareNames() {
+      if (expected.name != actual.name) {
+        _write('Expected a ');
+        _write(descriptor);
+        _write(' named ');
+        _write(expected.name);
+        _write('; found a ');
+        _write(descriptor);
+        _write(' named ');
+        _write(actual.name);
+      }
+    }
+    void compareTypeArguments(
+        ParameterizedType expected, ParameterizedType actual) {
+      List<DartType> expectedArguments = expected.typeArguments;
+      List<DartType> actualArguments = actual.typeArguments;
+      int expectedLength = expectedArguments.length;
+      if (expectedLength != actualArguments.length) {
+        _write('Expected ');
+        _write(expectedLength);
+        _write(' type arguments; found ');
+        _write(actualArguments.length);
+      } else {
+        for (int i = 0; i < expectedLength; i++) {
+          _compareTypes(
+              'type argument', expectedArguments[i], actualArguments[i]);
+        }
+      }
+    }
+
+    if (expected == null) {
+      if (actual != null) {
+        _write('Expected no ');
+        _write(descriptor);
+        _write('; found a ');
+        _write(descriptor);
+        _write(' named ');
+        _write(actual.name);
+      }
+    } else if (actual == null) {
+      _write('Expected a ');
+      _write(descriptor);
+      _write(' named ');
+      _write(expected.name);
+      _write('; found none');
+    } else if ((expected.isBottom && actual.isBottom) ||
+        (expected.isDynamic && actual.isDynamic) ||
+        (expected.isVoid && actual.isVoid)) {
+      // The types are the same
+    } else if (expected is InterfaceType && actual is InterfaceType) {
+      compareNames();
+      compareTypeArguments(expected, actual);
+    } else if (expected is FunctionType && actual is FunctionType) {
+      compareNames();
+      compareTypeArguments(expected, actual);
+    } else if (expected is TypeParameterType && actual is TypeParameterType) {
+      compareNames();
+      _compareTypes('bound', expected.element.bound, actual.element.bound);
+    } else {
+      _write('Expected an instance of ');
+      _write(expected.runtimeType);
+      _write(' named ');
+      _write(expected.name);
+      _write('; found an instance of ');
+      _writeln(actual.runtimeType);
+      _write(' named ');
+      _write(actual.name);
+    }
+  }
+
+  void _compareUriReferencedElements(
+      UriReferencedElement expected, UriReferencedElement actual) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if (expected.uri != actual.uri) {
+      _write('Expected a uri of ');
+      _write(expected.uri);
+      _write('; found ');
+      _writeln(actual.uri);
+    }
+    if (expected.uriOffset != actual.uriOffset) {
+      _write('Expected a uri offset of ');
+      _write(expected.uriOffset);
+      _write('; found ');
+      _writeln(actual.uriOffset);
+    }
+  }
+
+  void _compareVariableElements(
+      VariableElement expected, VariableElement actual, String kind) {
+    _compareGenericElements(expected, actual);
+    //
+    // Compare attributes.
+    //
+    if ((expected.constantValue == null) != (actual.constantValue == null)) {
+      // TODO(brianwilkerson) Check for more than existence.
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.constantValue == null
+              ? 'a $kind with no constant value'
+              : 'a $kind with a constant value');
+    }
+    if (expected.hasImplicitType != actual.hasImplicitType) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.hasImplicitType
+              ? 'a $kind with an implicit type'
+              : 'a $kind with an explicit type');
+    }
+    if (expected.isConst != actual.isConst) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) =>
+              element.isConst ? 'a const $kind' : 'a non-const $kind');
+    }
+    if (expected.isFinal != actual.isFinal) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) =>
+              element.isFinal ? 'a final $kind' : 'a non-final $kind');
+    }
+    if (expected.isPotentiallyMutatedInClosure !=
+        actual.isPotentiallyMutatedInClosure) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.isPotentiallyMutatedInClosure
+              ? 'a $kind that is potentially mutated in a closure'
+              : 'a $kind that is not mutated in a closure');
+    }
+    if (expected.isPotentiallyMutatedInScope !=
+        actual.isPotentiallyMutatedInScope) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) => element.isPotentiallyMutatedInScope
+              ? 'a $kind that is potentially mutated in its scope'
+              : 'a $kind that is not mutated in its scope');
+    }
+    if (expected.isStatic != actual.isStatic) {
+      _writeMismatch(
+          expected,
+          actual,
+          (VariableElement element) =>
+              element.isStatic ? 'a static $kind' : 'an instance $kind');
+    }
+    //
+    // Compare children.
+    //
+    compareElements(expected.initializer, actual.initializer);
+  }
+
+  void _write(Object value) {
+    if (_needsLineBreak) {
+      _buffer.write('</p><p>');
+      _needsLineBreak = false;
+    }
+    _buffer.write(value);
+  }
+
+  void _writeln(Object value) {
+    _buffer.write(value);
+    _needsLineBreak = true;
+  }
+
+  /**
+   * Write a simple message explaining that the [expected] and [actual] values
+   * were different, using the [describe] function to describe the values.
+   */
+  void _writeMismatch /*<E>*/ (Object /*=E*/ expected, Object /*=E*/ actual,
+      String describe(Object /*=E*/ value)) {
+    _write('Expected ');
+    _write(describe(expected));
+    _write('; found ');
+    _writeln(describe(actual));
+  }
+}
+
+/**
+ * The comparison of two analyses of the same target.
+ */
+class EntryComparison {
+  /**
+   * The target that was analyzed.
+   */
+  final AnalysisTarget target;
+
+  /**
+   * The cache entry from the original context.
+   */
+  final CacheEntry originalEntry;
+
+  /**
+   * The cache entry from the re-analysis in a cloned context.
+   */
+  final CacheEntry cloneEntry;
+
+  /**
+   * A flag indicating whether the target is obsolete. A target is obsolete if
+   * it is an element in an element model that was replaced at a some point.
+   */
+  bool obsoleteTarget = false;
+
+  /**
+   * A table mapping the results that were computed for the target to
+   * comparisons of the values of those results. The table only contains entries
+   * for results for which the comparison produced interesting data.
+   */
+  Map<ResultDescriptor, ResultComparison> resultMap =
+      new HashMap<ResultDescriptor, ResultComparison>();
+
+  /**
+   * Initialize a newly created comparison of the given [target]'s analysis,
+   * given the [originalEntry] from the original context and the [cloneEntry]
+   * from the cloned context.
+   */
+  EntryComparison(this.target, this.originalEntry, this.cloneEntry) {
+    _performComparison();
+  }
+
+  /**
+   * Return `true` if there is something interesting about the analysis of this
+   * target that should be reported.
+   */
+  bool hasInterestingState() => obsoleteTarget || resultMap.isNotEmpty;
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    buffer.write('<p>');
+    buffer.write(target);
+    buffer.write('</p>');
+    buffer.write('<blockquote>');
+    if (obsoleteTarget) {
+      buffer.write('<p><b>This target is obsolete.</b></p>');
+    }
+    List<ResultDescriptor> results = resultMap.keys.toList();
+    results.sort((ResultDescriptor first, ResultDescriptor second) =>
+        first.toString().compareTo(second.toString()));
+    for (ResultDescriptor result in results) {
+      resultMap[result].writeOn(buffer);
+    }
+    buffer.write('</blockquote>');
+  }
+
+  /**
+   * Compare all of the results that were computed in the two contexts, adding
+   * the interesting comparisons to the [resultMap].
+   */
+  void _compareResults() {
+    Set<ResultDescriptor> results = new Set<ResultDescriptor>();
+    results.addAll(originalEntry.nonInvalidResults);
+    results.addAll(cloneEntry.nonInvalidResults);
+
+    for (ResultDescriptor result in results) {
+      ResultComparison difference = new ResultComparison(this, result);
+      if (difference.hasInterestingState()) {
+        resultMap[result] = difference;
+      }
+    }
+  }
+
+  /**
+   * Return `true` if the target of this entry is an obsolete element.
+   */
+  bool _isTargetObsolete() {
+    if (target is Element) {
+      LibraryElement library = (target as Element).library;
+      AnalysisContextImpl context = library.context;
+      CacheEntry entry = context.analysisCache.get(library.source);
+      LibraryElement value = entry.getValue(LIBRARY_ELEMENT);
+      return value != library;
+    }
+    return false;
+  }
+
+  /**
+   * Determine whether or not there is any interesting difference between the
+   * original and cloned contexts.
+   */
+  void _performComparison() {
+    obsoleteTarget = _isTargetObsolete();
+    _compareResults();
+  }
+}
+
+/**
+ * The comparison of the value of a single result computed for a single target.
+ */
+class ResultComparison {
+  /**
+   * The entry for the target for which the result was computed.
+   */
+  final EntryComparison entry;
+
+  /**
+   * The result that was computed for the target.
+   */
+  final ResultDescriptor result;
+
+  /**
+   * A flag indicating whether the state of the result is different.
+   */
+  bool differentStates = false;
+
+  /**
+   * The result of comparing the values of the results, or `null` if the states
+   * are different or if the values are the same.
+   */
+  ValueComparison valueComparison;
+
+  /**
+   * Initialize a newly created result comparison.
+   */
+  ResultComparison(this.entry, this.result) {
+    _performComparison();
+  }
+
+  /**
+   * Return `true` if this object represents a difference between the original
+   * and cloned contexts.
+   */
+  bool hasInterestingState() => differentStates || valueComparison != null;
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    buffer.write('<p>');
+    buffer.write(result);
+    buffer.write('</p>');
+    buffer.write('<blockquote>');
+    if (differentStates) {
+      CacheState originalState = entry.originalEntry.getState(result);
+      CacheState cloneState = entry.cloneEntry.getState(result);
+      buffer.write('<p>Original state = ');
+      buffer.write(originalState.name);
+      buffer.write('; clone state = ');
+      buffer.write(cloneState.name);
+      buffer.write('</p>');
+    }
+    if (valueComparison != null) {
+      valueComparison.writeOn(buffer);
+    }
+    buffer.write('</blockquote>');
+  }
+
+  /**
+   * Determine whether the state of the result is different between the
+   * original and cloned contexts.
+   */
+  bool _areStatesDifferent(CacheState originalState, CacheState cloneState) {
+    if (originalState == cloneState) {
+      return false;
+    } else if (originalState == CacheState.FLUSHED &&
+        cloneState == CacheState.VALID) {
+      return false;
+    } else if (originalState == CacheState.VALID &&
+        cloneState == CacheState.FLUSHED) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Determine whether the value of the result is different between the
+   * original and cloned contexts.
+   */
+  void _compareValues(CacheState originalState, CacheState cloneState) {
+    if (originalState != cloneState || originalState != CacheState.VALID) {
+      return null;
+    }
+    ValueComparison comparison = new ValueComparison(
+        entry.originalEntry.getValue(result),
+        entry.cloneEntry.getValue(result));
+    if (comparison.hasInterestingState()) {
+      valueComparison = comparison;
+    }
+  }
+
+  /**
+   * Determine whether or not there is any interesting difference between the
+   * original and cloned contexts.
+   */
+  void _performComparison() {
+    CacheState originalState = entry.originalEntry.getState(result);
+    CacheState cloneState = entry.cloneEntry.getState(result);
+    if (_areStatesDifferent(originalState, cloneState)) {
+      differentStates = true;
+      _compareValues(originalState, cloneState);
+    }
+  }
+}
+
+/**
+ * The results of validating an analysis context.
+ *
+ * Validation is done by re-analyzing all of the explicitly added source in a
+ * new analysis context that is configured to be the same as the original
+ * context.
+ */
+class ValidationResults {
+  /**
+   * A set of targets that were in the original context that were not included
+   * in the re-created context.
+   */
+  Set<AnalysisTarget> extraTargets;
+
+  /**
+   * A set of targets that were in the re-created context that were not included
+   * in the original context.
+   */
+  Set<AnalysisTarget> missingTargets;
+
+  /**
+   * A table, keyed by targets, whose values are comparisons of the analysis of
+   * those targets. The table only contains entries for targets for which the
+   * comparison produced interesting data.
+   */
+  Map<AnalysisTarget, EntryComparison> targetMap =
+      new HashMap<AnalysisTarget, EntryComparison>();
+
+  /**
+   * Initialize a newly created validation result by validating the given
+   * [context].
+   */
+  ValidationResults(AnalysisContextImpl context) {
+    _validate(context);
+  }
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    if (extraTargets.isEmpty && missingTargets.isEmpty && targetMap.isEmpty) {
+      buffer.write('<p>No interesting results.</p>');
+      return;
+    }
+    if (extraTargets.isNotEmpty) {
+      buffer.write('<h4>Extra Targets</h4>');
+      buffer.write('<p style="commentary">');
+      buffer.write('Targets that exist in the original context that were not ');
+      buffer.write('re-created in the cloned context.');
+      buffer.write('</p>');
+      _writeTargetList(buffer, extraTargets.toList());
+    }
+    if (missingTargets.isNotEmpty) {
+      buffer.write('<h4>Missing Targets</h4>');
+      buffer.write('<p style="commentary">');
+      buffer.write('Targets that do <b>not</b> exist in the original context ');
+      buffer.write('but do exist in the cloned context.');
+      buffer.write('</p>');
+      _writeTargetList(buffer, missingTargets.toList());
+    }
+    if (targetMap.isNotEmpty) {
+      buffer.write('<h4>Differing Targets</h4>');
+      // TODO(brianwilkerson) Sort the list of targets.
+      for (EntryComparison comparison in targetMap.values) {
+        comparison.writeOn(buffer);
+      }
+    }
+  }
+
+  /**
+   * Analyze all of the explicit sources in the given [context].
+   */
+  void _analyze(AnalysisContextImpl context) {
+    while (true) {
+      AnalysisResult result = context.performAnalysisTask();
+      if (!result.hasMoreWork) {
+        return;
+      }
+    }
+  }
+
+  /**
+   * Create and return a new analysis context that will analyze files in the
+   * same way as the given [context].
+   */
+  AnalysisContextImpl _clone(AnalysisContextImpl context) {
+    AnalysisContextImpl clone = AnalysisEngine.instance.createAnalysisContext();
+
+    clone.analysisOptions = context.analysisOptions;
+    //clone.declaredVariables = context.declaredVariables;
+    clone.sourceFactory = context.sourceFactory.clone();
+    // TODO(brianwilkerson) Check content cache. We either need to copy the
+    // cache into the clone or ensure that the context's cache is empty.
+
+    ChangeSet changeSet = new ChangeSet();
+    for (AnalysisTarget target in context.explicitTargets) {
+      if (target is Source) {
+        changeSet.addedSource(target);
+      }
+    }
+    clone.applyChanges(changeSet);
+    return clone;
+  }
+
+  /**
+   * Compare the results produced in the [original] context to those produced in
+   * the [clone].
+   */
+  void _compareContexts(
+      AnalysisContextImpl original, AnalysisContextImpl clone) {
+    AnalysisCache originalCache = original.analysisCache;
+    AnalysisCache cloneCache = clone.analysisCache;
+    List<AnalysisTarget> originalTargets = _getKeys(original, originalCache);
+    List<AnalysisTarget> cloneTargets = _getKeys(clone, cloneCache);
+
+    extraTargets =
+        new HashSet<AnalysisTarget>(equals: _equal, hashCode: _hashCode);
+    extraTargets.addAll(originalTargets);
+    extraTargets.removeAll(cloneTargets);
+
+    missingTargets =
+        new HashSet<AnalysisTarget>(equals: _equal, hashCode: _hashCode);
+    missingTargets.addAll(cloneTargets);
+    missingTargets.removeAll(originalTargets);
+
+    for (AnalysisTarget cloneTarget in cloneTargets) {
+      if (!missingTargets.contains(cloneTarget)) {
+        AnalysisTarget originalTarget = _find(originalTargets, cloneTarget);
+        CacheEntry originalEntry = originalCache.get(originalTarget);
+        CacheEntry cloneEntry = cloneCache.get(cloneTarget);
+        EntryComparison comparison =
+            new EntryComparison(cloneTarget, originalEntry, cloneEntry);
+        if (comparison.hasInterestingState()) {
+          targetMap[cloneTarget] = comparison;
+        }
+      }
+    }
+  }
+
+  /**
+   * Find the target in the list of [originalTargets] that is equal to the
+   * [cloneTarget].
+   */
+  AnalysisTarget _find(
+      List<AnalysisTarget> originalTargets, AnalysisTarget cloneTarget) {
+    for (AnalysisTarget originalTarget in originalTargets) {
+      if (_equal(originalTarget, cloneTarget)) {
+        return originalTarget;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return a list of the analysis targets in the given [cache] that are owned
+   * by the given [context].
+   */
+  List<AnalysisTarget> _getKeys(
+      AnalysisContextImpl context, AnalysisCache cache) {
+    List<AnalysisTarget> targets = <AnalysisTarget>[];
+    MapIterator<AnalysisTarget, CacheEntry> iterator =
+        cache.iterator(context: context);
+    while (iterator.moveNext()) {
+      targets.add(iterator.key);
+    }
+    return targets;
+  }
+
+  /**
+   * Validate the given [context].
+   */
+  void _validate(AnalysisContextImpl context) {
+    AnalysisContextImpl clone = _clone(context);
+    _analyze(clone);
+    _compareContexts(context, clone);
+  }
+
+  /**
+   * Write the list of [targets] to the [buffer].
+   */
+  void _writeTargetList(StringBuffer buffer, List<AnalysisTarget> targets) {
+    // TODO(brianwilkerson) Sort the list of targets.
+    //targets.sort();
+    for (AnalysisTarget target in targets) {
+      buffer.write('<p>');
+      buffer.write(target);
+      buffer.write(' (');
+      buffer.write(target.runtimeType);
+      buffer.write(')');
+      buffer.write('</p>');
+    }
+  }
+
+  /**
+   * Return `true` if the [first] and [second] objects are equal.
+   */
+  static bool _equal(Object first, Object second) {
+    //
+    // Compare possible null values.
+    //
+    if (first == null) {
+      return second == null;
+    } else if (second == null) {
+      return false;
+    }
+    //
+    // Handle special cases.
+    //
+    if (first is ConstantEvaluationTarget_Annotation &&
+        second is ConstantEvaluationTarget_Annotation) {
+      return _equal(first.source, second.source) &&
+          _equal(first.librarySource, second.librarySource) &&
+          _equal(first.annotation, second.annotation);
+    } else if (first is AstNode && second is AstNode) {
+      return first.runtimeType == second.runtimeType &&
+          first.offset == second.offset &&
+          first.length == second.length;
+    }
+    //
+    // Handle the general case.
+    //
+    return first == second;
+  }
+
+  /**
+   * Return a hash code for the given [object].
+   */
+  static int _hashCode(Object object) {
+    //
+    // Handle special cases.
+    //
+    if (object is ConstantEvaluationTarget_Annotation) {
+      return object.source.hashCode;
+    } else if (object is AstNode) {
+      return object.offset;
+    }
+    //
+    // Handle the general case.
+    //
+    return object.hashCode;
+  }
+}
+
+class ValueComparison {
+  /**
+   * The result value from the original context.
+   */
+  final Object originalValue;
+
+  /**
+   * The result value from the cloned context.
+   */
+  final Object cloneValue;
+
+  /**
+   * A description of the difference between the original and clone values, or
+   * `null` if the values are equal.
+   */
+  String description = null;
+
+  /**
+   * Initialize a newly created value comparison to represents the difference,
+   * if any, between the [originalValue] and the [cloneValue].
+   */
+  ValueComparison(this.originalValue, this.cloneValue) {
+    _performComparison();
+  }
+
+  /**
+   * Return `true` if this object represents a difference between the original
+   * and cloned values.
+   */
+  bool hasInterestingState() => description != null;
+
+  /**
+   * Write an HTML formatted description of the validation results to the given
+   * [buffer].
+   */
+  void writeOn(StringBuffer buffer) {
+    buffer.write('<p>');
+    buffer.write(description);
+    buffer.write('</p>');
+  }
+
+  bool _compareAnalysisErrors(
+      AnalysisError expected, AnalysisError actual, StringBuffer buffer) {
+    if (actual.errorCode == expected.errorCode &&
+        actual.source == expected.source &&
+        actual.offset == expected.offset) {
+      return true;
+    }
+    if (buffer != null) {
+      void write(AnalysisError originalError) {
+        buffer.write('a ');
+        buffer.write(originalError.errorCode.uniqueName);
+        buffer.write(' in ');
+        buffer.write(originalError.source.fullName);
+        buffer.write(' at ');
+        buffer.write(originalError.offset);
+      }
+
+      buffer.write('Expected ');
+      write(expected);
+      buffer.write('; found ');
+      write(actual);
+    }
+    return false;
+  }
+
+  bool _compareAstNodes(AstNode expected, AstNode actual, StringBuffer buffer) {
+    if (AstComparator.equalNodes(actual, expected)) {
+      return true;
+    }
+    if (buffer != null) {
+      // TODO(brianwilkerson) Compute where the difference is rather than just
+      // whether there is a difference.
+      buffer.write('Different AST nodes');
+    }
+    return false;
+  }
+
+  bool _compareConstantEvaluationTargets(ConstantEvaluationTarget expected,
+      ConstantEvaluationTarget actual, StringBuffer buffer) {
+    if (actual is ConstantEvaluationTarget_Annotation) {
+      ConstantEvaluationTarget_Annotation expectedAnnotation = expected;
+      ConstantEvaluationTarget_Annotation actualAnnotation = actual;
+      if (actualAnnotation.source == expectedAnnotation.source &&
+          actualAnnotation.librarySource == expectedAnnotation.librarySource &&
+          actualAnnotation.annotation == expectedAnnotation.annotation) {
+        return true;
+      }
+      if (buffer != null) {
+        void write(ConstantEvaluationTarget_Annotation target) {
+          Annotation annotation = target.annotation;
+          buffer.write(annotation);
+          buffer.write(' at ');
+          buffer.write(annotation.offset);
+          buffer.write(' in ');
+          buffer.write(target.source);
+          buffer.write(' in ');
+          buffer.write(target.librarySource);
+        }
+
+        buffer.write('Expected ');
+        write(expectedAnnotation);
+        buffer.write('; found ');
+        write(actualAnnotation);
+      }
+      return false;
+    }
+    if (buffer != null) {
+      buffer.write('Unknown class of ConstantEvaluationTarget: ');
+      buffer.write(actual.runtimeType);
+    }
+    return false;
+  }
+
+  bool _compareDartScripts(
+      DartScript expected, DartScript actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareDocuments(
+      html.Document expected, html.Document actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareElements(Element expected, Element actual, StringBuffer buffer) {
+    ElementComparator comparator = new ElementComparator();
+    comparator.compareElements(expected, actual);
+    if (comparator.hasDifference) {
+      if (buffer != null) {
+        buffer.write(comparator.description);
+      }
+      return false;
+    }
+    return true;
+  }
+
+  bool _compareLibrarySpecificUnits(LibrarySpecificUnit expected,
+      LibrarySpecificUnit actual, StringBuffer buffer) {
+    if (actual.library.fullName == expected.library.fullName &&
+        actual.unit.fullName == expected.unit.fullName) {
+      return true;
+    }
+    if (buffer != null) {
+      buffer.write('Expected ');
+      buffer.write(expected);
+      buffer.write('; found ');
+      buffer.write(actual);
+    }
+    return false;
+  }
+
+  bool _compareLineInfos(
+      LineInfo expected, LineInfo actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareLists(List expected, List actual, StringBuffer buffer) {
+    int expectedLength = expected.length;
+    int actualLength = actual.length;
+    int left = 0;
+    while (left < expectedLength &&
+        left < actualLength &&
+        _compareObjects(expected[left], actual[left], null)) {
+      left++;
+    }
+    if (left == actualLength) {
+      if (left == expectedLength) {
+        // The lists are the same length and the elements are equal.
+        return true;
+      }
+      if (buffer != null) {
+        buffer.write('Expected a list of length ');
+        buffer.write(expectedLength);
+        buffer.write('; found a list of length ');
+        buffer.write(actualLength);
+        buffer.write(' that was a prefix of the expected list');
+      }
+      return false;
+    } else if (left == expectedLength) {
+      if (buffer != null) {
+        buffer.write('Expected a list of length ');
+        buffer.write(expectedLength);
+        buffer.write('; found a list of length ');
+        buffer.write(actualLength);
+        buffer.write(' that was an extension of the expected list');
+      }
+      return false;
+    }
+    int expectedRight = expectedLength - 1;
+    int actualRight = actualLength - 1;
+    while (expectedRight > left &&
+        actualRight > left &&
+        _compareObjects(expected[expectedRight], actual[actualRight], null)) {
+      actualRight--;
+      expectedRight--;
+    }
+    if (buffer != null) {
+      void write(int left, int right, int length) {
+        buffer.write('the elements (');
+        buffer.write(left);
+        buffer.write('..');
+        buffer.write(right);
+        buffer.write(') in a list of length ');
+        buffer.write(length);
+      }
+
+      buffer.write('Expected ');
+      write(left, expectedRight, expectedLength);
+      buffer.write(' to match ');
+      write(left, actualRight, actualLength);
+      buffer.write(' but they did not');
+    }
+    return false;
+  }
+
+  /**
+   * Return `true` if the [expected] and [actual] objects are equal. If they are
+   * not equal, and the given [buffer] is not `null`, then a description of the
+   * difference will be written to the [buffer].
+   */
+  bool _compareObjects(Object expected, Object actual, StringBuffer buffer) {
+    //
+    // Compare possible null values.
+    //
+    if (actual == null) {
+      if (expected == null) {
+        return true;
+      } else {
+        if (buffer != null) {
+          buffer.write('Expected an instance of ');
+          buffer.write(expected.runtimeType);
+          buffer.write('; found null');
+        }
+        return false;
+      }
+    }
+    Type actualType = actual.runtimeType;
+    if (expected == null) {
+      if (buffer != null) {
+        buffer.write('Expected null; found an instance of ');
+        buffer.write(actualType);
+      }
+      return false;
+    }
+    Type expectedType = expected.runtimeType;
+    //
+    // Compare the types.
+    //
+    if (expectedType != actualType) {
+      if (buffer != null) {
+        buffer.write('Expected an instance of ');
+        buffer.write(expectedType);
+        buffer.write('; found an instance of ');
+        buffer.write(actualType);
+      }
+      return false;
+    }
+    //
+    // Compare non-null values of the same type.
+    //
+    if (actual is bool) {
+      return _comparePrimitives(expected, actual, buffer);
+    } else if (actual is int) {
+      return _comparePrimitives(expected, actual, buffer);
+    } else if (actual is String) {
+      return _compareStrings(expected, actual, buffer);
+    } else if (actual is List) {
+      return _compareLists(expected, actual, buffer);
+    } else if (actual is AnalysisError) {
+      return _compareAnalysisErrors(expected, actual, buffer);
+    } else if (actual is AstNode) {
+      return _compareAstNodes(expected, actual, buffer);
+    } else if (actual is DartScript) {
+      return _compareDartScripts(expected, actual, buffer);
+    } else if (actual is html.Document) {
+      return _compareDocuments(expected, actual, buffer);
+    } else if (actual is Element) {
+      return _compareElements(expected, actual, buffer);
+    } else if (actual is LibrarySpecificUnit) {
+      return _compareLibrarySpecificUnits(expected, actual, buffer);
+    } else if (actual is LineInfo) {
+      return _compareLineInfos(expected, actual, buffer);
+    } else if (actual is ReferencedNames) {
+      return _compareReferencedNames(expected, actual, buffer);
+    } else if (actual is Source) {
+      return _compareSources(expected, actual, buffer);
+    } else if (actual is SourceKind) {
+      return _comparePrimitives(expected, actual, buffer);
+    } else if (actual is Token) {
+      return _compareTokenStreams(expected, actual, buffer);
+    } else if (actual is TypeProvider) {
+      return true;
+    } else if (actual is UsedLocalElements) {
+      return _compareUsedLocalElements(expected, actual, buffer);
+    } else if (actual is UsedImportedElements) {
+      return _compareUsedImportedElements(expected, actual, buffer);
+    } else if (actual is ConstantEvaluationTarget) {
+      return _compareConstantEvaluationTargets(expected, actual, buffer);
+    }
+    if (buffer != null) {
+      buffer.write('Cannot compare values of type ');
+      buffer.write(actualType);
+    }
+    return false;
+  }
+
+  bool _comparePrimitives(Object expected, Object actual, StringBuffer buffer) {
+    if (actual == expected) {
+      return true;
+    }
+    if (buffer != null) {
+      buffer.write('Expected ');
+      buffer.write(expected);
+      buffer.write('; found ');
+      buffer.write(actual);
+    }
+    return false;
+  }
+
+  bool _compareReferencedNames(
+      ReferencedNames expected, ReferencedNames actual, StringBuffer buffer) {
+    Set<String> expectedNames = expected.names;
+    Map<String, Set<String>> expectedUserToDependsOn = expected.userToDependsOn;
+    Set<String> expectedKeys = expectedUserToDependsOn.keys.toSet();
+
+    Set<String> actualNames = actual.names;
+    Map<String, Set<String>> actualUserToDependsOn = actual.userToDependsOn;
+    Set<String> actualKeys = actualUserToDependsOn.keys.toSet();
+
+    Set<String> missingNames = expectedNames.difference(actualNames);
+    Set<String> extraNames = actualNames.difference(expectedNames);
+    Set<String> missingKeys = expectedKeys.difference(actualKeys);
+    Set<String> extraKeys = actualKeys.difference(expectedKeys);
+    Map<String, List<Set<String>>> mismatchedDependencies =
+        new HashMap<String, List<Set<String>>>();
+    Set<String> commonKeys = expectedKeys.intersection(actualKeys);
+    for (String key in commonKeys) {
+      Set<String> expectedDependencies = expectedUserToDependsOn[key];
+      Set<String> actualDependencies = actualUserToDependsOn[key];
+      Set<String> missingDependencies =
+          expectedDependencies.difference(actualDependencies);
+      Set<String> extraDependencies =
+          actualDependencies.difference(expectedDependencies);
+      if (missingDependencies.isNotEmpty || extraDependencies.isNotEmpty) {
+        mismatchedDependencies[key] = [missingDependencies, extraDependencies];
+      }
+    }
+
+    if (missingNames.isEmpty &&
+        extraNames.isEmpty &&
+        missingKeys.isEmpty &&
+        extraKeys.isEmpty &&
+        mismatchedDependencies.isEmpty) {
+      return true;
+    }
+    if (buffer != null) {
+      void write(String title, Set<String> names) {
+        buffer.write(names.length);
+        buffer.write(' ');
+        buffer.write(title);
+        buffer.write(': {');
+        bool first = true;
+        for (String name in names) {
+          if (first) {
+            first = false;
+          } else {
+            buffer.write(', ');
+          }
+          buffer.write(name);
+        }
+        buffer.write('}');
+      }
+      bool needsNewline = false;
+      if (missingNames.isNotEmpty) {
+        buffer.write('Has ');
+        write('missing names', missingNames);
+        needsNewline = true;
+      }
+      if (extraNames.isNotEmpty) {
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('Has ');
+        write('extra names', extraNames);
+        needsNewline = true;
+      }
+      if (missingKeys.isNotEmpty) {
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('Has ');
+        write('missing keys', missingKeys);
+        needsNewline = true;
+      }
+      if (extraKeys.isNotEmpty) {
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('Has ');
+        write('extra keys', extraKeys);
+        needsNewline = true;
+      }
+      mismatchedDependencies.forEach((String key, List<Set<String>> value) {
+        Set<String> missingDependencies = value[0];
+        Set<String> extraDependencies = value[1];
+        if (needsNewline) {
+          buffer.write('</p><p>');
+        }
+        buffer.write('The key ');
+        buffer.write(key);
+        buffer.write(' has ');
+        bool needsConjunction = false;
+        if (missingNames.isNotEmpty) {
+          write('missing dependencies', missingDependencies);
+          needsConjunction = true;
+        }
+        if (extraNames.isNotEmpty) {
+          if (needsConjunction) {
+            buffer.write(' and ');
+          }
+          write('extra dependencies', extraDependencies);
+        }
+        needsNewline = true;
+      });
+    }
+    return true;
+  }
+
+  bool _compareSources(Source expected, Source actual, StringBuffer buffer) {
+    if (actual.fullName == expected.fullName) {
+      return true;
+    }
+    if (buffer != null) {
+      buffer.write('Expected a source for ');
+      buffer.write(expected.fullName);
+      buffer.write('; found a source for ');
+      buffer.write(actual.fullName);
+    }
+    return false;
+  }
+
+  bool _compareStrings(String expected, String actual, StringBuffer buffer) {
+    if (actual == expected) {
+      return true;
+    }
+    int expectedLength = expected.length;
+    int actualLength = actual.length;
+    int left = 0;
+    while (left < actualLength &&
+        left < expectedLength &&
+        actual.codeUnitAt(left) == expected.codeUnitAt(left)) {
+      left++;
+    }
+    if (left == actualLength) {
+      if (buffer != null) {
+        buffer.write('Expected ...[');
+        buffer.write(expected.substring(left));
+        buffer.write(']; found ...[]');
+      }
+      return false;
+    } else if (left == expectedLength) {
+      if (buffer != null) {
+        buffer.write('Expected ...[]; found ...[');
+        buffer.write(actual.substring(left));
+        buffer.write(']');
+      }
+      return false;
+    }
+    int actualRight = actualLength - 1;
+    int expectedRight = expectedLength - 1;
+    while (actualRight > left &&
+        expectedRight > left &&
+        actual.codeUnitAt(actualRight) == expected.codeUnitAt(expectedRight)) {
+      actualRight--;
+      expectedRight--;
+    }
+    if (buffer != null) {
+      void write(String string, int left, int right) {
+        buffer.write('...[');
+        buffer.write(string.substring(left, right));
+        buffer.write(']... (');
+        buffer.write(left);
+        buffer.write('..');
+        buffer.write(right);
+        buffer.write(')');
+      }
+
+      buffer.write('Expected ');
+      write(expected, left, expectedRight);
+      buffer.write('; found ');
+      write(actual, left, actualRight);
+    }
+    return false;
+  }
+
+  bool _compareTokenStreams(Token expected, Token actual, StringBuffer buffer) {
+    bool equals(Token originalToken, Token cloneToken) {
+      return originalToken.type == cloneToken.type &&
+          originalToken.offset == cloneToken.offset &&
+          originalToken.lexeme == cloneToken.lexeme;
+    }
+
+    Token actualLeft = actual;
+    Token expectedLeft = expected;
+    while (actualLeft.type != TokenType.EOF &&
+        expectedLeft.type != TokenType.EOF &&
+        equals(actualLeft, expectedLeft)) {
+      actualLeft = actualLeft.next;
+      expectedLeft = expectedLeft.next;
+    }
+    if (actualLeft.type == TokenType.EOF &&
+        expectedLeft.type == TokenType.EOF) {
+      return true;
+    }
+    if (buffer != null) {
+      void write(Token token) {
+        buffer.write(token.type);
+        buffer.write(' at ');
+        buffer.write(token.offset);
+        buffer.write(' (');
+        buffer.write(token.lexeme);
+        buffer.write(')');
+      }
+
+      buffer.write('Expected ');
+      write(expectedLeft);
+      buffer.write('; found ');
+      write(actualLeft);
+    }
+    return false;
+  }
+
+  bool _compareUsedImportedElements(UsedImportedElements expected,
+      UsedImportedElements actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  bool _compareUsedLocalElements(UsedLocalElements expected,
+      UsedLocalElements actual, StringBuffer buffer) {
+    // TODO(brianwilkerson) Implement this.
+    return true;
+  }
+
+  /**
+   * Determine whether or not there is any interesting difference between the
+   * original and cloned values.
+   */
+  void _performComparison() {
+    StringBuffer buffer = new StringBuffer();
+    if (!_compareObjects(cloneValue, originalValue, buffer)) {
+      description = buffer.toString();
+    }
+  }
+}
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 8049890..d96edc0 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -75,6 +75,10 @@
     }
   }
 
+  void processRequiredPlugins() {
+    AnalysisEngine.instance.processRequiredPlugins();
+  }
+
   CompilationUnit resolveDartUnit(Source unitSource, Source librarySource) {
     return context.resolveCompilationUnit2(unitSource, librarySource);
   }
@@ -84,6 +88,7 @@
   }
 
   void setUp() {
+    processRequiredPlugins();
     setupResourceProvider();
     resourceResolver = new ResourceUriResolver(provider);
     packageMap = new Map<String, List<Folder>>();
@@ -121,28 +126,12 @@
   }
 
   @override
-  void logError2(String message, Object exception) {
-    print(message);
-    if (exception != null) {
-      print(exception);
-    }
-  }
-
-  @override
   void logInformation(String message, [CaughtException exception]) {
     print(message);
     if (exception != null) {
       print(exception);
     }
   }
-
-  @override
-  void logInformation2(String message, Object exception) {
-    print(message);
-    if (exception != null) {
-      print(exception);
-    }
-  }
 }
 
 /**
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index 966559b..a24b811 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -23,9 +23,6 @@
 
 @reflectiveTest
 class AnalysisOptionsFileNotificationTest extends AbstractAnalysisTest {
-  /// Cached model state in case tests need to set task model to on/off.
-  bool wasTaskModelEnabled;
-
   Map<String, List<AnalysisError>> filesErrors = {};
 
   final testSource = '''
@@ -78,13 +75,10 @@
   void setUp() {
     super.setUp();
     server.handlers = [new AnalysisDomainHandler(server)];
-    wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
-    AnalysisEngine.instance.useTaskModel = true;
   }
 
   @override
   void tearDown() {
-    AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
     filesErrors[optionsFilePath] = [];
     filesErrors[testFile] = [];
     super.tearDown();
@@ -108,10 +102,10 @@
     await waitForTasksFinished();
 
     // Verify options file.
-    expect(optionsFileErrors, hasLength(0));
+    expect(optionsFileErrors, isEmpty);
 
     // Verify test file.
-    expect(testFileErrors, hasLength(0));
+    expect(testFileErrors, isEmpty);
   }
 
   test_error_filter_removed() async {
@@ -132,10 +126,10 @@
     await waitForTasksFinished();
 
     // Verify options file.
-    expect(optionsFileErrors, hasLength(0));
+    expect(optionsFileErrors, isEmpty);
 
     // Verify test file.
-    expect(testFileErrors, hasLength(0));
+    expect(testFileErrors, isEmpty);
 
     addOptionsFile('''
 analyzer:
@@ -147,7 +141,7 @@
     await waitForTasksFinished();
 
     // Verify options file.
-    expect(optionsFileErrors, hasLength(0));
+    expect(optionsFileErrors, isEmpty);
 
     // Verify test file.
     expect(testFileErrors, hasLength(1));
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index dbbe7af..02b05ec 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -25,9 +25,6 @@
 class NotificationErrorsTest extends AbstractAnalysisTest {
   Map<String, List<AnalysisError>> filesErrors = {};
 
-  /// Cached model state in case tests need to set task model to on/off.
-  bool wasTaskModelEnabled;
-
   void processNotification(Notification notification) {
     if (notification.event == ANALYSIS_ERRORS) {
       var decoded = new AnalysisErrorsParams.fromNotification(notification);
@@ -39,13 +36,6 @@
   void setUp() {
     super.setUp();
     server.handlers = [new AnalysisDomainHandler(server),];
-    wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
-  }
-
-  @override
-  void tearDown() {
-    AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
-    super.tearDown();
   }
 
   test_importError() async {
@@ -66,9 +56,6 @@
   }
 
   test_lintError() async {
-    // Requires task model.
-    AnalysisEngine.instance.useTaskModel = true;
-
     var camelCaseTypesLintName = 'camel_case_types';
 
     addFile(
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index 6fbc5d8..3e09632 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -107,11 +107,7 @@
     server.updateContent('2', {testFile: new RemoveContentOverlay()});
     // Validate that at the end the unit was indexed.
     await server.onAnalysisComplete;
-    if (AnalysisEngine.instance.useTaskModel) {
-      verify(server.index.index(anyObject, testUnitMatcher)).times(3);
-    } else {
-      verify(server.index.index(anyObject, testUnitMatcher)).times(2);
-    }
+    verify(server.index.index(anyObject, testUnitMatcher)).times(3);
   }
 
   test_multiple_contexts() async {
@@ -136,8 +132,9 @@
 library baz;
 f(int i) {}
 ''');
-    Request request = new AnalysisSetAnalysisRootsParams(
-        ['/project1', '/project2'], []).toRequest('0');
+    Request request =
+        new AnalysisSetAnalysisRootsParams(['/project1', '/project2'], [])
+            .toRequest('0');
     handleSuccessfulRequest(request);
     {
       await server.onAnalysisComplete;
@@ -166,8 +163,9 @@
     String filePath = '/User/project1/test.dart';
     Folder folder1 = resourceProvider.newFolder('/User/project1');
     Folder folder2 = resourceProvider.newFolder('/User/project2');
-    Request request = new AnalysisSetAnalysisRootsParams(
-        [folder1.path, folder2.path], []).toRequest('0');
+    Request request =
+        new AnalysisSetAnalysisRootsParams([folder1.path, folder2.path], [])
+            .toRequest('0');
     handleSuccessfulRequest(request);
     // exactly 2 contexts
     expect(server.folderMap, hasLength(2));
@@ -274,6 +272,4 @@
   }
 }
 
-class _MockIndex extends TypedMock implements Index {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockIndex extends TypedMock implements Index {}
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index de27610..5c0616e 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -97,22 +97,27 @@
   }
 
   AnalysisServer createAnalysisServer(Index index) {
+    //
+    // Collect plugins
+    //
     ServerPlugin serverPlugin = new ServerPlugin();
-    // TODO(pq): this convoluted extension registry dance needs cleanup.
-    List<Plugin> plugins = <Plugin>[
-      serverPlugin,
-      linterPlugin,
-      linterServerPlugin,
-      dartCompletionPlugin,
-    ];
-    // Accessing `taskManager` ensures that AE plugins are registered.
-    AnalysisEngine.instance.taskManager;
-    plugins.addAll(AnalysisEngine.instance.supportedPlugins);
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(serverPlugin);
+    plugins.add(dartCompletionPlugin);
+    plugins.add(linterPlugin);
+    plugins.add(linterServerPlugin);
     addServerPlugins(plugins);
-    // process plugins
+    //
+    // Process plugins
+    //
     ExtensionManager manager = new ExtensionManager();
     manager.processPlugins(plugins);
-    // create server
+    //
+    // Create server
+    //
     return new AnalysisServer(
         serverChannel,
         resourceProvider,
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 58179eb..e9a1663 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
@@ -119,23 +120,31 @@
     });
   }
 
+  void processRequiredPlugins() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(server.serverPlugin);
+
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+  }
+
   void setUp() {
     channel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
     packageMapProvider = new MockPackageMapProvider();
-    ExtensionManager manager = new ExtensionManager();
-    ServerPlugin serverPlugin = new ServerPlugin();
-    manager.processPlugins([serverPlugin]);
     server = new AnalysisServer(
         channel,
         resourceProvider,
         packageMapProvider,
         null,
-        serverPlugin,
+        new ServerPlugin(),
         new AnalysisServerOptions(),
         new MockSdk(),
         InstrumentationService.NULL_SERVICE,
         rethrowExceptions: true);
+    processRequiredPlugins();
   }
 
   Future test_contextDisposed() {
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 0d5ea53..86defe8 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -1895,8 +1895,7 @@
 main() {
   B.!1;
 }''',
-        <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"],
-        failingTests: '1');
+        <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"]);
 
     buildTests(
         'testCompletion_propertyAccess_whenInstanceTarget',
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 9f51368..082f28d 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -11,12 +11,18 @@
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/embedder.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/services/lint.dart';
+import 'package:linter/src/plugin/linter_plugin.dart';
+import 'package:linter/src/rules/avoid_as.dart';
 import 'package:package_config/packages.dart';
 import 'package:path/path.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -67,6 +73,37 @@
 
   String projPath = '/my/proj';
 
+  AnalysisError missing_return =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+    ['x']
+  ]);
+
+  AnalysisError invalid_assignment_error =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+    ['x'],
+    ['y']
+  ]);
+
+  AnalysisError unused_local_variable = new AnalysisError(
+      new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+    ['x']
+  ]);
+
+  List<ErrorProcessor> get errorProcessors => callbacks.currentContext
+      .getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+
+  List<Linter> get lints => getLints(callbacks.currentContext);
+
+  AnalysisOptions get options => callbacks.currentContext.analysisOptions;
+
+  void deleteFile(List<String> pathComponents) {
+    String filePath = posix.joinAll(pathComponents);
+    resourceProvider.deleteFile(filePath);
+  }
+
+  ErrorProcessor getProcessor(AnalysisError error) =>
+      ErrorProcessor.getProcessor(callbacks.currentContext, error);
+
   String newFile(List<String> pathComponents, [String content = '']) {
     String filePath = posix.joinAll(pathComponents);
     resourceProvider.newFile(filePath, content);
@@ -79,11 +116,22 @@
     return folderPath;
   }
 
+  void processRequiredPlugins() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(linterPlugin);
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+  }
+
   UriResolver providePackageResolver(Folder folder) {
     return packageResolver;
   }
 
   void setUp() {
+    processRequiredPlugins();
     resourceProvider = new MemoryResourceProvider();
     packageMapProvider = new MockPackageMapProvider();
     manager = new ContextManagerImpl(resourceProvider, providePackageResolver,
@@ -93,6 +141,99 @@
     resourceProvider.newFolder(projPath);
   }
 
+  test_analysis_options_file_delete() async {
+    // Setup .analysis_options
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+embedder_libs:
+  "dart:foobar": "../sdk_ext/entry.dart"
+analyzer:
+  language:
+    enableGenericMethods: true
+  errors:
+    unused_local_variable: false
+linter:
+  rules:
+    - camel_case_types
+''');
+
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+
+    // Verify options were set.
+    expect(errorProcessors, hasLength(1));
+    expect(lints, hasLength(1));
+    expect(options.enableGenericMethods, isTrue);
+
+    // Remove options.
+    deleteFile([projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE]);
+    await pumpEventQueue();
+
+    // Verify defaults restored.
+    expect(errorProcessors, isEmpty);
+    expect(lints, isEmpty);
+    expect(options.enableGenericMethods, isFalse);
+  }
+
+  test_analysis_options_file_delete_with_embedder() async {
+    // Setup _embedder.yaml.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    newFile(
+        [libPath, '_embedder.yaml'],
+        r'''
+analyzer:
+  strong-mode: true
+  errors:
+    missing_return: false
+linter:
+  rules:
+    - avoid_as
+''');
+
+    // Setup .packages file
+    newFile(
+        [projPath, '.packages'],
+        r'''
+test_pack:lib/''');
+
+    // Setup .analysis_options
+    newFile(
+        [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
+        r'''
+analyzer:
+  language:
+    enableGenericMethods: true
+  errors:
+    unused_local_variable: false
+linter:
+  rules:
+    - camel_case_types
+''');
+
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    await pumpEventQueue();
+
+    // Verify options were set.
+    expect(options.enableGenericMethods, isTrue);
+    expect(options.strongMode, isTrue);
+    expect(errorProcessors, hasLength(2));
+    expect(lints, hasLength(2));
+
+    // Remove options.
+    deleteFile([projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE]);
+    await pumpEventQueue();
+
+    // Verify defaults restored.
+    expect(options.enableGenericMethods, isFalse);
+    expect(lints, hasLength(1));
+    expect(lints.first, new isInstanceOf<AvoidAs>());
+    expect(errorProcessors, hasLength(1));
+    expect(getProcessor(missing_return).severity, isNull);
+  }
+
   test_analysis_options_parse_failure() async {
     // Create files.
     String libPath = newFolder([projPath, LIB_NAME]);
@@ -154,6 +295,11 @@
   strong-mode: true
   language:
     enableSuperMixins: true
+  errors:
+    missing_return: false
+linter:
+  rules:
+    - avoid_as
 ''');
     // Setup .packages file
     newFile(
@@ -172,6 +318,9 @@
     enableGenericMethods: true
   errors:
     unused_local_variable: false
+linter:
+  rules:
+    - camel_case_types
 ''');
 
     // Setup context.
@@ -186,25 +335,31 @@
     var context = contexts[0];
 
     // Verify options.
-    //   * from `_embedder.yaml`:
+    // * from `_embedder.yaml`:
     expect(context.analysisOptions.strongMode, isTrue);
     expect(context.analysisOptions.enableSuperMixins, isTrue);
-    //   * from `.analysis_options`:
+    // * from `.analysis_options`:
     expect(context.analysisOptions.enableGenericMethods, isTrue);
-    //     verify tests are excluded
+    // * verify tests are excluded
     expect(callbacks.currentContextFilePaths[projPath].keys,
         ['/my/proj/sdk_ext/entry.dart']);
 
     // Verify filter setup.
-    List<ErrorFilter> filters =
-        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-    expect(filters, hasLength(1));
+    expect(errorProcessors, hasLength(2));
+
+    // * (embedder.)
+    expect(getProcessor(missing_return).severity, isNull);
+
+    // * (options.)
+    expect(getProcessor(unused_local_variable).severity, isNull);
+
+    // Verify lints.
+    var lintNames = lints.map((lint) => lint.name);
+
     expect(
-        filters.first(new AnalysisError(
-            new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
-          ['x']
-        ])),
-        isTrue);
+        lintNames,
+        unorderedEquals(
+            ['avoid_as' /* embedder */, 'camel_case_types' /* options */]));
 
     // Sanity check embedder libs.
     var source = context.sourceFactory.forUri('dart:foobar');
@@ -268,16 +423,8 @@
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
     // Verify filter setup.
-    List<ErrorFilter> filters =
-        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-    expect(filters, isNotNull);
-    expect(filters, hasLength(1));
-    expect(
-        filters.first(new AnalysisError(
-            new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
-          ['x']
-        ])),
-        isTrue);
+    expect(errorProcessors, hasLength(1));
+    expect(getProcessor(unused_local_variable).severity, isNull);
   }
 
   test_error_filter_analysis_option_multiple_filters() async {
@@ -288,30 +435,16 @@
 analyzer:
   errors:
     invalid_assignment: ignore
-    unused_local_variable: ignore
+    unused_local_variable: error
 ''');
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
     // Verify filter setup.
-    List<ErrorFilter> filters =
-        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-    expect(filters, isNotNull);
-    expect(filters, hasLength(2));
+    expect(errorProcessors, hasLength(2));
 
-    var unused_error = new AnalysisError(
-        new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
-      ['x']
-    ]);
-
-    var invalid_assignment_error =
-        new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
-      ['x'],
-      ['y']
-    ]);
-
-    expect(filters.any((filter) => filter(unused_error)), isTrue);
-    expect(filters.any((filter) => filter(invalid_assignment_error)), isTrue);
+    expect(getProcessor(invalid_assignment_error).severity, isNull);
+    expect(getProcessor(unused_local_variable).severity, ErrorSeverity.ERROR);
   }
 
   test_error_filter_analysis_option_synonyms() async {
@@ -328,10 +461,8 @@
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
     // Verify filter setup.
-    List<ErrorFilter> filters =
-        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-    expect(filters, isNotNull);
-    expect(filters, hasLength(2));
+    expect(errorProcessors, isNotNull);
+    expect(errorProcessors, hasLength(2));
   }
 
   test_error_filter_analysis_option_unpsecified() async {
@@ -347,9 +478,7 @@
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
     // Verify filter setup.
-    List<ErrorFilter> filters =
-        callbacks.currentContext.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-    expect(filters, isEmpty);
+    expect(errorProcessors, isEmpty);
   }
 
   test_ignoreFilesInPackagesFolder() {
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 2c6fc7b..b7f4b34 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -119,6 +119,22 @@
             expect(serverRef.getResolvedCompilationUnits(fileB), isEmpty);
           });
         });
+
+        test('not absolute', () async {
+          var response = testSetAnalysisRoots([], ['foo/bar']);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
+
+        test('not normalized', () async {
+          var response = testSetAnalysisRoots([], ['/foo/../bar']);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
       });
 
       group('included', () {
@@ -147,6 +163,22 @@
           await server.onAnalysisComplete;
           expect(serverRef.getResolvedCompilationUnits(fileB), hasLength(1));
         });
+
+        test('not absolute', () async {
+          var response = testSetAnalysisRoots(['foo/bar'], []);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
+
+        test('not normalized', () async {
+          var response = testSetAnalysisRoots(['/foo/../bar'], []);
+          expect(
+              response,
+              isResponseFailure(
+                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+        });
       });
     });
 
@@ -167,8 +199,9 @@
         resourceProvider.newFile('/p2/b.dart', 'library b;');
         resourceProvider.newFile('/p2/c.dart', 'library c;');
 
-        var setRootsRequest = new AnalysisSetAnalysisRootsParams(
-            ['/p1', '/p2'], []).toRequest('0');
+        var setRootsRequest =
+            new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], [])
+                .toRequest('0');
         var setRootsResponse = handler.handleRequest(setRootsRequest);
         expect(setRootsResponse, isResponseSuccess('0'));
 
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 888b7cc..619136b 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -29,6 +29,7 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -52,13 +53,23 @@
   int requestCount = 0;
   String testFile2 = '/project/bin/test2.dart';
 
-  /// Cached model state in case tests need to set task model to on/off.
-  bool wasTaskModelEnabled;
-
   AnalysisServer createAnalysisServer(Index index) {
-    ExtensionManager manager = new ExtensionManager();
+    //
+    // Collect plugins
+    //
     ServerPlugin serverPlugin = new ServerPlugin();
-    manager.processPlugins([serverPlugin]);
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(serverPlugin);
+    addServerPlugins(plugins);
+    //
+    // Process plugins
+    //
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+    //
+    // Create the server
+    //
     return new Test_AnalysisServer(
         super.serverChannel,
         super.resourceProvider,
@@ -85,8 +96,6 @@
   @override
   void setUp() {
     super.setUp();
-    wasTaskModelEnabled = AnalysisEngine.instance.useTaskModel;
-    AnalysisEngine.instance.useTaskModel = true;
     createProject();
     analysisDomain = handler;
     completionDomain = new Test_CompletionDomainHandler(server);
@@ -99,7 +108,6 @@
     super.tearDown();
     analysisDomain = null;
     completionDomain = null;
-    AnalysisEngine.instance.useTaskModel = wasTaskModelEnabled;
   }
 
   /**
@@ -464,12 +472,25 @@
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
       assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'foo');
+      assertHasResult(CompletionSuggestionKind.IDENTIFIER, 'foo');
       assertNoResult('HtmlElement');
       assertNoResult('test');
     });
   }
 
+  test_imports_prefixed2() {
+    addTestFile('''
+      import 'dart:html' as foo;
+      main() {foo.^}
+    ''');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'HtmlElement');
+      assertNoResult('test');
+    });
+  }
+
   test_invocation() {
     addTestFile('class A {b() {}} main() {A a; a.^}');
     return getSuggestions().then((_) {
@@ -632,6 +653,16 @@
     });
   }
 
+  test_static() {
+    addTestFile('class A {static b() {} c() {}} main() {A.^}');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'b');
+      assertNoResult('c');
+    });
+  }
+
   test_topLevel() {
     addTestFile('''
       typedef foo();
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 444e6cf..f234463 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -10,7 +10,9 @@
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:unittest/unittest.dart';
 
 import 'mock_sdk.dart';
@@ -25,11 +27,25 @@
   initializeTestEnvironment();
 
   setUp(() {
+    //
+    // Collect plugins
+    //
+    ServerPlugin serverPlugin = new ServerPlugin();
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    plugins.add(serverPlugin);
+    //
+    // Process plugins
+    //
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+    //
+    // Create the server
+    //
     var serverChannel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
-    ExtensionManager manager = new ExtensionManager();
-    ServerPlugin serverPlugin = new ServerPlugin();
-    manager.processPlugins([serverPlugin]);
     server = new AnalysisServer(
         serverChannel,
         resourceProvider,
@@ -42,10 +58,6 @@
     handler = new DiagnosticDomainHandler(server);
   });
 
-  tearDown(() {
-    handler.sampler?.stop();
-  });
-
   group('DiagnosticDomainHandler', () {
     test('getDiagnostics', () async {
       String file = '/project/bin/test.dart';
@@ -68,7 +80,6 @@
       expect(context['explicitFileCount'], fileCount);
       expect(context['implicitFileCount'], 0);
       expect(context['workItemQueueLength'], isNotNull);
-      expect(context['workItemQueueLengthAverage'], isNotNull);
     });
 
     test('getDiagnostics - (no root)', () async {
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index 8bae43f..a955360 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -34,8 +34,7 @@
     handler = new EditDomainHandler(server);
   }
 
-  Future test_BAD_doesNotExist() async {
-    await waitForTasksFinished();
+  test_BAD_doesNotExist() async {
     Request request =
         new EditSortMembersParams('/no/such/file.dart').toRequest('0');
     Response response = handler.handleRequest(request);
@@ -43,21 +42,19 @@
         isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
   }
 
-  Future test_BAD_hasParseError() async {
+  test_BAD_hasParseError() async {
     addTestFile('''
 main() {
   print()
 }
 ''');
-    await waitForTasksFinished();
     Request request = new EditSortMembersParams(testFile).toRequest('0');
     Response response = handler.handleRequest(request);
     expect(response,
         isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS));
   }
 
-  Future test_BAD_notDartFile() async {
-    await waitForTasksFinished();
+  test_BAD_notDartFile() async {
     Request request =
         new EditSortMembersParams('/not-a-Dart-file.txt').toRequest('0');
     Response response = handler.handleRequest(request);
@@ -65,7 +62,21 @@
         isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
   }
 
-  Future test_OK_classMembers_method() {
+  test_OK_afterWaitForAnalysis() async {
+    addTestFile('''
+class C {}
+class A {}
+class B {}
+''');
+    await waitForTasksFinished();
+    return _assertSorted(r'''
+class A {}
+class B {}
+class C {}
+''');
+  }
+
+  test_OK_classMembers_method() async {
     addTestFile('''
 class A {
   c() {}
@@ -82,7 +93,7 @@
 ''');
   }
 
-  Future test_OK_directives() {
+  test_OK_directives() async {
     addTestFile('''
 library lib;
 
@@ -133,7 +144,7 @@
 ''');
   }
 
-  Future test_OK_unitMembers_class() {
+  test_OK_unitMembers_class() async {
     addTestFile('''
 class C {}
 class A {}
@@ -147,7 +158,6 @@
   }
 
   Future _assertSorted(String expectedCode) async {
-    await waitForTasksFinished();
     _requestSort();
     String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits);
     expect(resultCode, expectedCode);
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 5004f86..f4dcfeb 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -11,7 +11,6 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/server/driver.dart' as analysisServer;
 import 'package:path/path.dart';
 import 'package:unittest/unittest.dart';
 
@@ -597,7 +596,6 @@
       {bool debugServer: false,
       int diagnosticPort,
       bool profileServer: false,
-      bool newTaskModel: true,
       bool useAnalysisHighlight2: false}) {
     if (_process != null) {
       throw new Exception('Process already started');
@@ -627,9 +625,6 @@
     if (useAnalysisHighlight2) {
       arguments.add('--useAnalysisHighlight2');
     }
-    if (!newTaskModel) {
-      arguments.add('--${analysisServer.Driver.DISABLE_NEW_TASK_MODEL}');
-    }
 //    print('Launching $serverPath');
 //    print('$dartBinary ${arguments.join(' ')}');
     return Process.start(dartBinary, arguments).then((Process process) {
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 2a0cd06..6266cb9 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -1307,7 +1307,6 @@
  *   "explicitFileCount": int
  *   "implicitFileCount": int
  *   "workItemQueueLength": int
- *   "workItemQueueLengthAverage": String
  *   "cacheEntryExceptions": List<String>
  * }
  */
@@ -1317,7 +1316,6 @@
     "explicitFileCount": isInt,
     "implicitFileCount": isInt,
     "workItemQueueLength": isInt,
-    "workItemQueueLengthAverage": isString,
     "cacheEntryExceptions": isListOf(isString)
   }));
 
@@ -2104,6 +2102,7 @@
  *   GET_REACHABLE_SOURCES_INVALID_FILE
  *   INVALID_ANALYSIS_ROOT
  *   INVALID_EXECUTION_CONTEXT
+ *   INVALID_FILE_PATH_FORMAT
  *   INVALID_OVERLAY_CHANGE
  *   INVALID_PARAMETER
  *   INVALID_REQUEST
@@ -2130,6 +2129,7 @@
   "GET_REACHABLE_SOURCES_INVALID_FILE",
   "INVALID_ANALYSIS_ROOT",
   "INVALID_EXECUTION_CONTEXT",
+  "INVALID_FILE_PATH_FORMAT",
   "INVALID_OVERLAY_CHANGE",
   "INVALID_PARAMETER",
   "INVALID_REQUEST",
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 99be8fc..5aaec99 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -6,7 +6,7 @@
 
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -219,11 +219,7 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      if (AnalysisEngine.instance.useTaskModel) {
-        _analysisContext = new newContext.SdkAnalysisContext();
-      } else {
-        _analysisContext = new SdkAnalysisContext();
-      }
+      _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
       ChangeSet changeSet = new ChangeSet();
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 428f53b..efc19fd 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -72,23 +72,19 @@
 
 class MockAnalysisContext extends StringTypedMock implements AnalysisContext {
   MockAnalysisContext(String name) : super(name);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockClassElement extends TypedMock implements ClassElement {
   final ElementKind kind = ElementKind.CLASS;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockCompilationUnitElement extends TypedMock
     implements CompilationUnitElement {
   final ElementKind kind = ElementKind.COMPILATION_UNIT;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockConstructorElement extends TypedMock implements ConstructorElement {
   final kind = ElementKind.CONSTRUCTOR;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockElement extends StringTypedMock implements Element {
@@ -99,55 +95,39 @@
 
   @override
   String get name => _toString;
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockFieldElement extends TypedMock implements FieldElement {
   final ElementKind kind = ElementKind.FIELD;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockFunctionElement extends TypedMock implements FunctionElement {
   final ElementKind kind = ElementKind.FUNCTION;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockFunctionTypeAliasElement extends TypedMock
     implements FunctionTypeAliasElement {
   final ElementKind kind = ElementKind.FUNCTION_TYPE_ALIAS;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-class MockHtmlElement extends TypedMock implements HtmlElement {
-  final ElementKind kind = ElementKind.HTML;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockImportElement extends TypedMock implements ImportElement {
   final ElementKind kind = ElementKind.IMPORT;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockLibraryElement extends TypedMock implements LibraryElement {
   final ElementKind kind = ElementKind.LIBRARY;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockLocalVariableElement extends TypedMock
     implements LocalVariableElement {
   final ElementKind kind = ElementKind.LOCAL_VARIABLE;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class MockLogger extends TypedMock implements Logger {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLogger extends TypedMock implements Logger {}
 
 class MockMethodElement extends StringTypedMock implements MethodElement {
   final kind = ElementKind.METHOD;
   MockMethodElement([String name = 'method']) : super(name);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -192,14 +172,12 @@
 
 class MockParameterElement extends TypedMock implements ParameterElement {
   final ElementKind kind = ElementKind.PARAMETER;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockPropertyAccessorElement extends TypedMock
     implements PropertyAccessorElement {
   final ElementKind kind;
   MockPropertyAccessorElement(this.kind);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -255,7 +233,7 @@
     if (_closed) {
       throw new Exception('sendRequest after connection closed');
     }
-    // Wrap send request in future to simulate websocket
+    // Wrap send request in future to simulate WebSocket.
     new Future(() => requestController.add(request));
     return waitForResponse(request);
   }
@@ -267,7 +245,7 @@
       return;
     }
     responsesReceived.add(response);
-    // Wrap send response in future to simulate websocket
+    // Wrap send response in future to simulate WebSocket.
     new Future(() => responseController.add(response));
   }
 
@@ -342,19 +320,16 @@
 
 class MockSource extends StringTypedMock implements Source {
   MockSource([String name = 'mocked.dart']) : super(name);
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockTopLevelVariableElement extends TypedMock
     implements TopLevelVariableElement {
   final ElementKind kind = ElementKind.TOP_LEVEL_VARIABLE;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class MockTypeParameterElement extends TypedMock
     implements TypeParameterElement {
   final ElementKind kind = ElementKind.TYPE_PARAMETER;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class NoResponseException implements Exception {
diff --git a/pkg/analysis_server/test/operation/operation_queue_test.dart b/pkg/analysis_server/test/operation/operation_queue_test.dart
index ed7fbca..e6926c9 100644
--- a/pkg/analysis_server/test/operation/operation_queue_test.dart
+++ b/pkg/analysis_server/test/operation/operation_queue_test.dart
@@ -36,8 +36,6 @@
 
 class AnalysisContextMock extends TypedMock implements InternalAnalysisContext {
   List<Source> prioritySources = <Source>[];
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class AnalysisServerMock extends TypedMock implements AnalysisServer {
@@ -48,13 +46,9 @@
   final SearchEngine searchEngine;
 
   AnalysisServerMock({this.resourceProvider, this.searchEngine});
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class ServerContextManagerMock extends TypedMock implements ContextManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class ServerContextManagerMock extends TypedMock implements ContextManager {}
 
 @reflectiveTest
 class ServerOperationQueueTest {
@@ -230,21 +224,15 @@
   ServerOperationPriority get priority {
     return ServerOperationPriority.ANALYSIS_NOTIFICATION;
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 class _ServerOperationMock extends TypedMock implements ServerOperation {
   final AnalysisContext context;
 
   _ServerOperationMock([this.context]);
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class _SourceMock extends TypedMock implements Source {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _SourceMock extends TypedMock implements Source {}
 
 class _SourceSensitiveOperationMock extends TypedMock
     implements SourceSensitiveOperation {
@@ -257,8 +245,6 @@
     return ServerOperationPriority.ANALYSIS_NOTIFICATION;
   }
 
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
   @override
   bool shouldBeDiscardedOnSourceChange(Source source) {
     return source == this.source;
diff --git a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
index 592b8dd..a92c943 100644
--- a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
+++ b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
@@ -25,9 +25,7 @@
 
 main() {
   initializeTestEnvironment();
-  if (AnalysisEngine.instance.useTaskModel) {
-    defineReflectiveTests(SetAnalysisDomainTest);
-  }
+  defineReflectiveTests(SetAnalysisDomainTest);
 }
 
 /**
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index 5f503b6..a210a94 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -26,9 +26,7 @@
   defineReflectiveTests(EnumTest);
 }
 
-class AnalysisErrorMock extends TypedMock implements engine.AnalysisError {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class AnalysisErrorMock extends TypedMock implements engine.AnalysisError {}
 
 @reflectiveTest
 class AnalysisErrorTest {
diff --git a/pkg/analysis_server/test/services/completion/completion_test_util.dart b/pkg/analysis_server/test/services/completion/completion_test_util.dart
index 63180b7..7812fd8 100644
--- a/pkg/analysis_server/test/services/completion/completion_test_util.dart
+++ b/pkg/analysis_server/test/services/completion/completion_test_util.dart
@@ -16,7 +16,6 @@
 import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analysis_server/src/services/completion/imported_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
@@ -356,29 +355,6 @@
     return cs;
   }
 
-  CompletionSuggestion assertSuggestNamedConstructor(
-      String name, String returnType,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    if (contributor is PrefixedElementContributor) {
-      CompletionSuggestion cs =
-          assertSuggest(name, csKind: kind, relevance: relevance);
-      protocol.Element element = cs.element;
-      expect(element, isNotNull);
-      expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
-      expect(element.name, equals(name));
-      String param = element.parameters;
-      expect(param, isNotNull);
-      expect(param[0], equals('('));
-      expect(param[param.length - 1], equals(')'));
-      expect(element.returnType, equals(returnType));
-      assertHasParameterInfo(cs);
-      return cs;
-    } else {
-      return assertNotSuggested(name);
-    }
-  }
-
   CompletionSuggestion assertSuggestParameter(String name, String returnType,
       {int relevance: DART_RELEVANCE_PARAMETER}) {
     return assertNotSuggested(name);
@@ -660,11 +636,7 @@
 
   CompletionSuggestion assertSuggestInvocationClass(String name,
       [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestClass(name, relevance: relevance);
-    } else {
-      return assertNotSuggested(name);
-    }
+    return assertNotSuggested(name);
   }
 
   CompletionSuggestion assertSuggestInvocationField(String name, String type,
@@ -675,42 +647,24 @@
   CompletionSuggestion assertSuggestInvocationGetter(
       String name, String returnType,
       {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestGetter(name, returnType,
-          relevance: relevance, isDeprecated: isDeprecated);
-    } else {
-      return assertNotSuggested(name);
-    }
+    return assertNotSuggested(name);
   }
 
   CompletionSuggestion assertSuggestInvocationMethod(
       String name, String declaringType, String returnType,
       {int relevance: DART_RELEVANCE_DEFAULT}) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestMethod(name, declaringType, returnType,
-          relevance: relevance);
-    } else {
-      return assertNotSuggested(name);
-    }
+    return assertNotSuggested(name);
   }
 
   CompletionSuggestion assertSuggestInvocationSetter(String name,
       [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestSetter(name);
-    } else {
-      return assertNotSuggested(name);
-    }
+    return assertNotSuggested(name);
   }
 
   CompletionSuggestion assertSuggestInvocationTopLevelVar(
       String name, String returnType,
       [int relevance = DART_RELEVANCE_DEFAULT]) {
-    if (contributor is PrefixedElementContributor) {
-      return assertSuggestTopLevelVar(name, returnType, relevance);
-    } else {
-      return assertNotSuggested(name);
-    }
+    return assertNotSuggested(name);
   }
 
   CompletionSuggestion assertSuggestLocalClass(String name,
@@ -1336,7 +1290,8 @@
       assertSuggestImportedClass('EE');
       // hidden element suggested as low relevance
       //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('g');
       assertNotSuggested('G');
       //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
       assertSuggestImportedClass('Object');
@@ -1447,7 +1402,8 @@
       assertSuggestImportedClass('EE');
       // hidden element suggested as low relevance
       //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('g');
       assertNotSuggested('G');
       //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
       assertSuggestImportedClass('Object');
@@ -1570,7 +1526,8 @@
       assertSuggestImportedClass('EE');
       // hidden element suggested as low relevance
       //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('g');
       assertNotSuggested('G');
       //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
       assertSuggestImportedClass('Object');
@@ -1677,7 +1634,8 @@
       assertSuggestImportedClass('EE');
       // hidden element suggested as low relevance
       //assertSuggestImportedClass('F', COMPLETION_RELEVANCE_LOW);
-      assertSuggestLibraryPrefix('g');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('g');
       assertNotSuggested('G');
       //assertSuggestImportedClass('H', COMPLETION_RELEVANCE_LOW);
       assertSuggestImportedClass('Object');
@@ -2124,7 +2082,8 @@
         expect(suggestionO.element.isPrivate, isFalse);
       }
       assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('x');
     });
   }
 
@@ -2147,7 +2106,8 @@
       assertSuggestLocalClass('_B');
       assertSuggestImportedClass('Object');
       assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('x');
     });
   }
 
@@ -2170,7 +2130,8 @@
       assertSuggestLocalClass('_B');
       assertSuggestImportedClass('String');
       assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('x');
     });
   }
 
@@ -2193,7 +2154,8 @@
       assertSuggestLocalClass('_B');
       assertSuggestImportedClass('String');
       assertNotSuggested('Sew');
-      assertSuggestLibraryPrefix('Soo');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('Soo');
     });
   }
 
@@ -2216,7 +2178,8 @@
       assertSuggestLocalClass('_B');
       assertSuggestImportedClass('Object');
       assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('x');
     });
   }
 
@@ -2239,7 +2202,8 @@
       assertSuggestLocalClass('_B');
       assertSuggestImportedClass('Object');
       assertNotSuggested('T');
-      assertSuggestLibraryPrefix('x');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('x');
     });
   }
 
@@ -2452,7 +2416,8 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
+      // Suggested by NamedConstructorContributor
+      assertNotSuggested('c');
       assertNotSuggested('F1');
       assertNotSuggested('T1');
       assertNotSuggested('_d');
@@ -2479,7 +2444,8 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
+      // Suggested by NamedConstructorContributor
+      assertNotSuggested('c');
       assertNotSuggested('F1');
       assertNotSuggested('T1');
       assertNotSuggested('_d');
@@ -2497,7 +2463,8 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset - 2);
       expect(request.replacementLength, 13);
-      assertSuggestNamedConstructor('fromCharCodes', 'String');
+      // Suggested by NamedConstructorContributor
+      assertNotSuggested('fromCharCodes');
       assertNotSuggested('isEmpty');
       assertNotSuggested('isNotEmpty');
       assertNotSuggested('length');
@@ -2518,8 +2485,9 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
-      assertSuggestNamedConstructor('_d', 'X');
+      // Suggested by NamedConstructorContributor
+      assertNotSuggested('c');
+      assertNotSuggested('_d');
       assertNotSuggested('F1');
       assertNotSuggested('T1');
       assertNotSuggested('z');
@@ -2539,8 +2507,9 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestNamedConstructor('c', 'X');
-      assertSuggestNamedConstructor('_d', 'X');
+      // Suggested by NamedConstructorContributor
+      assertNotSuggested('c');
+      assertNotSuggested('_d');
       assertNotSuggested('F1');
       assertNotSuggested('T1');
       assertNotSuggested('z');
@@ -3878,9 +3847,10 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestInvocationField('scA', 'String');
-      assertSuggestInvocationField('scB', 'int');
-      assertSuggestInvocationField('scI', null);
+      // Suggested by StaticMemberContributor
+      assertNotSuggested('scA');
+      assertNotSuggested('scB');
+      assertNotSuggested('scI');
       assertNotSuggested('b');
       assertNotSuggested('_c');
       assertNotSuggested('d');
@@ -4002,9 +3972,10 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestInvocationClass('X');
-      assertSuggestInvocationClass('Y');
-      assertSuggestInvocationTopLevelVar('T1', null);
+      // Suggested by LibraryMemberContributor
+      assertNotSuggested('X');
+      assertNotSuggested('Y');
+      assertNotSuggested('T1');
       assertNotSuggested('T2');
       assertNotSuggested('Object');
       assertNotSuggested('b');
@@ -4031,8 +4002,9 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestInvocationClass('X');
-      assertSuggestInvocationClass('Y');
+      // Suggested by LibraryMemberContributor
+      assertNotSuggested('X');
+      assertNotSuggested('Y');
       assertNotSuggested('T1');
       assertNotSuggested('T2');
       assertNotSuggested('Object');
@@ -4060,8 +4032,9 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestInvocationClass('X');
-      assertSuggestInvocationClass('Y');
+      // Suggested by LibraryMemberContributor
+      assertNotSuggested('X');
+      assertNotSuggested('Y');
       assertNotSuggested('T1');
       assertNotSuggested('T2');
       assertNotSuggested('Object');
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 273509c..0a14ef1 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -31,15 +31,19 @@
 
   void assertSuggestArgumentList(
       List<String> paramNames, List<String> paramTypes) {
-    CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST;
-    CompletionSuggestion cs = getSuggest(csKind: csKind);
-    if (cs == null) {
-      failedCompletion('expected completion $csKind', suggestions);
-    }
-    assertSuggestArgumentList_params(
-        paramNames, paramTypes, cs.parameterNames, cs.parameterTypes);
-    expect(cs.relevance, DART_RELEVANCE_HIGH);
-    assertNoOtherSuggestions([cs]);
+    // DEPRECATED... argument lists are no longer suggested.
+    // See https://github.com/dart-lang/sdk/issues/25197
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+
+    // CompletionSuggestionKind csKind = CompletionSuggestionKind.ARGUMENT_LIST;
+    // CompletionSuggestion cs = getSuggest(csKind: csKind);
+    // if (cs == null) {
+    //   failedCompletion('expected completion $csKind', suggestions);
+    // }
+    // assertSuggestArgumentList_params(
+    //     paramNames, paramTypes, cs.parameterNames, cs.parameterTypes);
+    // expect(cs.relevance, DART_RELEVANCE_HIGH);
+    // assertNoOtherSuggestions([cs]);
   }
 
   void assertSuggestArgumentList_params(
@@ -302,6 +306,27 @@
     assertNoSuggestions();
   }
 
+  test_ArgumentList_imported_function_named_param_label1() async {
+    //
+    addTestSource('main() { int.parse("16", r^: 16);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_imported_function_named_param_label2() async {
+    //
+    addTestSource('main() { int.parse("16", ^r: 16);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
+  test_ArgumentList_imported_function_named_param_label3() async {
+    //
+    addTestSource('main() { int.parse("16", ^: 16);}');
+    await computeSuggestions();
+    assertSuggestArguments(namedArguments: ['radix', 'onError']);
+  }
+
   test_ArgumentList_local_constructor_named_param() async {
     //
     addTestSource('''
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index d75024b..59e5e69 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -368,6 +368,9 @@
     if (libraries.isNotEmpty) {
       return new Future.value(libraries);
     }
+    if (times == 0) {
+      fail('failed to determine libraries containing $testSource');
+    }
     context.performAnalysisTask();
     // We use a delayed future to allow microtask events to finish. The
     // Future.value or Future() constructors use scheduleMicrotask themselves and
@@ -380,23 +383,33 @@
   Future computeSuggestions([int times = 200]) async {
     CompletionRequestImpl baseRequest = new CompletionRequestImpl(
         context, provider, searchEngine, testSource, completionOffset);
-    request = new DartCompletionRequestImpl.forRequest(baseRequest);
+
+    // Build the request
+    Completer<DartCompletionRequest> requestCompleter =
+        new Completer<DartCompletionRequest>();
+    DartCompletionRequestImpl
+        .from(baseRequest)
+        .then((DartCompletionRequest request) {
+      requestCompleter.complete(request);
+    });
+    request = await performAnalysis(times, requestCompleter);
+
     var range = new ReplacementRange.compute(request.offset, request.target);
     replacementOffset = range.offset;
     replacementLength = range.length;
-    Completer<List<CompletionSuggestion>> completer =
+    Completer<List<CompletionSuggestion>> suggestionCompleter =
         new Completer<List<CompletionSuggestion>>();
 
     // Request completions
     contributor
         .computeSuggestions(request)
         .then((List<CompletionSuggestion> computedSuggestions) {
-      completer.complete(computedSuggestions);
+      suggestionCompleter.complete(computedSuggestions);
     });
 
     // Perform analysis until the suggestions have been computed
     // or the max analysis cycles ([times]) has been reached
-    suggestions = await performAnalysis(times, completer);
+    suggestions = await performAnalysis(times, suggestionCompleter);
     expect(suggestions, isNotNull, reason: 'expected suggestions');
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 8933b0a..1d3549d 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -333,13 +333,15 @@
     addTestSource('main() {foo(() ^ {}}}');
     await computeSuggestions();
     assertSuggestKeywords([],
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_anonymous_function_async2() async {
     addTestSource('main() {foo(() a^ {}}}');
     await computeSuggestions();
-    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['async']);
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_anonymous_function_async3() async {
@@ -348,6 +350,20 @@
     assertSuggestKeywords([]);
   }
 
+  test_anonymous_function_async4() async {
+    addTestSource('main() {foo(() ^ => 2}}');
+    await computeSuggestions();
+    assertSuggestKeywords([],
+        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_anonymous_function_async5() async {
+    addTestSource('main() {foo(() ^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
+  }
+
   test_argument() async {
     addTestSource('main() {foo(^);}');
     await computeSuggestions();
@@ -651,35 +667,40 @@
     addTestSource('main()^');
     await computeSuggestions();
     assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_function_async2() async {
     addTestSource('main()^{}');
     await computeSuggestions();
     assertSuggestKeywords([],
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_function_async3() async {
     addTestSource('main()a^');
     await computeSuggestions();
     assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_function_async4() async {
     addTestSource('main()a^{}');
     await computeSuggestions();
     assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_function_async5() async {
     addTestSource('main()a^ Foo foo;');
     await computeSuggestions();
     assertSuggestKeywords(DECLARATION_KEYWORDS,
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_function_body_inClass_constructorInitializer() async {
@@ -706,6 +727,19 @@
     assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
   }
 
+  test_function_body_inClass_constructorInitializer_async_star() async {
+    addTestSource(r'''
+  foo(p) {}
+  class A {
+    final f;
+    A() : f = foo(() async* {^});
+  }
+  ''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
   test_function_body_inClass_field() async {
     addTestSource(r'''
 class A {
@@ -756,6 +790,21 @@
     assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
   }
 
+  test_function_body_inClass_methodBody_inFunction_async_star() async {
+    addTestSource(r'''
+  class A {
+    m() {
+      f() {
+        f2() async* {^};
+      };
+    }
+  }
+  ''');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
   test_function_body_inUnit() async {
     addTestSource('main() {^}');
     await computeSuggestions();
@@ -774,6 +823,34 @@
     assertSuggestKeywords(STMT_START_OUTSIDE_CLASS, pseudoKeywords: ['await']);
   }
 
+  test_function_body_inUnit_async_star() async {
+    addTestSource('main() async* {n^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inUnit_async_star2() async {
+    addTestSource('main() async* {n^ foo}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inUnit_sync_star() async {
+    addTestSource('main() sync* {n^}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
+  test_function_body_inUnit_sync_star2() async {
+    addTestSource('main() sync* {n^ foo}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_OUTSIDE_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
   test_if_expression_in_class() async {
     addTestSource('class A {foo() {if (^) }}');
     await computeSuggestions();
@@ -1098,38 +1175,44 @@
   test_method_async() async {
     addTestSource('class A { foo() ^}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_async2() async {
     addTestSource('class A { foo() ^{}}');
     await computeSuggestions();
     assertSuggestKeywords([],
-        pseudoKeywords: ['async'], relevance: DART_RELEVANCE_HIGH);
+        pseudoKeywords: ['async', 'async*', 'sync*'],
+        relevance: DART_RELEVANCE_HIGH);
   }
 
   test_method_async3() async {
     addTestSource('class A { foo() a^}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_async4() async {
     addTestSource('class A { foo() a^{}}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_async5() async {
     addTestSource('class A { foo() ^ Foo foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_async6() async {
     addTestSource('class A { foo() a^ Foo foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_async7() async {
@@ -1142,7 +1225,8 @@
   test_method_async8() async {
     addTestSource('class A { foo() a^ Foo foo;}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS, pseudoKeywords: ['async']);
+    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+        pseudoKeywords: ['async', 'async*', 'sync*']);
   }
 
   test_method_body() async {
@@ -1175,6 +1259,13 @@
     assertSuggestKeywords(STMT_START_IN_CLASS, pseudoKeywords: ['await']);
   }
 
+  test_method_body_async_star() async {
+    addTestSource('class A { foo() async* {^}}');
+    await computeSuggestions();
+    assertSuggestKeywords(STMT_START_IN_CLASS,
+        pseudoKeywords: ['await', 'yield', 'yield*']);
+  }
+
   test_method_body_async2() async {
     addTestSource('class A { foo() async => ^}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
new file mode 100644
index 0000000..ac38fa6
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -0,0 +1,262 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.services.completion.contributor.dart.library_member;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LibraryMemberContributorTest);
+}
+
+@reflectiveTest
+class LibraryMemberContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new LibraryMemberContributor();
+  }
+
+  test_libraryPrefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^}');
+    await computeSuggestions();
+    assertSuggestClass('Future');
+    assertNotSuggested('loadLibrary');
+  }
+
+  test_libraryPrefix_cascade() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math..^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_libraryPrefix_cascade2() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math.^.}''');
+    await computeSuggestions();
+    assertSuggestFunction('min', 'num');
+  }
+
+  test_libraryPrefix_cascade3() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math..^a}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_libraryPrefix_cascade4() async {
+    addTestSource('''
+    import "dart:math" as math;
+    main() {math.^.a}''');
+    await computeSuggestions();
+    assertSuggestFunction('min', 'num');
+  }
+
+  test_libraryPrefix2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
+    await computeSuggestions();
+    assertSuggestClass('Future');
+  }
+
+  test_libraryPrefix3() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
+    await computeSuggestions();
+    assertSuggestConstructor('Future');
+    assertSuggestConstructor('Future.delayed');
+  }
+
+  test_libraryPrefix_deferred() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
+    await computeSuggestions();
+    assertSuggestClass('Future');
+    assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+  }
+
+  test_libraryPrefix_deferred_inPart() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart';
+    addSource(
+        libFile,
+        '''
+        library testA;
+        import "dart:async" deferred as bar;
+        part "$testFile";''');
+    addTestSource('part of testA; foo() {bar.^}');
+    // Assume that libraries containing has been computed for part files
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    assertSuggestClass('Future');
+    assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+  }
+
+  test_libraryPrefix_with_exports() async {
+    addSource('/libA.dart', 'library libA; class A { }');
+    addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
+    addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
+    await computeSuggestions();
+    assertSuggestClass('B');
+    assertSuggestClass('A');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        main() {b.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_inPart() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    var libFile = '${testFile.substring(0, testFile.length - 5)}A.dart';
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addSource(
+        libFile,
+        '''
+        library testA;
+        import "/testB.dart" as b;
+        part "$testFile";
+        var T2;
+        class A { }''');
+    addTestSource('''
+        part of testA;
+        main() {b.^}''');
+    // Assume that libraries containing has been computed for part files
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^ f) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestClass('X');
+    assertSuggestClass('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class _W {M y; var _z;}
+        class X extends _W {}
+        class M{}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo(X x) {x.^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class A {static int bar = 10;}
+        _B() {}''');
+    addTestSource('''
+        import "/testA.dart";
+        class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
new file mode 100644
index 0000000..2de1f23
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
@@ -0,0 +1,377 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.services.completion.contributor.dart.library_prefix;
+
+import 'package:analysis_server/src/protocol_server.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(LibraryPrefixContributorTest);
+}
+
+@reflectiveTest
+class LibraryPrefixContributorTest extends DartCompletionContributorTest {
+  void assertSuggestLibraryPrefixes(List<String> expectedPrefixes) {
+    for (String prefix in expectedPrefixes) {
+      CompletionSuggestion cs = assertSuggest(prefix,
+          csKind: CompletionSuggestionKind.IDENTIFIER,
+          relevance: DART_RELEVANCE_DEFAULT);
+      Element element = cs.element;
+      expect(element, isNotNull);
+      expect(element.kind, equals(ElementKind.LIBRARY));
+      expect(element.parameters, isNull);
+      expect(element.returnType, isNull);
+      assertHasNoParameterInfo(cs);
+    }
+    if (suggestions.length != expectedPrefixes.length) {
+      failedCompletion('expected only ${expectedPrefixes.length} suggestions');
+    }
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new LibraryPrefixContributor();
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    var f;
+    localF(int arg1) { }
+    {var x;}
+    ^ var r;
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['g']);
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    final var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['g']);
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+export "dart:math" hide max;
+class A {int x;}
+@deprecated D1() {int x;}
+class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+String T1;
+var _T2;
+class C { }
+class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+class EE { }
+class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+class H { }
+int T3;
+var _T4;'''); // not imported
+    addTestSource('''
+import "/testAB.dart";
+import "/testCD.dart" hide D;
+import "/testEEF.dart" show EE;
+import "/testG.dart" as g;
+int T5;
+var _T6;
+String get T7 => 'hello';
+set T8(int value) { partT8() {} }
+Z D2() {int x;}
+class X {
+  int get clog => 8;
+  set blog(value) { }
+  a() {
+    final ^
+    var f;
+    localF(int arg1) { }
+    {var x;}
+  }
+  void b() { }}
+class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['g']);
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+@deprecated class A {^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ A(){}}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as Soo;
+class A {final S^ A();}
+class _B {}
+A Sew;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertSuggestLibraryPrefixes(['Soo']);
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ final foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+class B { }''');
+    addTestSource('''
+import "testB.dart" as x;
+class A {final ^ var foo;}
+class _B {}
+A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestLibraryPrefixes(['x']);
+  }
+
+  test_InstanceCreationExpression() async {
+    addSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addTestSource('''
+import "/testA.dart" as t;
+import "dart:math" as math;
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    assertSuggestLibraryPrefixes(['math', 't']);
+  }
+
+  test_InstanceCreationExpression2() async {
+    addTestSource('import "dart:convert" as json;f() {var x=new js^}');
+    await computeSuggestions();
+    assertSuggestLibraryPrefixes(['json']);
+  }
+
+  test_InstanceCreationExpression_inPart() async {
+    addSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addSource(
+        '/testB.dart',
+        '''
+library testB;
+import "/testA.dart" as t;
+import "dart:math" as math;
+part "$testFile"
+main() {new ^ String x = "hello";}''');
+    addTestSource('''
+part of testB;
+main() {new ^ String x = "hello";}''');
+    await computeLibrariesContaining();
+    await computeSuggestions();
+    assertSuggestLibraryPrefixes(['math', 't']);
+  }
+
+  test_InstanceCreationExpression_inPart_detached() async {
+    addSource(
+        '/testA.dart',
+        '''
+class A {foo(){var f; {var x;}}}
+class B {B(this.x, [String boo]) { } int x;}
+class C {C.bar({boo: 'hoo', int z: 0}) { } }''');
+    addSource(
+        '/testB.dart',
+        '''
+library testB;
+import "/testA.dart" as t;
+import "dart:math" as math;
+//part "$testFile"
+main() {new ^ String x = "hello";}''');
+    addTestSource('''
+//part of testB;
+main() {new ^ String x = "hello";}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
new file mode 100644
index 0000000..0ac517b
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
@@ -0,0 +1,182 @@
+// 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 test.services.completion.contributor.dart.named_constructor;
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+import 'package:analyzer/src/generated/source.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(NamedConstructorContributorTest);
+}
+
+@reflectiveTest
+class NamedConstructorContributorTest extends DartCompletionContributorTest {
+  CompletionSuggestion assertSuggestNamedConstructor(
+      String name, String returnType,
+      [int relevance = DART_RELEVANCE_DEFAULT,
+      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
+    CompletionSuggestion cs =
+        assertSuggest(name, csKind: kind, relevance: relevance);
+    Element element = cs.element;
+    expect(element, isNotNull);
+    expect(element.kind, equals(ElementKind.CONSTRUCTOR));
+    expect(element.name, equals(name));
+    String param = element.parameters;
+    expect(param, isNotNull);
+    expect(param[0], equals('('));
+    expect(param[param.length - 1], equals(')'));
+    expect(element.returnType, equals(returnType));
+    assertHasParameterInfo(cs);
+    return cs;
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new NamedConstructorContributor();
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    Source libSource = addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    // Assume that imported libraries are resolved
+    await resolveLibraryUnit(libSource);
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedClass_unresolved() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    // Assume that imported libraries are NOT resolved
+    //await resolveLibraryUnit(libSource);
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    Source libSource = addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    // Assume that imported libraries are resolved
+    await resolveLibraryUnit(libSource);
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    assertSuggestNamedConstructor('fromCharCodes', 'String');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertSuggestNamedConstructor('_d', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestNamedConstructor('c', 'X');
+    assertSuggestNamedConstructor('_d', 'X');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
new file mode 100644
index 0000000..6efd8ab
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -0,0 +1,289 @@
+// 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 test.services.completion.dart.static_member;
+
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(StaticMemberContributorTest);
+}
+
+@reflectiveTest
+class StaticMemberContributorTest extends DartCompletionContributorTest {
+  @override
+  DartCompletionContributor createContributor() {
+    return new StaticMemberContributor();
+  }
+
+  fail_enumConst_deprecated() async {
+    addTestSource('@deprecated enum E { one, two } main() {E.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // TODO(danrubel) Investigate why enum suggestion is not marked
+    // as deprecated if enum ast element is deprecated
+    assertSuggestEnumConst('one', isDeprecated: true);
+    assertSuggestEnumConst('two', isDeprecated: true);
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>', isDeprecated: true);
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {
+          static const scI = 'boo';
+          X get f => new A();
+          get _g => new A();}
+        class B implements I {
+          static const int scB = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends B {
+          static const String scA = 'foo';
+          w() { }}
+        main() {A.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('scA', 'String');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_enumConst() async {
+    addTestSource('enum E { one, two } main() {E.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst2() async {
+    addTestSource('enum E { one, two } main() {E.o^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst3() async {
+    addTestSource('enum E { one, two } main() {E.^ int g;}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst_cascade1() async {
+    addTestSource('enum E { one, two } main() {E..^}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_enumConst_cascade2() async {
+    addTestSource('enum E { one, two } main() {E.^.}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_enumConst_cascade3() async {
+    addTestSource('enum E { one, two } main() {E..o^}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_enumConst_cascade4() async {
+    addTestSource('enum E { one, two } main() {E.^.o}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertSuggestEnumConst('one');
+    assertSuggestEnumConst('two');
+    assertNotSuggested('index');
+    assertSuggestField('values', 'List<E>');
+  }
+
+  test_keyword() async {
+    addTestSource('class C { static C get instance => null; } main() {C.in^}');
+    await computeSuggestions();
+    assertSuggestGetter('instance', 'C');
+  }
+
+  test_only_static() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^ print("something");}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static_cascade1() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C..^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_only_static_cascade2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^.}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static_cascade3() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C..m^()}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_only_static_cascade4() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class B {
+  static int b1;
+}
+class C extends B {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^.m()}''');
+    await computeSuggestions();
+    assertNotSuggested('b1');
+    assertNotSuggested('f1');
+    assertSuggestField('f2', 'int');
+    assertNotSuggested('m1');
+    assertSuggestMethod('m2', 'C', null);
+  }
+
+  test_only_static_cascade_prefixed1() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+import "dart:async" as async;
+void main() {async.Future..w^()}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_only_static_cascade_prefixed2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+import "dart:async" as async;
+void main() {async.Future.^.w()}''');
+    await computeSuggestions();
+    assertSuggestMethod('wait', 'Future', 'Future<dynamic>');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index 6d5c836..a9dc275 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -7,12 +7,17 @@
 import 'package:unittest/unittest.dart';
 
 import '../../../utils.dart';
-import 'combinator_contributor_test.dart' as combinator_test;
 import 'arglist_contributor_test.dart' as arglist_test;
+import 'combinator_contributor_test.dart' as combinator_test;
 import 'common_usage_sorter_test.dart' as common_usage_test;
 import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
 import 'inherited_contributor_test.dart' as inherited_contributor_test;
 import 'keyword_contributor_test.dart' as keyword_test;
+import 'library_member_contributor_test.dart' as library_member_test;
+import 'library_prefix_contributor_test.dart' as library_prefix_test;
+import 'named_constructor_contributor_test.dart' as named_contributor_test;
+import 'static_member_contributor_test.dart' as static_contributor_test;
+import 'type_member_contributor_test.dart' as type_member_contributor_test;
 import 'uri_contributor_test.dart' as uri_contributor_test;
 
 /// Utility for manually running all tests.
@@ -25,6 +30,11 @@
     field_formal_contributor_test.main();
     inherited_contributor_test.main();
     keyword_test.main();
+    library_member_test.main();
+    library_prefix_test.main();
+    named_contributor_test.main();
+    static_contributor_test.main();
+    type_member_contributor_test.main();
     uri_contributor_test.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
new file mode 100644
index 0000000..8d176b8
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -0,0 +1,4157 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.services.completion.contributor.dart.type_member;
+
+import 'dart:async';
+
+import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../../utils.dart';
+import 'completion_contributor_util.dart';
+
+main() {
+  initializeTestEnvironment();
+  defineReflectiveTests(TypeMemberContributorTest);
+}
+
+@reflectiveTest
+class TypeMemberContributorTest extends DartCompletionContributorTest {
+  /**
+   * Check whether a declaration of the form [shadower] in a derived class
+   * shadows a declaration of the form [shadowee] in a base class, for the
+   * purposes of what is shown during completion.  [shouldBeShadowed] indicates
+   * whether shadowing is expected.
+   */
+  Future check_shadowing(
+      String shadower, String shadowee, bool shouldBeShadowed) async {
+    addTestSource('''
+class Base {
+  $shadowee
+}
+class Derived extends Base {
+  $shadower
+}
+void f(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    List<CompletionSuggestion> suggestionsForX = suggestions
+        .where((CompletionSuggestion s) => s.completion == 'x')
+        .toList();
+    expect(suggestionsForX, hasLength(1));
+    if (shouldBeShadowed) {
+      expect(suggestionsForX[0].declaringType, 'Derived');
+    } else {
+      expect(suggestionsForX[0].declaringType, 'Base');
+    }
+  }
+
+  fail_test_PrefixedIdentifier_trailingStmt_const_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  @override
+  DartCompletionContributor createContributor() {
+    return new TypeMemberContributor();
+  }
+
+  test_enumConst() async {
+    addTestSource('enum E { one, two } main() {E.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertNotSuggested('index');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst2() async {
+    addTestSource('enum E { one, two } main() {E.o^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertNotSuggested('index');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst3() async {
+    addTestSource('enum E { one, two } main() {E.^ int g;}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertNotSuggested('index');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst_index() async {
+    addTestSource('enum E { one, two } main() {E.one.^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertSuggestField('index', 'int');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst_index2() async {
+    addTestSource('enum E { one, two } main() {E.one.i^}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertSuggestField('index', 'int');
+    assertNotSuggested('values');
+  }
+
+  test_enumConst_index3() async {
+    addTestSource('enum E { one, two } main() {E.one.^ int g;}');
+    await computeSuggestions();
+    assertNotSuggested('E');
+    assertNotSuggested('one');
+    assertNotSuggested('two');
+    assertSuggestField('index', 'int');
+    assertNotSuggested('values');
+  }
+
+  test_generic_field() async {
+    addTestSource('''
+class C<T> {
+  T t;
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestField('t', 'int');
+  }
+
+  test_generic_getter() async {
+    addTestSource('''
+class C<T> {
+  T get t => null;
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestGetter('t', 'int');
+  }
+
+  test_generic_method() async {
+    addTestSource('''
+class C<T> {
+  T m(T t) {}
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int');
+    expect(suggestion.parameterTypes[0], 'int');
+    expect(suggestion.element.returnType, 'int');
+    expect(suggestion.element.parameters, '(int t)');
+  }
+
+  test_generic_setter() async {
+    addTestSource('''
+class C<T> {
+  set t(T value) {}
+}
+void f(C<int> c) {
+  c.^
+}
+''');
+    await computeSuggestions();
+    // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int'
+    // as a parmeter to it, and it will check the appropriate field in
+    // the suggestion object.
+    CompletionSuggestion suggestion = assertSuggestSetter('t');
+    expect(suggestion.element.parameters, '(int value)');
+  }
+
+  test_keyword() async {
+    addTestSource('class C { static C get instance => null; } main() {C.in^}');
+    await computeSuggestions();
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('instance');
+  }
+
+  test_libraryPrefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+    assertNotSuggested('loadLibrary');
+  }
+
+  test_libraryPrefix2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+  }
+
+  test_libraryPrefix3() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+    assertNotSuggested('Future.delayed');
+  }
+
+  test_libraryPrefix_deferred() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('Future');
+    assertNotSuggested('loadLibrary');
+  }
+
+  test_libraryPrefix_with_exports() async {
+    addSource('/libA.dart', 'library libA; class A { }');
+    addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
+    addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
+    await computeSuggestions();
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+  }
+
+  test_local() async {
+    addTestSource('foo() {String x = "bar"; x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_local_is() async {
+    addTestSource('foo() {var x; if (x is String) x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_local_propogatedType() async {
+    addTestSource('foo() {var x = "bar"; x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_method_parameters_mixed_required_and_named() async {
+    addTestSource('''
+class C {
+  void m(x, {int y}) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_mixed_required_and_positional() async {
+    addTestSource('''
+class C {
+  void m(x, [int y]) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_named() async {
+    addTestSource('''
+class C {
+  void m({x, int y}) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  test_method_parameters_none() async {
+    addTestSource('''
+class C {
+  void m() {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_positional() async {
+    addTestSource('''
+class C {
+  void m([x, int y]) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_method_parameters_required() async {
+    addTestSource('''
+class C {
+  void m(x, int y) {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  test_no_parameters_field() async {
+    addTestSource('''
+class C {
+  int x;
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestField('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_getter() async {
+    addTestSource('''
+class C {
+  int get x => null;
+}
+void main() {int y = new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_no_parameters_setter() async {
+    addTestSource('''
+class C {
+  set x(int value) {};
+}
+void main() {int y = new C().^}''');
+    await computeSuggestions();
+    CompletionSuggestion suggestion = assertSuggestSetter('x');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  test_only_instance() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {new C().^}''');
+    await computeSuggestions();
+    assertSuggestField('f1', 'int');
+    assertNotSuggested('f2');
+    assertSuggestMethod('m1', 'C', null);
+    assertNotSuggested('m2');
+  }
+
+  test_only_instance2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {new C().^ print("something");}''');
+    await computeSuggestions();
+    assertSuggestField('f1', 'int');
+    assertNotSuggested('f2');
+    assertSuggestMethod('m1', 'C', null);
+    assertNotSuggested('m2');
+  }
+
+  test_only_static() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^}''');
+    await computeSuggestions();
+    assertNotSuggested('f1');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('f2');
+    assertNotSuggested('m1');
+    assertNotSuggested('m2');
+  }
+
+  test_only_static2() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class C {
+  int f1;
+  static int f2;
+  m1() {}
+  static m2() {}
+}
+void main() {C.^ print("something");}''');
+    await computeSuggestions();
+    assertNotSuggested('f1');
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('f2');
+    assertNotSuggested('m1');
+    assertNotSuggested('m2');
+  }
+
+  test_param() async {
+    addTestSource('foo(String x) {x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_param_is() async {
+    addTestSource('foo(x) {if (x is String) x.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_shadowing_field_over_field() =>
+      check_shadowing('int x;', 'int x;', true);
+
+  test_shadowing_field_over_getter() =>
+      check_shadowing('int x;', 'int get x => null;', true);
+
+  test_shadowing_field_over_method() =>
+      check_shadowing('int x;', 'void x() {}', true);
+
+  test_shadowing_field_over_setter() =>
+      check_shadowing('int x;', 'set x(int value) {}', true);
+
+  test_shadowing_getter_over_field() =>
+      check_shadowing('int get x => null;', 'int x;', false);
+
+  test_shadowing_getter_over_getter() =>
+      check_shadowing('int get x => null;', 'int get x => null;', true);
+
+  test_shadowing_getter_over_method() =>
+      check_shadowing('int get x => null;', 'void x() {}', true);
+
+  test_shadowing_getter_over_setter() =>
+      check_shadowing('int get x => null;', 'set x(int value) {}', false);
+
+  test_shadowing_method_over_field() =>
+      check_shadowing('void x() {}', 'int x;', true);
+
+  test_shadowing_method_over_getter() =>
+      check_shadowing('void x() {}', 'int get x => null;', true);
+
+  test_shadowing_method_over_method() =>
+      check_shadowing('void x() {}', 'void x() {}', true);
+
+  test_shadowing_method_over_setter() =>
+      check_shadowing('void x() {}', 'set x(int value) {}', true);
+
+  test_shadowing_mixin_order() async {
+    addTestSource('''
+class Base {
+}
+class Mixin1 {
+  void f() {}
+}
+class Mixin2 {
+  void f() {}
+}
+class Derived extends Base with Mixin1, Mixin2 {
+}
+void test(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in
+    // reverse order.  The correct order is that Derived inherits from
+    // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1",
+    // which inherits from "Base".  So the definition of f in Mixin2 should
+    // shadow the definition in Mixin1.
+    assertSuggestMethod('f', 'Mixin2', 'void');
+  }
+
+  test_shadowing_mixin_over_superclass() async {
+    addTestSource('''
+class Base {
+  void f() {}
+}
+class Mixin {
+  void f() {}
+}
+class Derived extends Base with Mixin {
+}
+void test(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('f', 'Mixin', 'void');
+  }
+
+  test_shadowing_setter_over_field() =>
+      check_shadowing('set x(int value) {}', 'int x;', false);
+
+  test_shadowing_setter_over_getter() =>
+      check_shadowing('set x(int value) {}', 'int get x => null;', false);
+
+  test_shadowing_setter_over_method() =>
+      check_shadowing('set x(int value) {}', 'void x() {}', true);
+
+  test_shadowing_setter_over_setter() =>
+      check_shadowing('set x(int value) {}', 'set x(int value) {}', true);
+
+  test_shadowing_superclass_over_interface() async {
+    addTestSource('''
+class Base {
+  void f() {}
+}
+class Interface {
+  void f() {}
+}
+class Derived extends Base implements Interface {
+}
+void test(Derived d) {
+  d.^
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('f', 'Base', 'void');
+  }
+
+  test_super() async {
+    // SimpleIdentifier  MethodInvocation  ExpressionStatement
+    addTestSource('''
+class C3 {
+  int fi3;
+  static int fs3;
+  m() {}
+  mi3() {}
+  static ms3() {}
+}
+class C2 {
+  int fi2;
+  static int fs2;
+  m() {}
+  mi2() {}
+  static ms2() {}
+}
+class C1 extends C2 implements C3 {
+  int fi1;
+  static int fs1;
+  m() {super.^}
+  mi1() {}
+  static ms1() {}
+}''');
+    await computeSuggestions();
+    assertNotSuggested('fi1');
+    assertNotSuggested('fs1');
+    assertNotSuggested('mi1');
+    assertNotSuggested('ms1');
+    assertSuggestField('fi2', 'int');
+    assertNotSuggested('fs2');
+    assertSuggestMethod('mi2', 'C2', null);
+    assertNotSuggested('ms2');
+    assertSuggestMethod('m', 'C2', null, relevance: DART_RELEVANCE_HIGH);
+    assertNotSuggested('fi3');
+    assertNotSuggested('fs3');
+    assertNotSuggested('mi3');
+    assertNotSuggested('ms3');
+  }
+
+  test_ArgumentList() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_imported_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        expect(arg) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_functionalArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_InstanceCreationExpression_typedefArg() async {
+    // ArgumentList  InstanceCreationExpression  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        typedef Funct();
+        class A { A(Funct f) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar() => true;
+        void main() {new A(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_function() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        expect(arg) { }
+        class B { }
+        String bar() => true;
+        void main() {expect(^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_local_method() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import '/libA.dart'
+        class B {
+          expect(arg) { }
+          void foo() {expect(^)}}
+        String bar() => true;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_functionalArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { }
+        String bar(f()) => true;
+        void main() {bar(^);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_MethodInvocation_methodArg() async {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        class A { A(f()) { } }
+        bool hasLength(int expected) { }
+        void baz() { }''');
+    addTestSource('''
+        import 'dart:async';
+        import '/libA.dart';
+        class B { String bar(f()) => true; }
+        void main() {new B().bar(^);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNoSuggestions(kind: CompletionSuggestionKind.ARGUMENT_LIST);
+    assertNotSuggested('hasLength');
+    assertNotSuggested('identical');
+    assertNotSuggested('B');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('main');
+    assertNotSuggested('baz');
+    assertNotSuggested('print');
+  }
+
+  test_ArgumentList_namedParam() async {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addSource(
+        '/libA.dart',
+        '''
+        library A;
+        bool hasLength(int expected) { }''');
+    addTestSource('''
+        import '/libA.dart'
+        String bar() => true;
+        void main() {expect(foo: ^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('bar');
+    assertNotSuggested('hasLength');
+    assertNotSuggested('main');
+  }
+
+  test_AsExpression() async {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+        class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_AssignmentExpression_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_AssignmentExpression_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_AssignmentExpression_type() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^ b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          ^
+          b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          int^ b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    //assertNotSuggested('a');
+    //assertNotSuggested('main');
+    //assertNotSuggested('identical');
+  }
+
+  test_AssignmentExpression_type_partial_newline() async {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+        class A {} main() {
+          int a;
+          i^
+          b = 1;}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('int');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('identical');
+  }
+
+  test_AwaitExpression() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main() async {A a; await ^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_BinaryExpression_LHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+  }
+
+  test_BinaryExpression_RHS() async {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('==');
+  }
+
+  test_Block() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            ^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            final ^
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final2() async {
+    addTestSource('main() {final S^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final3() async {
+    addTestSource('main() {final ^ v;}');
+    await computeSuggestions();
+
+    assertNotSuggested('String');
+  }
+
+  test_Block_final_final() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            final var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_final_var() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            final ^
+            var f;
+            localF(int arg1) { }
+            {var x;}
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('localF');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+    assertNotSuggested('partT8');
+
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('C');
+    assertNotSuggested('partBoo');
+    // hidden element suggested as low relevance
+    // but imported results are partially filtered
+    //assertNotSuggested('D');
+    //assertNotSuggested(
+    //    'D1', null, true, COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('D2');
+    assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    assertNotSuggested('Object');
+    assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('T1');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    assertNotSuggested('T5');
+    assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    assertNotSuggested('T7');
+    assertNotSuggested('T8');
+    assertNotSuggested('clog');
+    assertNotSuggested('blog');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+    assertNotSuggested('Uri');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_identifier_partial() async {
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        class D3 { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        Z D2() {int x;}
+        class X {a() {var f; {var x;} D^ var r;} void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+
+    assertNotSuggested('X');
+    assertNotSuggested('Z');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertNotSuggested('f');
+    // Don't suggest locals out of scope
+    assertNotSuggested('r');
+    assertNotSuggested('x');
+
+    // imported elements are portially filtered
+    //assertNotSuggested('A');
+    assertNotSuggested('_B');
+    //assertNotSuggested('C');
+    // hidden element suggested as low relevance
+    assertNotSuggested('D');
+    assertNotSuggested('D1');
+    assertNotSuggested('D2');
+    // unimported elements suggested with low relevance
+    assertNotSuggested('D3');
+    //assertNotSuggested('EE');
+    // hidden element suggested as low relevance
+    //assertNotSuggested('F');
+    //assertNotSuggested('g');
+    assertNotSuggested('G');
+    //assertNotSuggested('H');
+    //assertNotSuggested('Object');
+    //assertNotSuggested('min');
+    //assertNotSuggested(
+    //    'max',
+    //    'num',
+    //    false,
+    //    COMPLETION_RELEVANCE_LOW);
+    //assertSuggestTopLevelVarGetterSetter('T1', 'String');
+    assertNotSuggested('_T2');
+    //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
+    assertNotSuggested('_T4');
+    //assertNotSuggested('T5');
+    //assertNotSuggested('_T6');
+    assertNotSuggested('==');
+    // TODO (danrubel) suggest HtmlElement as low relevance
+    assertNotSuggested('HtmlElement');
+  }
+
+  test_Block_inherited_imported() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // TODO (danrubel) prefer fields over getters
+    // If add `get e1;` to interface I
+    // then suggestions include getter e1 rather than field e1
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    //assertNotSuggested('m2');
+    assertNotSuggested('==');
+  }
+
+  test_Block_inherited_local() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+        class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+        class E extends F { var e1; e2() { } }
+        class I { int i1; i2() { } }
+        class M { var m1; int m2() { } }
+        class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e1');
+    assertNotSuggested('f1');
+    assertNotSuggested('i1');
+    assertNotSuggested('m1');
+    assertNotSuggested('f3');
+    assertNotSuggested('f4');
+    assertNotSuggested('e2');
+    assertNotSuggested('f2');
+    assertNotSuggested('i2');
+    assertNotSuggested('m2');
+  }
+
+  test_Block_local_function() async {
+    addSource(
+        '/testAB.dart',
+        '''
+        export "dart:math" hide max;
+        class A {int x;}
+        @deprecated D1() {int x;}
+        class _B {boo() { partBoo() {}} }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        String T1;
+        var _T2;
+        class C { }
+        class D { }''');
+    addSource(
+        '/testEEF.dart',
+        '''
+        class EE { }
+        class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource(
+        '/testH.dart',
+        '''
+        class H { }
+        int T3;
+        var _T4;'''); // not imported
+    addTestSource('''
+        import "/testAB.dart";
+        import "/testCD.dart" hide D;
+        import "/testEEF.dart" show EE;
+        import "/testG.dart" as g;
+        int T5;
+        var _T6;
+        String get T7 => 'hello';
+        set T8(int value) { partT8() {} }
+        Z D2() {int x;}
+        class X {
+          int get clog => 8;
+          set blog(value) { }
+          a() {
+            var f;
+            localF(int arg1) { }
+            {var x;}
+            p^ var r;
+          }
+          void b() { }}
+        class Z { }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('partT8');
+    assertNotSuggested('partBoo');
+    assertNotSuggested('parseIPv6Address');
+    assertNotSuggested('parseHex');
+  }
+
+  test_Block_unimported() async {
+    addPackageSource('myBar', 'bar.dart', 'class Foo2 { Foo2() { } }');
+    addSource(
+        '/proj/testAB.dart', 'import "package:myBar/bar.dart"; class Foo { }');
+    testFile = '/proj/completionTest.dart';
+    addTestSource('class C {foo(){F^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Foo');
+    // TODO(danrubel) implement
+    assertNotSuggested('Foo2');
+    assertNotSuggested('Future');
+  }
+
+  test_CascadeExpression_method1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        // looks like a cascade to the parser
+        // but the user is trying to get completions for a non-cascade
+        main() {A a; a.^.z()}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector1() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        // looks like a cascade to the parser
+        // but the user is trying to get completions for a non-cascade
+        main() {A a; a.^.z}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2() async {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^z}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() async {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "/testB.dart";
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a..^ return}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('X');
+    assertNotSuggested('z');
+    assertNotSuggested('==');
+  }
+
+  test_CascadeExpression_target() async {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('''
+        class A {var b; X _c;}
+        class X{}
+        main() {A a; a^..b}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_CatchClause_onType() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^ {}}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_onType_noBrackets() async {
+    // TypeName  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on ^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_typed() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_CatchClause_untyped() async {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('e');
+    assertNotSuggested('s');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        @deprecated class A {^}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ A(){}}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_field2() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as Soo;
+        class A {final S^ A();}
+        class _B {}
+        A Sew;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('String');
+    assertNotSuggested('Sew');
+    assertNotSuggested('Soo');
+  }
+
+  test_ClassDeclaration_body_final_final() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ final foo;}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_ClassDeclaration_body_final_var() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testB.dart',
+        '''
+        class B { }''');
+    addTestSource('''
+        import "testB.dart" as x;
+        class A {final ^ var foo;}
+        class _B {}
+        A T;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('_B');
+    assertNotSuggested('Object');
+    assertNotSuggested('T');
+    assertNotSuggested('x');
+  }
+
+  test_Combinator_hide() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" hide ^;
+        import "/testCD.dart";
+        class X {}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_Combinator_show() async {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addSource(
+        '/testAB.dart',
+        '''
+        library libAB;
+        part '/partAB.dart';
+        class A { }
+        class B { }''');
+    addSource(
+        '/partAB.dart',
+        '''
+        part of libAB;
+        var T1;
+        PB F1() => new PB();
+        typedef PB2 F2(int blat);
+        class Clz = Object with Object;
+        class PB { }''');
+    addSource(
+        '/testCD.dart',
+        '''
+        class C { }
+        class D { }''');
+    addTestSource('''
+        import "/testAB.dart" show ^;
+        import "/testCD.dart";
+        class X {}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ConditionalExpression_elseExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : T^}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_elseExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T1 : ^}}''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_partial_thenExpression_empty() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? ^}}''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConditionalExpression_thenExpression() async {
+    // SimpleIdentifier  ConditionalExpression  ReturnStatement
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} return a ? T^ : c}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_ConstructorName_importedClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        var m;
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_importedFactory2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        main() {new String.fr^omCharCodes([]);}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 13);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('fromCharCodes');
+    assertNotSuggested('isEmpty');
+    assertNotSuggested('isNotEmpty');
+    assertNotSuggested('length');
+    assertNotSuggested('Object');
+    assertNotSuggested('String');
+  }
+
+  test_ConstructorName_localClass() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_ConstructorName_localFactory() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+        int T1;
+        F1() { }
+        class X {factory X.c(); factory X._d(); z() {}}
+        main() {new X.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by NamedConstructorContributor
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_DefaultFormalParameter_named_expression() async {
+    // DefaultFormalParameter FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(blat: ^) { }}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ExpressionStatement_identifier() async {
+    // SimpleIdentifier  ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        _B F1() { }
+        class A {int x;}
+        class _B { }''');
+    addTestSource('''
+        import "/testA.dart";
+        typedef int F2(int blat);
+        class Clz = Object with Object;
+        class C {foo(){^} void bar() {}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('C');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('F2');
+    assertNotSuggested('Clz');
+    assertNotSuggested('C');
+    assertNotSuggested('x');
+    assertNotSuggested('_B');
+  }
+
+  test_ExpressionStatement_name() async {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        B T1;
+        class B{}''');
+    addTestSource('''
+        import "/testA.dart";
+        class C {a() {C ^}}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_typed() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {A ^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldDeclaration_name_var() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addSource('/testA.dart', 'class A { }');
+    addTestSource('''
+        import "/testA.dart";
+        class C {var ^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_FieldFormalParameter_in_non_constructor() async {
+    // SimpleIdentifer  FieldFormalParameter  FormalParameterList
+    addTestSource('class A {B(this.^foo) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 3);
+    assertNoSuggestions();
+  }
+
+  test_ForEachStatement_body_typed() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_body_untyped() async {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_iterable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (int foo in ^) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('Object');
+  }
+
+  test_ForEachStatement_loopVariable() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ in args) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type() async {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (^ foo in args) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_ForEachStatement_loopVariable_type2() async {
+    // DeclaredIdentifier  ForEachStatement  Block
+    addTestSource('main(args) {for (S^ foo in args) {}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('args');
+    assertNotSuggested('foo');
+    assertNotSuggested('String');
+  }
+
+  test_FormalParameterList() async {
+    // FormalParameterList MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {a(^) { }}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('String');
+    assertNotSuggested('identical');
+    assertNotSuggested('bar');
+  }
+
+  test_ForStatement_body() async {
+    // Block  ForStatement
+    addTestSource('main(args) {for (int i; i < 10; ++i) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('i');
+    assertNotSuggested('Object');
+  }
+
+  test_ForStatement_condition() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_initializer() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('int');
+  }
+
+  test_ForStatement_updaters() async {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+  }
+
+  test_ForStatement_updaters_prefix_expression() async {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('''
+        void bar() { }
+        main() {for (int index = 0; index < 10; ++i^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('index');
+    assertNotSuggested('main');
+    assertNotSuggested('bar');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /* */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment2() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        /** */ ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionDeclaration_returnType_afterComment3() async {
+    // FunctionDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        /// some dartdoc
+        class C2 { }
+        ^ zoo(z) { } String name;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_FunctionExpression_body_function() async {
+    // Block  BlockFunctionBody  FunctionExpression
+    addTestSource('''
+        void bar() { }
+        String foo(List args) {x.then((R b) {^}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('args');
+    assertNotSuggested('b');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (true) ^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_condition() async {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IfStatement_empty() async {
+    // SimpleIdentifier  IfStatement
+    addTestSource('''
+        class A {var b; X _c; foo() {A a; if (^) something}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_IfStatement_invocation() async {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+        main() {var a; if (a.^) something}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestMethod('toString', 'Object', 'String');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_ImportDirective_dart() async {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+        import "dart^";
+        main() {}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_IndexExpression() async {
+    // ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[^]}}''');
+    await computeSuggestions();
+    assertNotSuggested('x');
+    assertNotSuggested('f');
+    assertNotSuggested('foo');
+    assertNotSuggested('C');
+    assertNotSuggested('F2');
+    assertNotSuggested('T2');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_IndexExpression2() async {
+    // SimpleIdentifier IndexExpression ExpressionStatement  Block
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        class B {int x;}
+        class C {foo(){var f; {var x;} f[T^]}}''');
+    await computeSuggestions();
+    // top level results are partially filtered based on first char
+    assertNotSuggested('T2');
+    // TODO (danrubel) getter is being suggested instead of top level var
+    //assertSuggestImportedTopLevelVar('T1', 'int');
+  }
+
+  test_InstanceCreationExpression_imported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        class A {A(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        import "dart:async";
+        int T2;
+        F2() { }
+        class B {B(this.x, [String boo]) { } int x;}
+        class C {foo(){var f; {var x;} new ^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('Future');
+    assertNotSuggested('A');
+    assertNotSuggested('B');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('foo');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+  }
+
+  test_InstanceCreationExpression_unimported() async {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){new F^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('Future');
+    assertNotSuggested('Foo');
+  }
+
+  test_InterpolationExpression() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \$^");}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    // TODO(danrubel) should return top level var rather than getter
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        main() {String name; print("hello \${^}");}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_InterpolationExpression_block2() async {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+  }
+
+  test_InterpolationExpression_prefix_selector() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('length', 'int');
+    assertNotSuggested('name');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_InterpolationExpression_prefix_selector2() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \$name.^");}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_InterpolationExpression_prefix_target() async {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    await computeSuggestions();
+    assertNotSuggested('name');
+    // top level results are partially filtered
+    //assertNotSuggested('Object');
+    assertNotSuggested('length');
+  }
+
+  test_IsExpression() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var x; if (x is ^) { }}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('x');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+  }
+
+  test_IsExpression_target() async {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {int x; int y() => 0;}
+        main(){var a; if (^ is A)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is ^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_IsExpression_type_partial() async {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+        class A {int x; int y() => 0;}
+        main(){var a; if (a is Obj^)}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('a');
+    assertNotSuggested('main');
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+  }
+
+  test_keyword2() async {
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int newT1;
+        int T1;
+        nowIsIt() { }
+        class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        String newer() {}
+        var m;
+        main() {new^ X.c();}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('c');
+    assertNotSuggested('_d');
+    // Imported suggestion are filtered by 1st character
+    assertNotSuggested('nowIsIt');
+    assertNotSuggested('T1');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+    assertNotSuggested('newer');
+  }
+
+  test_Literal_list() async {
+    // ']'  ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([^]);}');
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_list2() async {
+    // SimpleIdentifier ListLiteral  ArgumentList  MethodInvocation
+    addTestSource('main() {var Some; print([S^]);}');
+    await computeSuggestions();
+    assertNotSuggested('Some');
+    assertNotSuggested('String');
+  }
+
+  test_Literal_string() async {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_MapLiteralEntry() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {^''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+  }
+
+  test_MapLiteralEntry1() async {
+    // MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {T^''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T2');
+  }
+
+  test_MapLiteralEntry2() async {
+    // SimpleIdentifier  MapLiteralEntry  MapLiteral  VariableDeclaration
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 { }
+        foo = {7:T^};''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('T2');
+  }
+
+  test_MethodDeclaration_body_getters() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X get f => 0; Z a() {^} get _g => 1;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+  }
+
+  test_MethodDeclaration_body_static() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addSource(
+        '/testC.dart',
+        '''
+        class C {
+          c1() {}
+          var c2;
+          static c3() {}
+          static var c4;}''');
+    addTestSource('''
+        import "/testC.dart";
+        class B extends C {
+          b1() {}
+          var b2;
+          static b3() {}
+          static var b4;}
+        class A extends B {
+          a1() {}
+          var a2;
+          static a3() {}
+          static var a4;
+          static a() {^}}''');
+    await computeSuggestions();
+    assertNotSuggested('a1');
+    assertNotSuggested('a2');
+    assertNotSuggested('a3');
+    assertNotSuggested('a4');
+    assertNotSuggested('b1');
+    assertNotSuggested('b2');
+    assertNotSuggested('b3');
+    assertNotSuggested('b4');
+    assertNotSuggested('c1');
+    assertNotSuggested('c2');
+    assertNotSuggested('c3');
+    assertNotSuggested('c4');
+  }
+
+  test_MethodDeclaration_members() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated X f; Z _a() {^} var _g;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('_a');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('bool');
+  }
+
+  test_MethodDeclaration_parameters_named() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {@deprecated Z a(X x, _, b, {y: boo}) {^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('b');
+    assertNotSuggested('int');
+    assertNotSuggested('_');
+  }
+
+  test_MethodDeclaration_parameters_positional() async {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+        foo() { }
+        void bar() { }
+        class A {Z a(X x, [int y=1]) {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('a');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('String');
+  }
+
+  test_MethodDeclaration_returnType() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment() async {
+    // ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/* */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {/** */ ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodDeclaration_returnType_afterComment3() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addSource(
+        '/testA.dart',
+        '''
+        int T1;
+        F1() { }
+        typedef D1();
+        class C1 {C1(this.x) { } int x;}''');
+    addTestSource('''
+        import "/testA.dart";
+        int T2;
+        F2() { }
+        typedef D2();
+        class C2 {
+          /// some dartdoc
+          ^ zoo(z) { } String name; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('T1');
+    assertNotSuggested('F1');
+    assertNotSuggested('D1');
+    assertNotSuggested('C1');
+    assertNotSuggested('T2');
+    assertNotSuggested('F2');
+    assertNotSuggested('D2');
+    assertNotSuggested('C2');
+    assertNotSuggested('name');
+  }
+
+  test_MethodInvocation_no_semicolon() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {x.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_new_instance() async {
+    addTestSource('import "dart:math"; class A {x() {new Random().^}}');
+    await computeSuggestions();
+    assertSuggestMethod('nextBool', 'Random', 'bool');
+    assertSuggestMethod('nextDouble', 'Random', 'double');
+    assertSuggestMethod('nextInt', 'Random', 'int');
+    assertNotSuggested('Random');
+    assertNotSuggested('Object');
+    assertNotSuggested('A');
+  }
+
+  test_parameterName_excludeTypes() async {
+    addTestSource('m(int ^) {}');
+    await computeSuggestions();
+    assertNotSuggested('int');
+    assertNotSuggested('bool');
+  }
+
+  test_partFile_TypeName() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        library libA;
+        import "/testB.dart";
+        part "$testFile";
+        class A { }
+        var m;''');
+    addTestSource('''
+        part of libA;
+        class B { factory B.bar(int x) => null; }
+        main() {new ^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('B.bar');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('A');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_partFile_TypeName2() async {
+    // SimpleIdentifier  TypeName  ConstructorName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        int T1;
+        F1() { }
+        class X {X.c(); X._d(); z() {}}''');
+    addSource(
+        '/testA.dart',
+        '''
+        part of libA;
+        class B { }''');
+    addTestSource('''
+        library libA;
+        import "/testB.dart";
+        part "/testA.dart";
+        class A { A({String boo: 'hoo'}) { } }
+        main() {new ^}
+        var m;''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertNotSuggested('X.c');
+    assertNotSuggested('X._d');
+    assertNotSuggested('B');
+    assertNotSuggested('F1');
+    assertNotSuggested('T1');
+    assertNotSuggested('_d');
+    assertNotSuggested('z');
+    assertNotSuggested('m');
+  }
+
+  test_PrefixedIdentifier_class_const() async {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {
+          static const scI = 'boo';
+          X get f => new A();
+          get _g => new A();}
+        class B implements I {
+          static const int scB = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        class A extends B {
+          static const String scA = 'foo';
+          w() { }}
+        main() {A.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by StaticMemberContributor
+    assertNotSuggested('scA');
+    assertNotSuggested('scB');
+    assertNotSuggested('scI');
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('w');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_imported() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          @deprecated var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    addTestSource('''
+        import "/testB.dart";
+        main() {A a; a.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertSuggestField('b', null, isDeprecated: true);
+    assertNotSuggested('_c');
+    assertSuggestGetter('d', 'X');
+    assertNotSuggested('_e');
+    assertSuggestGetter('f', 'X');
+    assertNotSuggested('_g');
+    assertSuggestSetter('s1');
+    assertNotSuggested('_s2');
+    assertSuggestMethod('m', 'A', null);
+    assertNotSuggested('_n');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_class_local() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('''
+        main() {A a; a.^}
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          static const int sc = 12;
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          set s1(I x) {} set _s2(I x) {}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('sc');
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertSuggestGetter('d', 'X');
+    assertSuggestGetter('_e', null);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertSuggestSetter('s1');
+    assertSuggestSetter('_s2');
+    assertSuggestMethod('m', 'A', null);
+    assertSuggestMethod('_n', 'A', 'I');
+    assertNotSuggested('a');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_library() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        main() {b.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^ f) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_library_typesOnly2() async {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        var T1;
+        class X { }
+        class Y { }''');
+    addTestSource('''
+        import "/testB.dart" as b;
+        var T2;
+        class A { }
+        foo(b.^) {}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Suggested by LibraryMemberContributor
+    assertNotSuggested('X');
+    assertNotSuggested('Y');
+    assertNotSuggested('T1');
+    assertNotSuggested('T2');
+    assertNotSuggested('Object');
+    assertNotSuggested('b');
+    assertNotSuggested('A');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_parameter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        class _W {M y; var _z;}
+        class X extends _W {}
+        class M{}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo(X x) {x.^}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('y', 'M');
+    assertNotSuggested('_z');
+    assertNotSuggested('==');
+  }
+
+  test_PrefixedIdentifier_prefix() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class A {static int bar = 10;}
+        _B() {}''');
+    addTestSource('''
+        import "/testA.dart";
+        class X {foo(){A^.bar}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('foo');
+    assertNotSuggested('bar');
+    assertNotSuggested('_B');
+  }
+
+  test_PrefixedIdentifier_propertyAccess() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('isEmpty', 'bool');
+    assertSuggestMethod('compareTo', 'Comparable', 'int');
+  }
+
+  test_PrefixedIdentifier_propertyAccess_newStmt() async {
+    // PrefixedIdentifier  ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('class A {String x; int get foo {x.^ int y = 0;}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('isEmpty', 'bool');
+    assertSuggestMethod('compareTo', 'Comparable', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_const() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('const String g = "hello"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_field() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_function() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g() => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_functionTypeAlias() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('typedef String g(); f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_getter() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String get g => "one"; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_typed() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {String g; g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_local_untyped() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f() {var g = "hello"; g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_method() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {String g() {}; f() {g.^ int y = 0;}}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class A {f(String g) {g.^ int y = 0;}}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_localVariableDeclarationName() async {
+    addTestSource('main() {String m^}');
+    await computeSuggestions();
+    assertNotSuggested('main');
+    assertNotSuggested('min');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_param2() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('f(String g) {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PrefixedIdentifier_trailingStmt_topLevelVar() async {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('String g; f() {g.^ int y = 0;}');
+    await computeSuggestions();
+    assertSuggestGetter('length', 'int');
+  }
+
+  test_PropertyAccess_expression() async {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 2);
+    expect(replacementLength, 8);
+    assertSuggestGetter('length', 'int');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_PropertyAccess_noTarget() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('class C {foo(){.^}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_noTarget2() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement
+    addSource('/testAB.dart', 'class Foo { }');
+    addTestSource('main() {.^}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_PropertyAccess_selector() async {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestGetter('isEven', 'bool');
+    assertNotSuggested('A');
+    assertNotSuggested('a');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_SwitchStatement_c() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_SwitchStatement_case() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {var t; switch(x) {case 0: ^}}}');
+    await computeSuggestions();
+    assertNotSuggested('A');
+    assertNotSuggested('g');
+    assertNotSuggested('t');
+    assertNotSuggested('String');
+  }
+
+  test_SwitchStatement_empty() async {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_ThisExpression_block() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {this.^ m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertSuggestGetter('d', 'X');
+    assertSuggestGetter('_e', null);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertSuggestMethod('m', 'A', null);
+    assertSuggestMethod('_n', 'A', 'I');
+    assertSuggestSetter('s1');
+    assertSuggestSetter('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor() async {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A() {this.^}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('b', null);
+    assertSuggestField('_c', 'X');
+    assertSuggestGetter('d', 'X');
+    assertSuggestGetter('_e', null);
+    assertSuggestGetter('f', 'X');
+    assertSuggestGetter('_g', null);
+    assertSuggestMethod('m', 'A', null);
+    assertSuggestMethod('_n', 'A', 'I');
+    assertSuggestSetter('s1');
+    assertSuggestSetter('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^) {}
+          A.z() {}
+          var b; X _c; static sb;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('sb');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param2() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param3() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.^b) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 1);
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('b');
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_ThisExpression_constructor_param4() async {
+    // SimpleIdentifier  FieldFormalParameter  FormalParameterList
+    addTestSource('''
+        main() { }
+        class I {X get f => new A();get _g => new A();}
+        class A implements I {
+          A(this.b, this.^) {}
+          A.z() {}
+          var b; X _c;
+          X get d => new A();get _e => new A();
+          // no semicolon between completion point and next statement
+          set s1(I x) {} set _s2(I x) {m(null);}
+          m(X x) {} I _n(X x) {}}
+        class X{}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('b');
+    // Contributed by FieldFormalConstructorContributor
+    assertNotSuggested('_c');
+    assertNotSuggested('d');
+    assertNotSuggested('_e');
+    assertNotSuggested('f');
+    assertNotSuggested('_g');
+    assertNotSuggested('m');
+    assertNotSuggested('_n');
+    assertNotSuggested('s1');
+    assertNotSuggested('_s2');
+    assertNotSuggested('z');
+    assertNotSuggested('I');
+    assertNotSuggested('A');
+    assertNotSuggested('X');
+    assertNotSuggested('Object');
+    assertNotSuggested('==');
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_TypeArgumentList() async {
+    // SimpleIdentifier  BinaryExpression  ExpressionStatement
+    addSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<^> c; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertNotSuggested('C1');
+    assertNotSuggested('T1');
+    assertNotSuggested('C2');
+    assertNotSuggested('T2');
+    assertNotSuggested('F1');
+    assertNotSuggested('F2');
+  }
+
+  test_TypeArgumentList2() async {
+    // TypeName  TypeArgumentList  TypeName
+    addSource(
+        '/testA.dart',
+        '''
+        class C1 {int x;}
+        F1() => 0;
+        typedef String T1(int blat);''');
+    addTestSource('''
+        import "/testA.dart";'
+        class C2 {int x;}
+        F2() => 0;
+        typedef int T2(int blat);
+        class C<E> {}
+        main() { C<C^> c; }''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 1);
+    expect(replacementLength, 1);
+    assertNotSuggested('C1');
+    assertNotSuggested('C2');
+  }
+
+  test_VariableDeclaration_name() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        main() {var ^}''');
+    await computeSuggestions();
+    assertNoSuggestions();
+  }
+
+  test_VariableDeclarationList_final() async {
+    // VariableDeclarationList  VariableDeclarationStatement  Block
+    addTestSource('main() {final ^} class C { }');
+    await computeSuggestions();
+    assertNotSuggested('Object');
+    assertNotSuggested('C');
+    assertNotSuggested('==');
+  }
+
+  test_VariableDeclarationStatement_RHS() async {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() async {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addSource(
+        '/testB.dart',
+        '''
+        lib B;
+        foo1() { }
+        void bar1() { }
+        class _B { }
+        class X {X.c(); X._d(); z() {}}''');
+    addTestSource('''
+        import "/testB.dart";
+        foo2() { }
+        void bar2() { }
+        class Y {Y.c(); Y._d(); z() {}}
+        class C {bar(){var f; {var x;} var e = ^ var g}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('X');
+    assertNotSuggested('foo1');
+    assertNotSuggested('bar1');
+    assertNotSuggested('foo2');
+    assertNotSuggested('bar2');
+    assertNotSuggested('_B');
+    assertNotSuggested('Y');
+    assertNotSuggested('C');
+    assertNotSuggested('f');
+    assertNotSuggested('x');
+    assertNotSuggested('e');
+  }
+}
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index e6c2384..f120744 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -173,11 +173,32 @@
     assertNotSuggested('../blat.dart');
   }
 
+  test_import_file_outside_lib() async {
+    testFile = '/proj/lib/completion.dart';
+    addSource('/proj/lib/other.dart', 'library other;');
+    addSource('/proj/lib/foo/bar.dart', 'library bar;');
+    addSource('/proj/blat.dart', 'library blat;');
+    addSource('/proj/bin/boo.dart', 'library boo;');
+    addTestSource('import "../^" import');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset - 3);
+    expect(replacementLength, 3);
+    assertNotSuggested('completion.dart');
+    assertNotSuggested('other.dart');
+    assertNotSuggested('foo');
+    assertNotSuggested('foo/');
+    assertNotSuggested('foo/bar.dart');
+    assertNotSuggested('../bin');
+    assertNotSuggested('../bin/');
+    assertNotSuggested('../blat.dart');
+  }
+
   test_import_file_parent() async {
     testFile = '/proj/completion.dart';
     addSource('/proj/other.dart', 'library other;');
     addSource('/proj/foo/bar.dart', 'library bar;');
     addSource('/blat.dart', 'library blat;');
+    addSource('/proj2/boo.dart', 'library boo;');
     addTestSource('import "../^" import');
     await computeSuggestions();
     expect(replacementOffset, completionOffset - 3);
@@ -188,6 +209,7 @@
     assertNotSuggested('foo/');
     assertNotSuggested('foo/bar.dart');
     assertSuggest('../blat.dart', csKind: CompletionSuggestionKind.IMPORT);
+    assertSuggest('../proj2/', csKind: CompletionSuggestionKind.IMPORT);
   }
 
   test_import_file_parent2() async {
diff --git a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
index 54ad5e1..fb91d76 100644
--- a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
@@ -4,8 +4,6 @@
 
 library test.services.completion.toplevel;
 
-import 'package:analysis_server/plugin/protocol/protocol.dart' as protocol
-    show Element, ElementKind;
 import 'package:analysis_server/plugin/protocol/protocol.dart'
     hide Element, ElementKind;
 import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
@@ -33,7 +31,6 @@
     DartCompletionCache cache = request.cache;
     if (!isCached(cache.importedTypeSuggestions, completion) &&
         !isCached(cache.importedVoidReturnSuggestions, completion) &&
-        !isCached(cache.libraryPrefixSuggestions, completion) &&
         !isCached(cache.otherImportedSuggestions, completion)) {
       fail('expected $completion to be cached');
     }
@@ -116,7 +113,6 @@
     DartCompletionCache cache = request.cache;
     if (isCached(cache.importedTypeSuggestions, completion) ||
         isCached(cache.importedVoidReturnSuggestions, completion) ||
-        isCached(cache.libraryPrefixSuggestions, completion) ||
         isCached(cache.otherImportedSuggestions, completion)) {
       fail('expected $completion NOT to be cached');
     }
@@ -203,21 +199,6 @@
         name, returnType, relevance, kind, importUri);
   }
 
-  @override
-  CompletionSuggestion assertSuggestLibraryPrefix(String prefix,
-      [int relevance = DART_RELEVANCE_DEFAULT,
-      CompletionSuggestionKind kind = CompletionSuggestionKind.INVOCATION]) {
-    CompletionSuggestion cs =
-        assertSuggest(prefix, csKind: kind, relevance: relevance);
-    protocol.Element element = cs.element;
-    expect(element, isNotNull);
-    expect(element.kind, equals(protocol.ElementKind.LIBRARY));
-    expect(element.parameters, isNull);
-    expect(element.returnType, isNull);
-    assertHasNoParameterInfo(cs);
-    return cs;
-  }
-
   fail_enum_deprecated() {
     addSource('/libA.dart', 'library A; @deprecated enum E { one, two }');
     addTestSource('import "/libA.dart"; main() {^}');
@@ -257,6 +238,13 @@
     });
   }
 
+  test_Assert() {
+    addTestSource('main() {assert(^)}');
+    return computeFull((bool result) {
+      assertSuggestClass('String');
+    });
+  }
+
   @override
   test_AssignmentExpression_RHS() {
     return super.test_AssignmentExpression_RHS().then((_) {
@@ -545,7 +533,8 @@
       expect(suggestion.requiredParameterCount, 0);
       expect(suggestion.hasNamedParameters, true);
 
-      assertSuggestLibraryPrefix('math');
+      // Suggested by LibraryPrefixContributor
+      assertNotSuggested('math');
     });
   }
 
diff --git a/pkg/analysis_server/test/services/completion/optype_test.dart b/pkg/analysis_server/test/services/completion/optype_test.dart
index 94b5daf..179b09b 100644
--- a/pkg/analysis_server/test/services/completion/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/optype_test.dart
@@ -9,6 +9,7 @@
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:plugin/manager.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -67,6 +68,15 @@
     expect(visitor.isPrefixed, prefixed, reason: 'prefixed');
   }
 
+  void processRequiredPlugins() {
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
+  }
+
+  void setUp() {
+    processRequiredPlugins();
+  }
+
   test_Annotation() {
     // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
     addTestSource('class C { @A^ }');
@@ -98,6 +108,11 @@
     assertOpType(typeNames: true);
   }
 
+  test_Assert() {
+    addTestSource('main() {assert(^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
   test_AssignmentExpression_name() {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
diff --git a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart b/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
deleted file mode 100644
index 6e15a0c..0000000
--- a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
+++ /dev/null
@@ -1,675 +0,0 @@
-// 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 test.services.completion.invocation;
-
-import 'dart:async';
-
-import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
-import 'package:analysis_server/src/services/completion/prefixed_element_contributor.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
-import 'completion_test_util.dart';
-
-main() {
-  initializeTestEnvironment();
-  defineReflectiveTests(PrefixedElementContributorTest);
-}
-
-@reflectiveTest
-class PrefixedElementContributorTest extends AbstractSelectorSuggestionTest {
-  @override
-  CompletionSuggestion assertSuggestInvocationField(String name, String type,
-      {int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
-    return assertSuggestField(name, type,
-        relevance: relevance, isDeprecated: isDeprecated);
-  }
-
-  /**
-   * Check whether a declaration of the form [shadower] in a derived class
-   * shadows a declaration of the form [shadowee] in a base class, for the
-   * purposes of what is shown during completion.  [shouldBeShadowed] indicates
-   * whether shadowing is expected.
-   */
-  Future check_shadowing(
-      String shadower, String shadowee, bool shouldBeShadowed) {
-    addTestSource('''
-class Base {
-  $shadowee
-}
-class Derived extends Base {
-  $shadower
-}
-void f(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      List<CompletionSuggestion> suggestionsForX = request.suggestions
-          .where((CompletionSuggestion s) => s.completion == 'x')
-          .toList();
-      if (shouldBeShadowed) {
-        expect(suggestionsForX, hasLength(1));
-        expect(suggestionsForX[0].declaringType, 'Derived');
-      } else {
-        expect(suggestionsForX, hasLength(2));
-      }
-    });
-  }
-
-  fail_enumConst_deprecated() {
-    addTestSource('@deprecated enum E { one, two } main() {E.^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      // TODO(danrubel) Investigate why enum suggestion is not marked
-      // as deprecated if enum ast element is deprecated
-      assertSuggestEnumConst('one', isDeprecated: true);
-      assertSuggestEnumConst('two', isDeprecated: true);
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>', isDeprecated: true);
-    });
-  }
-
-  fail_test_PrefixedIdentifier_trailingStmt_const_untyped() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('const g = "hello"; f() {g.^ int y = 0;}');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestInvocationGetter('length', 'int');
-    });
-  }
-
-  @override
-  void setUpContributor() {
-    contributor = new PrefixedElementContributor();
-  }
-
-  test_enumConst() {
-    addTestSource('enum E { one, two } main() {E.^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertSuggestEnumConst('one');
-      assertSuggestEnumConst('two');
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>');
-    });
-  }
-
-  test_enumConst2() {
-    addTestSource('enum E { one, two } main() {E.o^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertSuggestEnumConst('one');
-      assertSuggestEnumConst('two');
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>');
-    });
-  }
-
-  test_enumConst3() {
-    addTestSource('enum E { one, two } main() {E.^ int g;}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertSuggestEnumConst('one');
-      assertSuggestEnumConst('two');
-      assertNotSuggested('index');
-      assertSuggestField('values', 'List<E>');
-    });
-  }
-
-  test_enumConst_index() {
-    addTestSource('enum E { one, two } main() {E.one.^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-      assertSuggestField('index', 'int');
-      assertNotSuggested('values');
-    });
-  }
-
-  test_enumConst_index2() {
-    addTestSource('enum E { one, two } main() {E.one.i^}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-      assertSuggestField('index', 'int');
-      assertNotSuggested('values');
-    });
-  }
-
-  test_enumConst_index3() {
-    addTestSource('enum E { one, two } main() {E.one.^ int g;}');
-    return computeFull((bool result) {
-      assertNotSuggested('E');
-      assertNotSuggested('one');
-      assertNotSuggested('two');
-      assertSuggestField('index', 'int');
-      assertNotSuggested('values');
-    });
-  }
-
-  test_generic_field() {
-    addTestSource('''
-class C<T> {
-  T t;
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestField('t', 'int');
-    });
-  }
-
-  test_generic_getter() {
-    addTestSource('''
-class C<T> {
-  T get t => null;
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestGetter('t', 'int');
-    });
-  }
-
-  test_generic_method() {
-    addTestSource('''
-class C<T> {
-  T m(T t) {}
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'int');
-      expect(suggestion.parameterTypes[0], 'int');
-      expect(suggestion.element.returnType, 'int');
-      expect(suggestion.element.parameters, '(int t)');
-    });
-  }
-
-  test_generic_setter() {
-    addTestSource('''
-class C<T> {
-  set t(T value) {}
-}
-void f(C<int> c) {
-  c.^
-}
-''');
-    return computeFull((bool result) {
-      // TODO(paulberry): modify assertSuggestSetter so that we can pass 'int'
-      // as a parmeter to it, and it will check the appropriate field in
-      // the suggestion object.
-      CompletionSuggestion suggestion = assertSuggestSetter('t');
-      expect(suggestion.element.parameters, '(int value)');
-    });
-  }
-
-  test_keyword() {
-    addTestSource('class C { static C get instance => null; } main() {C.in^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('instance', 'C');
-    });
-  }
-
-  test_libraryPrefix() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('import "dart:async" as bar; foo() {bar.^}');
-    return computeFull((bool result) {
-      assertSuggestClass('Future');
-      assertNotSuggested('loadLibrary');
-    });
-  }
-
-  test_libraryPrefix2() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('import "dart:async" as bar; foo() {bar.^ print("f")}');
-    return computeFull((bool result) {
-      assertSuggestClass('Future');
-    });
-  }
-
-  test_libraryPrefix3() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('import "dart:async" as bar; foo() {new bar.F^ print("f")}');
-    return computeFull((bool result) {
-      assertSuggestConstructor('Future');
-      assertSuggestConstructor('Future.delayed');
-    });
-  }
-
-  test_libraryPrefix_deferred() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
-    return computeFull((bool result) {
-      assertSuggestClass('Future');
-      assertSuggestFunction('loadLibrary', 'Future<dynamic>');
-    });
-  }
-
-  test_libraryPrefix_with_exports() {
-    addSource('/libA.dart', 'library libA; class A { }');
-    addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
-    addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
-    computeFast();
-    return computeFull((bool result) {
-      assertSuggestClass('B');
-      assertSuggestClass('A');
-    });
-  }
-
-  test_local() {
-    addTestSource('foo() {String x = "bar"; x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_local_is() {
-    addTestSource('foo() {var x; if (x is String) x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_local_propogatedType() {
-    addTestSource('foo() {var x = "bar"; x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_method_parameters_mixed_required_and_named() {
-    addTestSource('''
-class C {
-  void m(x, {int y}) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_mixed_required_and_positional() {
-    addTestSource('''
-class C {
-  void m(x, [int y]) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 1);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_named() {
-    addTestSource('''
-class C {
-  void m({x, int y}) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, true);
-    });
-  }
-
-  test_method_parameters_none() {
-    addTestSource('''
-class C {
-  void m() {}
-}
-void main() {new C().^}''');
-    computeFast();
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, isEmpty);
-      expect(suggestion.parameterTypes, isEmpty);
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_positional() {
-    addTestSource('''
-class C {
-  void m([x, int y]) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 0);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_method_parameters_required() {
-    addTestSource('''
-class C {
-  void m(x, int y) {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestMethod('m', 'C', 'void');
-      expect(suggestion.parameterNames, hasLength(2));
-      expect(suggestion.parameterNames[0], 'x');
-      expect(suggestion.parameterTypes[0], 'dynamic');
-      expect(suggestion.parameterNames[1], 'y');
-      expect(suggestion.parameterTypes[1], 'int');
-      expect(suggestion.requiredParameterCount, 2);
-      expect(suggestion.hasNamedParameters, false);
-    });
-  }
-
-  test_no_parameters_field() {
-    addTestSource('''
-class C {
-  int x;
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestField('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_getter() {
-    addTestSource('''
-class C {
-  int get x => null;
-}
-void main() {int y = new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestGetter('x', 'int');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_no_parameters_setter() {
-    addTestSource('''
-class C {
-  set x(int value) {};
-}
-void main() {int y = new C().^}''');
-    return computeFull((bool result) {
-      CompletionSuggestion suggestion = assertSuggestSetter('x');
-      assertHasNoParameterInfo(suggestion);
-    });
-  }
-
-  test_only_instance() {
-    // SimpleIdentifier  PropertyAccess  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {new C().^}''');
-    return computeFull((bool result) {
-      assertSuggestInvocationField('f1', 'int');
-      assertNotSuggested('f2');
-      assertSuggestMethod('m1', 'C', null);
-      assertNotSuggested('m2');
-    });
-  }
-
-  test_only_instance2() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {new C().^ print("something");}''');
-    return computeFull((bool result) {
-      assertSuggestInvocationField('f1', 'int');
-      assertNotSuggested('f2');
-      assertSuggestMethod('m1', 'C', null);
-      assertNotSuggested('m2');
-    });
-  }
-
-  test_only_static() {
-    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {C.^}''');
-    return computeFull((bool result) {
-      assertNotSuggested('f1');
-      assertSuggestInvocationField('f2', 'int');
-      assertNotSuggested('m1');
-      assertSuggestMethod('m2', 'C', null);
-    });
-  }
-
-  test_only_static2() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('''
-class C {
-  int f1;
-  static int f2;
-  m1() {}
-  static m2() {}
-}
-void main() {C.^ print("something");}''');
-    return computeFull((bool result) {
-      assertNotSuggested('f1');
-      assertSuggestInvocationField('f2', 'int');
-      assertNotSuggested('m1');
-      assertSuggestMethod('m2', 'C', null);
-    });
-  }
-
-  test_param() {
-    addTestSource('foo(String x) {x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_param_is() {
-    addTestSource('foo(x) {if (x is String) x.^}');
-    return computeFull((bool result) {
-      assertSuggestGetter('length', 'int');
-    });
-  }
-
-  test_shadowing_field_over_field() =>
-      check_shadowing('int x;', 'int x;', true);
-
-  test_shadowing_field_over_getter() =>
-      check_shadowing('int x;', 'int get x => null;', true);
-
-  test_shadowing_field_over_method() =>
-      check_shadowing('int x;', 'void x() {}', true);
-
-  test_shadowing_field_over_setter() =>
-      check_shadowing('int x;', 'set x(int value) {}', true);
-
-  test_shadowing_getter_over_field() =>
-      check_shadowing('int get x => null;', 'int x;', true);
-
-  test_shadowing_getter_over_getter() =>
-      check_shadowing('int get x => null;', 'int get x => null;', true);
-
-  test_shadowing_getter_over_method() =>
-      check_shadowing('int get x => null;', 'void x() {}', true);
-
-  test_shadowing_getter_over_setter() =>
-      check_shadowing('int get x => null;', 'set x(int value) {}', true);
-
-  test_shadowing_method_over_field() =>
-      check_shadowing('void x() {}', 'int x;', true);
-
-  test_shadowing_method_over_getter() =>
-      check_shadowing('void x() {}', 'int get x => null;', true);
-
-  test_shadowing_method_over_method() =>
-      check_shadowing('void x() {}', 'void x() {}', true);
-
-  test_shadowing_method_over_setter() =>
-      check_shadowing('void x() {}', 'set x(int value) {}', true);
-
-  test_shadowing_mixin_order() {
-    addTestSource('''
-class Base {
-}
-class Mixin1 {
-  void f() {}
-}
-class Mixin2 {
-  void f() {}
-}
-class Derived extends Base with Mixin1, Mixin2 {
-}
-void test(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      // Note: due to dartbug.com/22069, analyzer currently analyzes mixins in
-      // reverse order.  The correct order is that Derived inherits from
-      // "Base with Mixin1, Mixin2", which inherits from "Base with Mixin1",
-      // which inherits from "Base".  So the definition of f in Mixin2 should
-      // shadow the definition in Mixin1.
-      assertSuggestMethod('f', 'Mixin2', 'void');
-    });
-  }
-
-  test_shadowing_mixin_over_superclass() {
-    addTestSource('''
-class Base {
-  void f() {}
-}
-class Mixin {
-  void f() {}
-}
-class Derived extends Base with Mixin {
-}
-void test(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestMethod('f', 'Mixin', 'void');
-    });
-  }
-
-  test_shadowing_setter_over_field() =>
-      check_shadowing('set x(int value) {}', 'int x;', true);
-
-  test_shadowing_setter_over_getter() =>
-      check_shadowing('set x(int value) {}', 'int get x => null;', true);
-
-  test_shadowing_setter_over_method() =>
-      check_shadowing('set x(int value) {}', 'void x() {}', true);
-
-  test_shadowing_setter_over_setter() =>
-      check_shadowing('set x(int value) {}', 'set x(int value) {}', true);
-
-  test_shadowing_superclass_over_interface() {
-    addTestSource('''
-class Base {
-  void f() {}
-}
-class Interface {
-  void f() {}
-}
-class Derived extends Base implements Interface {
-}
-void test(Derived d) {
-  d.^
-}
-''');
-    return computeFull((bool result) {
-      assertSuggestMethod('f', 'Base', 'void');
-    });
-  }
-
-  test_super() {
-    // SimpleIdentifier  MethodInvocation  ExpressionStatement
-    addTestSource('''
-class C3 {
-  int fi3;
-  static int fs3;
-  m() {}
-  mi3() {}
-  static ms3() {}
-}
-class C2 {
-  int fi2;
-  static int fs2;
-  m() {}
-  mi2() {}
-  static ms2() {}
-}
-class C1 extends C2 implements C3 {
-  int fi1;
-  static int fs1;
-  m() {super.^}
-  mi1() {}
-  static ms1() {}
-}''');
-    return computeFull((bool result) {
-      assertNotSuggested('fi1');
-      assertNotSuggested('fs1');
-      assertNotSuggested('mi1');
-      assertNotSuggested('ms1');
-      assertSuggestInvocationField('fi2', 'int');
-      assertNotSuggested('fs2');
-      assertSuggestInvocationMethod('mi2', 'C2', null);
-      assertNotSuggested('ms2');
-      assertSuggestInvocationMethod('m', 'C2', null,
-          relevance: DART_RELEVANCE_HIGH);
-      assertNotSuggested('fi3');
-      assertNotSuggested('fs3');
-      assertNotSuggested('mi3');
-      assertNotSuggested('ms3');
-    });
-  }
-}
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index c4adeb2..41ddfc9 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.dart
@@ -16,7 +16,6 @@
 import 'local_reference_contributor_test.dart'
     as local_reference_contributor_test;
 import 'optype_test.dart' as optype_test;
-import 'prefixed_element_contributor_test.dart' as invocation_test;
 
 /// Utility for manually running all tests.
 main() {
@@ -27,7 +26,6 @@
     completion_target_test.main();
     dart_contributor_tests.main();
     imported_test.main();
-    invocation_test.main();
     local_declaration_visitor_test.main();
     local_reference_contributor_test.main();
     optype_test.main();
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 48e8068..ed3d7d3 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -10,8 +10,10 @@
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
@@ -99,13 +101,21 @@
     }).toList();
   }
 
+  void processRequiredPlugins() {
+    plugin = new ServerPlugin();
+
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(plugin);
+
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+  }
+
   void setUp() {
     super.setUp();
     offset = 0;
     length = 0;
-    ExtensionManager manager = new ExtensionManager();
-    plugin = new ServerPlugin();
-    manager.processPlugins([plugin]);
   }
 
   test_addTypeAnnotation_BAD_privateType_closureParameter() async {
@@ -865,6 +875,32 @@
         'AAA', DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK);
   }
 
+  test_convertDocumentationIntoBlock_OK_noSpaceBeforeText() async {
+    resolveTestUnit('''
+class A {
+  /// AAAAA
+  ///BBBBB
+  ///
+  /// CCCCC
+  mmm() {}
+}
+''');
+    await assertHasAssistAt(
+        'AAAAA',
+        DartAssistKind.CONVERT_DOCUMENTATION_INTO_BLOCK,
+        '''
+class A {
+  /**
+   * AAAAA
+   *BBBBB
+   *
+   * CCCCC
+   */
+  mmm() {}
+}
+''');
+  }
+
   test_convertDocumentationIntoBlock_OK_onReference() async {
     resolveTestUnit('''
 /// AAAAAAA [int] AAAAAAA
diff --git a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
index 9ba6cae..476c4dd 100644
--- a/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
+++ b/pkg/analysis_server/test/services/index/dart_index_contributor_test.dart
@@ -1781,9 +1781,7 @@
   }
 }
 
-class MockIndexStore extends TypedMock implements InternalIndexStore {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockIndexStore extends TypedMock implements InternalIndexStore {}
 
 /**
  * Information about a relation recorded into {@link IndexStore}.
diff --git a/pkg/analysis_server/test/services/index/store/mocks.dart b/pkg/analysis_server/test/services/index/store/mocks.dart
index 9ed78af..a197342 100644
--- a/pkg/analysis_server/test/services/index/store/mocks.dart
+++ b/pkg/analysis_server/test/services/index/store/mocks.dart
@@ -8,18 +8,10 @@
 import 'package:analysis_server/src/services/index/store/codec.dart';
 import 'package:typed_mock/typed_mock.dart';
 
-class MockContextCodec extends TypedMock implements ContextCodec {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockContextCodec extends TypedMock implements ContextCodec {}
 
-class MockElementCodec extends TypedMock implements ElementCodec {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockElementCodec extends TypedMock implements ElementCodec {}
 
-class MockLocation extends TypedMock implements LocationImpl {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLocation extends TypedMock implements LocationImpl {}
 
-class MockRelationshipCodec extends TypedMock implements RelationshipCodec {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockRelationshipCodec extends TypedMock implements RelationshipCodec {}
diff --git a/pkg/analysis_server/test/services/index/store/split_store_test.dart b/pkg/analysis_server/test/services/index/store/split_store_test.dart
index 17c7e8b..1ae14d5 100644
--- a/pkg/analysis_server/test/services/index/store/split_store_test.dart
+++ b/pkg/analysis_server/test/services/index/store/split_store_test.dart
@@ -420,13 +420,9 @@
   }
 }
 
-class _MockFileManager extends TypedMock implements FileManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockFileManager extends TypedMock implements FileManager {}
 
-class _MockIndexNode extends TypedMock implements IndexNode {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockIndexNode extends TypedMock implements IndexNode {}
 
 @reflectiveTest
 class _RelationKeyDataTest {
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index 46a6e67..cae09e7 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -5,6 +5,7 @@
 library test.services.refactoring.extract_local;
 
 import 'dart:async';
+import 'dart:convert';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
@@ -534,7 +535,7 @@
     expect(refactoring.names, unorderedEquals(['helloBob', 'bob']));
   }
 
-  test_occurrences_differentVariable() {
+  test_occurrences_differentVariable() async {
     indexTestUnit('''
 main() {
   {
@@ -550,7 +551,7 @@
 ''');
     _createRefactoringWithSuffix('v + 1', '); // marker');
     // apply refactoring
-    return _assertSuccessfulRefactoring('''
+    await _assertSuccessfulRefactoring('''
 main() {
   {
     int v = 1;
@@ -564,6 +565,8 @@
   }
 }
 ''');
+    _assertSingleLinkedEditGroup(
+        length: 3, offsets: [36, 59, 85], names: ['object', 'i']);
   }
 
   test_occurrences_disableOccurrences() {
@@ -788,7 +791,7 @@
 ''');
   }
 
-  test_singleExpression_inExpressionBody() {
+  test_singleExpression_inExpressionBody() async {
     indexTestUnit('''
 main() {
   print((x) => x.y * x.y + 1);
@@ -796,7 +799,7 @@
 ''');
     _createRefactoringForString('x.y');
     // apply refactoring
-    return _assertSuccessfulRefactoring('''
+    await _assertSuccessfulRefactoring('''
 main() {
   print((x) {
     var res = x.y;
@@ -804,6 +807,8 @@
   });
 }
 ''');
+    _assertSingleLinkedEditGroup(
+        length: 3, offsets: [31, 53, 59], names: ['y']);
   }
 
   test_singleExpression_inIfElseIf() {
@@ -987,7 +992,7 @@
 ''');
   }
 
-  test_stringLiteral_part() {
+  test_stringLiteral_part() async {
     indexTestUnit('''
 main() {
   print('abcdefgh');
@@ -995,15 +1000,16 @@
 ''');
     _createRefactoringForString('cde');
     // apply refactoring
-    return _assertSuccessfulRefactoring(r'''
+    await _assertSuccessfulRefactoring(r'''
 main() {
   var res = 'cde';
   print('ab${res}fgh');
 }
 ''');
+    _assertSingleLinkedEditGroup(length: 3, offsets: [15, 41], names: ['cde']);
   }
 
-  test_stringLiteral_whole() {
+  test_stringLiteral_whole() async {
     indexTestUnit('''
 main() {
   print('abc');
@@ -1011,15 +1017,17 @@
 ''');
     _createRefactoringForString("'abc'");
     // apply refactoring
-    return _assertSuccessfulRefactoring('''
+    await _assertSuccessfulRefactoring('''
 main() {
   var res = 'abc';
   print(res);
 }
 ''');
+    _assertSingleLinkedEditGroup(
+        length: 3, offsets: [15, 36], names: ['object', 's']);
   }
 
-  test_stringLiteralPart() {
+  test_stringLiteralPart() async {
     indexTestUnit(r'''
 main() {
   int x = 1;
@@ -1029,7 +1037,7 @@
 ''');
     _createRefactoringForString(r'$x+$y');
     // apply refactoring
-    return _assertSuccessfulRefactoring(r'''
+    await _assertSuccessfulRefactoring(r'''
 main() {
   int x = 1;
   int y = 2;
@@ -1037,6 +1045,7 @@
   print('${res}=${x+y}');
 }
 ''');
+    _assertSingleLinkedEditGroup(length: 3, offsets: [41, 67], names: ['xy']);
   }
 
   Future _assertInitialConditions_fatal_selection() async {
@@ -1046,6 +1055,27 @@
             'Expression must be selected to activate this refactoring.');
   }
 
+  void _assertSingleLinkedEditGroup(
+      {int length, List<int> offsets, List<String> names}) {
+    String positionsString = offsets
+        .map((offset) => '{"file": "$testFile", "offset": $offset}')
+        .join(',');
+    String suggestionsString =
+        names.map((name) => '{"value": "$name", "kind": "VARIABLE"}').join(',');
+    _assertSingleLinkedEditGroupJson('''
+{
+  "length": $length,
+  "positions": [$positionsString],
+  "suggestions": [$suggestionsString]
+}''');
+  }
+
+  void _assertSingleLinkedEditGroupJson(String expectedJsonString) {
+    List<LinkedEditGroup> editGroups = refactoringChange.linkedEditGroups;
+    expect(editGroups, hasLength(1));
+    expect(editGroups.first.toJson(), JSON.decode(expectedJsonString));
+  }
+
   /**
    * Checks that all conditions are OK and the result of applying the
    * [SourceChange] to [testUnit] is [expectedCode].
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 1453d46..31d826b 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -62,9 +62,7 @@
   }
 }
 
-class MockIndex extends TypedMock implements Index {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockIndex extends TypedMock implements Index {}
 
 @reflectiveTest
 class SearchEngineImplTest extends AbstractSingleUnitTest {
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
index af83c5e..ab4020c 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ContextData.java
@@ -64,11 +64,6 @@
   private final int workItemQueueLength;
 
   /**
-   * A rolling average of work items in the queue. (A double encoded as a String.)
-   */
-  private final String workItemQueueLengthAverage;
-
-  /**
    * Exceptions associated with cache entries.
    */
   private final List<String> cacheEntryExceptions;
@@ -76,12 +71,11 @@
   /**
    * Constructor for {@link ContextData}.
    */
-  public ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, String workItemQueueLengthAverage, List<String> cacheEntryExceptions) {
+  public ContextData(String name, int explicitFileCount, int implicitFileCount, int workItemQueueLength, List<String> cacheEntryExceptions) {
     this.name = name;
     this.explicitFileCount = explicitFileCount;
     this.implicitFileCount = implicitFileCount;
     this.workItemQueueLength = workItemQueueLength;
-    this.workItemQueueLengthAverage = workItemQueueLengthAverage;
     this.cacheEntryExceptions = cacheEntryExceptions;
   }
 
@@ -94,7 +88,6 @@
         other.explicitFileCount == explicitFileCount &&
         other.implicitFileCount == implicitFileCount &&
         other.workItemQueueLength == workItemQueueLength &&
-        ObjectUtilities.equals(other.workItemQueueLengthAverage, workItemQueueLengthAverage) &&
         ObjectUtilities.equals(other.cacheEntryExceptions, cacheEntryExceptions);
     }
     return false;
@@ -105,9 +98,8 @@
     int explicitFileCount = jsonObject.get("explicitFileCount").getAsInt();
     int implicitFileCount = jsonObject.get("implicitFileCount").getAsInt();
     int workItemQueueLength = jsonObject.get("workItemQueueLength").getAsInt();
-    String workItemQueueLengthAverage = jsonObject.get("workItemQueueLengthAverage").getAsString();
     List<String> cacheEntryExceptions = JsonUtilities.decodeStringList(jsonObject.get("cacheEntryExceptions").getAsJsonArray());
-    return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, workItemQueueLengthAverage, cacheEntryExceptions);
+    return new ContextData(name, explicitFileCount, implicitFileCount, workItemQueueLength, cacheEntryExceptions);
   }
 
   public static List<ContextData> fromJsonArray(JsonArray jsonArray) {
@@ -157,13 +149,6 @@
     return workItemQueueLength;
   }
 
-  /**
-   * A rolling average of work items in the queue. (A double encoded as a String.)
-   */
-  public String getWorkItemQueueLengthAverage() {
-    return workItemQueueLengthAverage;
-  }
-
   @Override
   public int hashCode() {
     HashCodeBuilder builder = new HashCodeBuilder();
@@ -171,7 +156,6 @@
     builder.append(explicitFileCount);
     builder.append(implicitFileCount);
     builder.append(workItemQueueLength);
-    builder.append(workItemQueueLengthAverage);
     builder.append(cacheEntryExceptions);
     return builder.toHashCode();
   }
@@ -182,7 +166,6 @@
     jsonObject.addProperty("explicitFileCount", explicitFileCount);
     jsonObject.addProperty("implicitFileCount", implicitFileCount);
     jsonObject.addProperty("workItemQueueLength", workItemQueueLength);
-    jsonObject.addProperty("workItemQueueLengthAverage", workItemQueueLengthAverage);
     JsonArray jsonArrayCacheEntryExceptions = new JsonArray();
     for (String elt : cacheEntryExceptions) {
       jsonArrayCacheEntryExceptions.add(new JsonPrimitive(elt));
@@ -203,8 +186,6 @@
     builder.append(implicitFileCount + ", ");
     builder.append("workItemQueueLength=");
     builder.append(workItemQueueLength + ", ");
-    builder.append("workItemQueueLengthAverage=");
-    builder.append(workItemQueueLengthAverage + ", ");
     builder.append("cacheEntryExceptions=");
     builder.append(StringUtils.join(cacheEntryExceptions, ", "));
     builder.append("]");
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
index a5e439f..346bf63 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
@@ -76,6 +76,11 @@
   public static final String INVALID_EXECUTION_CONTEXT = "INVALID_EXECUTION_CONTEXT";
 
   /**
+   * The format of the given file path is invalid, e.g. is not absolute and normalized.
+   */
+  public static final String INVALID_FILE_PATH_FORMAT = "INVALID_FILE_PATH_FORMAT";
+
+  /**
    * An "analysis.updateContent" request contained a ChangeContentOverlay object which can't be
    * applied, due to an edit having an offset or length that is out of range.
    */
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index fcddc94..3bb6cfe 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -6,7 +6,7 @@
   </head>
   <body>
     <h1>Analysis Server API Specification</h1>
-    <h1 style="color:#999999">Version <version>1.13.0</version></h1>
+    <h1 style="color:#999999">Version <version>1.14.0</version></h1>
     <p>
       This document contains a specification of the API provided by the
       analysis server.  The API in this document is currently under
@@ -1995,14 +1995,9 @@
         </params>
       </notification>
     </domain>
-    <domain name="diagnostic" experimental="true">
+    <domain name="diagnostic">
       <p>
-        The diagnostic domain contains experimental server diagnostics APIs. Note
-        that as an experimental API, docs are not generated for this domain and it
-        is subject subject to change without notice.
-        Because this experimental domain is not part of the analysis server's API,
-        the version number of the API will not be updated when changes are made.
-        Caveat emptor!
+        The diagnostic domain contains server diagnostics APIs.
       </p>
       <request method="getDiagnostics">
         <p>Return server diagnostics.</p>
@@ -2496,7 +2491,7 @@
           <value><code>PARAMETER</code></value>
         </enum>
       </type>
-      <type name="ContextData" experimental="true">
+      <type name="ContextData">
         <p>
           Information about an analysis context.
         </p>
@@ -2525,12 +2520,6 @@
               The number of work items in the queue.
             </p>
           </field>
-          <field name="workItemQueueLengthAverage">
-            <ref>String</ref>
-            <p>
-              A rolling average of work items in the queue. (A double encoded as a String.)
-            </p>
-          </field>
           <field name="cacheEntryExceptions">
             <list><ref>String</ref></list>
             <p>
@@ -2694,7 +2683,12 @@
       <type name="FilePath">
         <ref>String</ref>
         <p>
-          The absolute path of a file.
+          The absolute, normalized path of a file.
+        </p>
+        <p>
+          If the format of a file path in a request is not valid, e.g. the
+          path is not absolute or is not normalized, then an error of type
+          <tt>INVALID_FILE_PATH_FORMAT</tt> will be generated.
         </p>
       </type>
       <type name="FoldingKind">
@@ -3708,6 +3702,13 @@
             </p>
           </value>
           <value>
+            <code>INVALID_FILE_PATH_FORMAT</code>
+            <p>
+              The format of the given file path is invalid, e.g. is not
+              absolute and normalized.
+            </p>
+          </value>
+          <value>
             <code>INVALID_OVERLAY_CHANGE</code>
             <p>
               An "analysis.updateContent" request contained a
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 6ff682d..805dcd8 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 0.27.0
+* Support for DEP 37 (Assert with optional message).
+* Lexical support for DEP 40 (Interface libraries). This does not include any semantic checking to ensure that the
+  implementation libraries are compatible with the interface library.
+* Cleaned up the initialization of plugins. Clients are now required to initialize plugins, possibly using the utility
+  method AnalysisEngine.processRequiredPlugins().
+* Removed the old task model and code that supported it. None of the removed code was intended to be public API, but
+  might be in use anyway.
+* Removed previously deprecated API's (marked with the @deprecated annotation).
+
+## 0.26.4
+* Options processing API updated to accept untyped options maps (#25126).
+
 ## 0.26.3
 * (Internal) Support for `_embedder.yaml` discovery and processing.
 
@@ -88,7 +101,7 @@
 
 ## 0.25.2-alpha.0
 
-* Initial support for analyzing `dart:sdk` extensions from `.sdkext`. 
+* Initial support for analyzing `dart:sdk` extensions from `.sdkext`.
 
 ## 0.25.1
 
@@ -112,7 +125,7 @@
 ## 0.22.0
 
   New API:
-  
+
 * `Source.uri` added.
 
   Breaking changes:
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 83a72a1..d0fdc65 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -6,20 +6,19 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/error.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/string_source.dart';
 import 'package:path/path.dart' as pathos;
 
-import 'src/error.dart';
-import 'src/generated/ast.dart';
-import 'src/generated/error.dart';
-import 'src/generated/parser.dart';
-import 'src/generated/scanner.dart';
-import 'src/generated/source_io.dart';
-import 'src/string_source.dart';
-
-export 'src/error.dart';
-export 'src/generated/ast.dart';
-export 'src/generated/error.dart';
-export 'src/generated/utilities_dart.dart';
+export 'package:analyzer/src/error.dart';
+export 'package:analyzer/src/generated/ast.dart';
+export 'package:analyzer/src/generated/error.dart';
+export 'package:analyzer/src/generated/utilities_dart.dart';
 
 /// Parses a string of Dart code into an AST.
 ///
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index cbe175f..05bd4e7 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -2,7 +2,7 @@
 // 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 file_system;
+library analyzer.file_system.file_system;
 
 import 'dart:async';
 
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index c276397..dc676bb 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -2,20 +2,19 @@
 // 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 memory_file_system;
+library analyzer.file_system.memory_file_system;
 
 import 'dart:async';
 import 'dart:collection';
 import 'dart:core' hide Resource;
 
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
-import 'file_system.dart';
-
 /**
  * An in-memory implementation of [ResourceProvider].
  * Use `/` as a path separator.
@@ -30,7 +29,7 @@
   int nextStamp = 0;
 
   final AbsolutePathContext absolutePathContext =
-      new AbsolutePathContext(posix.separator);
+      new AbsolutePathContext(false);
 
   @override
   Context get pathContext => posix;
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index 94aa766..18694c0 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -2,20 +2,19 @@
 // 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 physical_file_system;
+library analyzer.file_system.physical_file_system;
 
 import 'dart:async';
 import 'dart:core' hide Resource;
 import 'dart:io' as io;
 
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:path/path.dart';
 import 'package:watcher/watcher.dart';
 
-import 'file_system.dart';
-
 /**
  * A `dart:io` based implementation of [ResourceProvider].
  */
@@ -33,7 +32,7 @@
   static final String SERVER_DIR = ".dartServer";
 
   final AbsolutePathContext absolutePathContext =
-      new AbsolutePathContext(io.Platform.pathSeparator);
+      new AbsolutePathContext(io.Platform.isWindows);
 
   PhysicalResourceProvider(String fileReadMode(String s)) {
     if (fileReadMode != null) {
diff --git a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
index 7269115..fe36a9e 100644
--- a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
@@ -2,7 +2,7 @@
 // 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 file_instrumentation;
+library analyzer.instrumentation.file_instrumentation;
 
 import 'dart:async';
 import 'dart:io';
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 8b36303..fe58cdb 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -2,7 +2,7 @@
 // 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 instrumentation;
+library analyzer.instrumentation.instrumentation;
 
 import 'dart:async';
 import 'dart:convert';
@@ -104,9 +104,7 @@
    * Log that the given analysis [task] is being performed in the given
    * [context].
    */
-  void logAnalysisTask(String context, dynamic task) {
-    // TODO(brianwilkerson) When the old task model is removed, change the
-    // parameter type to AnalysisTask.
+  void logAnalysisTask(String context, AnalysisTask task) {
     if (_instrumentationServer != null) {
       String description =
           (task is AnalysisTask) ? task.description : task.toString();
diff --git a/pkg/analyzer/lib/plugin/options.dart b/pkg/analyzer/lib/plugin/options.dart
index cec20c2..725315e 100644
--- a/pkg/analyzer/lib/plugin/options.dart
+++ b/pkg/analyzer/lib/plugin/options.dart
@@ -69,7 +69,7 @@
   /// options have changed and to handle those changes appropriately. In
   /// addition to the [options] map, the associated analysis [context] is
   /// provided as well to allow for context-specific configuration.
-  void optionsProcessed(AnalysisContext context, Map<String, YamlNode> options);
+  void optionsProcessed(AnalysisContext context, Map<String, Object> options);
 }
 
 /// Validates options as defined in an analysis options file.
diff --git a/pkg/analyzer/lib/plugin/task.dart b/pkg/analyzer/lib/plugin/task.dart
index d3eb4cd..2a242de 100644
--- a/pkg/analyzer/lib/plugin/task.dart
+++ b/pkg/analyzer/lib/plugin/task.dart
@@ -8,7 +8,7 @@
  */
 library analyzer.plugin.task;
 
-import 'package:analyzer/src/generated/engine.dart' hide WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:plugin/plugin.dart';
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 64c8c8b..c53bbad 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -2,7 +2,7 @@
 // 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 source.analysis_options_provider;
+library analyzer.source.analysis_options_provider;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
index 2695989..c82e4f3 100644
--- a/pkg/analyzer/lib/source/embedder.dart
+++ b/pkg/analyzer/lib/source/embedder.dart
@@ -2,10 +2,10 @@
 // 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 source.embedder;
+library analyzer.source.embedder;
 
-import 'dart:core' hide Resource;
 import 'dart:collection' show HashMap;
+import 'dart:core' hide Resource;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
diff --git a/pkg/analyzer/lib/source/error_processor.dart b/pkg/analyzer/lib/source/error_processor.dart
new file mode 100644
index 0000000..b20716a
--- /dev/null
+++ b/pkg/analyzer/lib/source/error_processor.dart
@@ -0,0 +1,105 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.source.error_processor;
+
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:yaml/yaml.dart';
+
+/// Error processor configuration derived from analysis (or embedder) options.
+class ErrorConfig {
+  /// The processors in this config.
+  final List<ErrorProcessor> processors = <ErrorProcessor>[];
+
+  /// Create an error config for the given error code map.
+  /// For example:
+  ///     new ErrorConfig({'missing_return' : 'error'});
+  /// will create a processor config that turns `missing_return` hints into
+  /// errors.
+  ErrorConfig(Object codeMap) {
+    _processMap(codeMap);
+  }
+
+  void _process(String code, Object action) {
+    action = toLowerCase(action);
+    code = toUpperCase(code);
+    if (AnalyzerOptions.ignoreSynonyms.contains(action)) {
+      processors.add(new ErrorProcessor.ignore(code));
+    } else {
+      ErrorSeverity severity = _toSeverity(action);
+      if (severity != null) {
+        processors.add(new ErrorProcessor(code, severity));
+      }
+    }
+  }
+
+  void _processMap(Object codes) {
+    if (codes is YamlMap) {
+      // TODO(pq): stop traversing nodes and unify w/ standard map handling
+      codes.nodes.forEach((k, v) {
+        if (k is YamlScalar && v is YamlScalar) {
+          _process(k.value, v.value);
+        }
+      });
+    } else if (codes is Map) {
+      codes.forEach((k, v) {
+        if (k is String) {
+          _process(k, v);
+        }
+      });
+    }
+  }
+
+  ErrorSeverity _toSeverity(String severity) {
+    switch (severity) {
+      case 'error':
+        return ErrorSeverity.ERROR;
+      case 'info':
+        return ErrorSeverity.INFO;
+      case 'warning':
+        return ErrorSeverity.WARNING;
+    }
+    return null;
+  }
+
+}
+
+/// Process errors by filtering or changing associated [ErrorSeverity].
+class ErrorProcessor {
+  /// The code name of the associated error.
+  final String code;
+
+  /// The desired severity of the processed error.
+  ///
+  /// If `null`, this processor will "filter" the associated error code.
+  final ErrorSeverity severity;
+
+  /// Create an error processor that assigns errors with this [code] the
+  /// given [severity].
+  ///
+  /// If [severity] is `null`, matching errors will be filtered.
+  ErrorProcessor(this.code, [this.severity]);
+
+  /// Create an error processor that ignores the given error by [code].
+  factory ErrorProcessor.ignore(String code) => new ErrorProcessor(code);
+
+  /// Check if this processor applies to the given [error].
+  bool appliesTo(AnalysisError error) => code == error.errorCode.name;
+
+  /// Return an error processor associated with this [context] for the given
+  /// [error], or `null` if none is found.
+  static ErrorProcessor getProcessor(
+      AnalysisContext context, AnalysisError error) {
+    if (context == null) {
+      return null;
+    }
+    List<ErrorProcessor> processors =
+        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+    return processors.firstWhere((ErrorProcessor p) => p.appliesTo(error),
+        orElse: () => null);
+  }
+}
diff --git a/pkg/analyzer/lib/source/package_map_provider.dart b/pkg/analyzer/lib/source/package_map_provider.dart
index 85b493d..b2eb8b6 100644
--- a/pkg/analyzer/lib/source/package_map_provider.dart
+++ b/pkg/analyzer/lib/source/package_map_provider.dart
@@ -2,7 +2,7 @@
 // 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 source.package_map_provider;
+library analyzer.source.package_map_provider;
 
 import 'package:analyzer/file_system/file_system.dart';
 
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 0fa12ae..4325582 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -2,7 +2,7 @@
 // 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 source.package_map_resolver;
+library analyzer.source.package_map_resolver;
 
 import 'dart:core' hide Resource;
 
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index 7eeada2..f449610 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -2,7 +2,7 @@
 // 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 source.path_filter;
+library analyzer.source.path_filter;
 
 import 'package:analyzer/src/util/glob.dart';
 import 'package:path/path.dart' as path;
diff --git a/pkg/analyzer/lib/source/pub_package_map_provider.dart b/pkg/analyzer/lib/source/pub_package_map_provider.dart
index 5daf61d..a7b2c42 100644
--- a/pkg/analyzer/lib/source/pub_package_map_provider.dart
+++ b/pkg/analyzer/lib/source/pub_package_map_provider.dart
@@ -2,7 +2,7 @@
 // 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 source.pub_package_map_provider;
+library analyzer.source.pub_package_map_provider;
 
 import 'dart:collection';
 import 'dart:convert';
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index 646a19f..fc7155a 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -2,7 +2,7 @@
 // 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 source.sdk_ext;
+library analyzer.source.sdk_ext;
 
 import 'dart:convert';
 import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
index 733cac5..8ae070b 100644
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -2,7 +2,7 @@
 // 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 cancelable_future;
+library analyzer.src.cancelable_future;
 
 import 'dart:async';
 
diff --git a/pkg/analyzer/lib/src/codegen/text_formatter.dart b/pkg/analyzer/lib/src/codegen/text_formatter.dart
index 28669e0..5274901 100644
--- a/pkg/analyzer/lib/src/codegen/text_formatter.dart
+++ b/pkg/analyzer/lib/src/codegen/text_formatter.dart
@@ -8,10 +8,9 @@
  */
 library analyzer.src.codegen.text_formatter;
 
+import 'package:analyzer/src/codegen/tools.dart';
 import 'package:html/dom.dart' as dom;
 
-import 'tools.dart';
-
 final RegExp whitespace = new RegExp(r'\s');
 
 /**
diff --git a/pkg/analyzer/lib/src/codegen/tools.dart b/pkg/analyzer/lib/src/codegen/tools.dart
index 87c9edf..6c4048c 100644
--- a/pkg/analyzer/lib/src/codegen/tools.dart
+++ b/pkg/analyzer/lib/src/codegen/tools.dart
@@ -9,12 +9,11 @@
 
 import 'dart:io';
 
+import 'package:analyzer/src/codegen/html.dart';
+import 'package:analyzer/src/codegen/text_formatter.dart';
 import 'package:html/dom.dart' as dom;
 import 'package:path/path.dart';
 
-import 'html.dart';
-import 'text_formatter.dart';
-
 final RegExp trailingSpacesInLineRegExp = new RegExp(r' +$', multiLine: true);
 final RegExp trailingWhitespaceRegExp = new RegExp(r'[\n ]+$');
 
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 2b81cdd..afe0216 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -7,8 +7,7 @@
 import 'dart:async';
 import 'dart:collection';
 
-import 'package:analyzer/src/generated/engine.dart'
-    show AnalysisEngine, CacheState, InternalAnalysisContext, RetentionPriority;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -41,9 +40,9 @@
   final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
       new ReentrantSynchronousStream<InvalidatedResult>();
 
-  final List<
-      ReentrantSynchronousStreamSubscription> onResultInvalidatedPartitionSubscriptions = <
-      ReentrantSynchronousStreamSubscription>[];
+  final List<ReentrantSynchronousStreamSubscription>
+      onResultInvalidatedPartitionSubscriptions =
+      <ReentrantSynchronousStreamSubscription>[];
 
   /**
    * Initialize a newly created cache to have the given [_partitions]. The
@@ -385,7 +384,7 @@
    * Return the value of the result represented by the given [descriptor], or
    * the default value for the result if this entry does not have a valid value.
    */
-  /*<V>*/ dynamic /*V*/ getValue(ResultDescriptor /*<V>*/ descriptor) {
+  dynamic /*=V*/ getValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor) {
     ResultData data = _resultMap[descriptor];
     if (data == null) {
       return descriptor.defaultValue;
@@ -483,11 +482,8 @@
    * Set the value of the result represented by the given [descriptor] to the
    * given [value].
    */
-  /*<V>*/ void setValue(
-      ResultDescriptor /*<V>*/ descriptor,
-      dynamic /*V*/
-      value,
-      List<TargetedResult> dependedOn) {
+  void setValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor,
+      dynamic /*=V*/ value, List<TargetedResult> dependedOn) {
 //    {
 //      String valueStr = '$value';
 //      if (valueStr.length > 20) {
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 4d3651b..7c2971a 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -15,15 +15,8 @@
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide
-        AnalysisCache,
-        CachePartition,
-        SdkCachePartition,
-        UniversalCachePartition,
-        WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht show HtmlUnit;
 import 'package:analyzer/src/generated/incremental_resolver.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -211,21 +204,6 @@
   CompilationUnit incrementalResolutionValidation_lastUnit;
 
   /**
-   * A factory to override how the [ResolverVisitor] is created.
-   */
-  ResolverVisitorFactory resolverVisitorFactory;
-
-  /**
-   * A factory to override how the [TypeResolverVisitor] is created.
-   */
-  TypeResolverVisitorFactory typeResolverVisitorFactory;
-
-  /**
-   * A factory to override how [LibraryResolver] is created.
-   */
-  LibraryResolverFactory libraryResolverFactory;
-
-  /**
    * Initialize a newly created analysis context.
    */
   AnalysisContextImpl() {
@@ -267,6 +245,7 @@
         (this._options.lint && !options.lint) ||
         this._options.preserveComments != options.preserveComments ||
         this._options.strongMode != options.strongMode ||
+        this._options.enableAssertMessage != options.enableAssertMessage ||
         ((options is AnalysisOptionsImpl)
             ? this._options.strongModeHints != options.strongModeHints
             : false) ||
@@ -284,6 +263,7 @@
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
     this._options.enableGenericMethods = options.enableGenericMethods;
+    this._options.enableAssertMessage = options.enableAssertMessage;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
     this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.hint = options.hint;
@@ -395,9 +375,8 @@
   /**
    * Make _pendingFutureSources available to unit tests.
    */
-  HashMap<AnalysisTarget,
-      List<PendingFuture>> get pendingFutureSources_forTesting =>
-      _pendingFutureTargets;
+  HashMap<AnalysisTarget, List<PendingFuture>>
+      get pendingFutureSources_forTesting => _pendingFutureTargets;
 
   @override
   List<Source> get prioritySources => _priorityOrder;
@@ -458,16 +437,6 @@
     return new List<Source>.from(sources);
   }
 
-  @override
-  AnalysisContextStatistics get statistics {
-    AnalysisContextStatisticsImpl statistics =
-        new AnalysisContextStatisticsImpl();
-    // TODO(brianwilkerson) Implement this.
-//    visitCacheItems(statistics._internalPutCacheItem);
-//    statistics.partitionData = _cache.partitionData;
-    return statistics;
-  }
-
   List<Source> get test_priorityOrder => _priorityOrder;
 
   @override
@@ -619,14 +588,6 @@
       computeResult(source, EXPORTED_LIBRARIES);
 
   @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   List<Source> computeImportedLibraries(Source source) =>
       computeResult(source, EXPLICITLY_IMPORTED_LIBRARIES);
 
@@ -651,26 +612,19 @@
   LineInfo computeLineInfo(Source source) => computeResult(source, LINE_INFO);
 
   @override
-  @deprecated
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    return null;
-  }
-
-  @override
   CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
       Source unitSource, Source librarySource) {
     if (!AnalysisEngine.isDartFileName(unitSource.shortName) ||
         !AnalysisEngine.isDartFileName(librarySource.shortName)) {
       return new CancelableFuture.error(new AnalysisNotScheduledError());
     }
-    return new AnalysisFutureHelper<CompilationUnit>(
-        this,
-        new LibrarySpecificUnit(librarySource, unitSource),
-        RESOLVED_UNIT).computeAsync();
+    return new AnalysisFutureHelper<CompilationUnit>(this,
+            new LibrarySpecificUnit(librarySource, unitSource), RESOLVED_UNIT)
+        .computeAsync();
   }
 
   @override
-  Object /*V*/ computeResult(
+  Object /*=V*/ computeResult /*<V>*/ (
       AnalysisTarget target, ResultDescriptor /*<V>*/ descriptor) {
     // Make sure we are not trying to invoke the task model in a reentrant
     // fashion.
@@ -700,7 +654,7 @@
       return new AnalysisCache(<CachePartition>[_privatePartition]);
     }
     return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager_new.forSdk(sdk),
+      AnalysisEngine.instance.partitionManager.forSdk(sdk),
       _privatePartition
     ]);
   }
@@ -840,14 +794,6 @@
   }
 
   @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   List<Source> getHtmlFilesReferencing(Source source) {
     if (!AnalysisEngine.isDartFileName(source.shortName)) {
       return Source.EMPTY_LIST;
@@ -979,14 +925,6 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   Object getResult(AnalysisTarget target, ResultDescriptor result) {
     return _cache.getValue(target, result);
   }
@@ -1108,14 +1046,6 @@
   }
 
   @override
-  @deprecated // use parseHtmlDocument(source)
-  ht.HtmlUnit parseHtmlUnit(Source source) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   AnalysisResult performAnalysisTask() {
     return PerformanceStatistics.performAnaysis.makeCurrentWhile(() {
       _evaluatePendingFutures();
@@ -1225,14 +1155,6 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    // TODO(brianwilkerson) Remove this method after switching to the new task
-    // model.
-    throw new UnimplementedError('Not supported in the new task model');
-  }
-
-  @override
   void setChangedContents(Source source, String contents, int offset,
       int oldLength, int newLength) {
     if (_contentRangeChanged(source, contents, offset, oldLength, newLength)) {
@@ -1252,7 +1174,7 @@
   }
 
   @override
-  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+  bool shouldErrorsBeAnalyzed(Source source) {
     CacheEntry entry = analysisCache.get(source);
     if (source.isInSystemLibrary) {
       return _options.generateSdkErrors;
@@ -1332,72 +1254,6 @@
     return changedSources.length > 0;
   }
 
-  @deprecated
-  @override
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state)) {
-    // TODO(brianwilkerson) Figure out where this is used and either remove it
-    // or adjust the call sites to use CacheEntry's.
-//    bool hintsEnabled = _options.hint;
-//    bool lintsEnabled = _options.lint;
-//    MapIterator<AnalysisTarget, cache.CacheEntry> iterator = _cache.iterator();
-//    while (iterator.moveNext()) {
-//      Source source = iterator.key;
-//      cache.CacheEntry entry = iterator.value;
-//      for (DataDescriptor descriptor in entry.descriptors) {
-//        if (descriptor == DartEntry.SOURCE_KIND) {
-//          // The source kind is always valid, so the state isn't interesting.
-//          continue;
-//        } else if (descriptor == DartEntry.CONTAINING_LIBRARIES) {
-//          // The list of containing libraries is always valid, so the state
-//          // isn't interesting.
-//          continue;
-//        } else if (descriptor == DartEntry.PUBLIC_NAMESPACE) {
-//          // The public namespace isn't computed by performAnalysisTask()
-//          // and therefore isn't interesting.
-//          continue;
-//        } else if (descriptor == HtmlEntry.HINTS) {
-//          // We are not currently recording any hints related to HTML.
-//          continue;
-//        }
-//        callback(
-//            source, entry, descriptor, entry.getState(descriptor));
-//      }
-//      if (entry is DartEntry) {
-//        // get library-specific values
-//        List<Source> librarySources = getLibrariesContaining(source);
-//        for (Source librarySource in librarySources) {
-//          for (DataDescriptor descriptor in entry.libraryDescriptors) {
-//            if (descriptor == DartEntry.BUILT_ELEMENT ||
-//                descriptor == DartEntry.BUILT_UNIT) {
-//              // These values are not currently being computed, so their state
-//              // is not interesting.
-//              continue;
-//            } else if (!entry.explicitlyAdded &&
-//                !_generateImplicitErrors &&
-//                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-//                    descriptor == DartEntry.HINTS ||
-//                    descriptor == DartEntry.LINTS)) {
-//              continue;
-//            } else if (source.isInSystemLibrary &&
-//                !_generateSdkErrors &&
-//                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-//                    descriptor == DartEntry.HINTS ||
-//                    descriptor == DartEntry.LINTS)) {
-//              continue;
-//            } else if (!hintsEnabled && descriptor == DartEntry.HINTS) {
-//              continue;
-//            } else if (!lintsEnabled && descriptor == DartEntry.LINTS) {
-//              continue;
-//            }
-//            callback(librarySource, entry, descriptor,
-//                entry.getStateInLibrary(descriptor, librarySource));
-//          }
-//        }
-//      }
-//    }
-  }
-
   @override
   void visitContentCache(ContentCacheVisitor visitor) {
     _contentCache.accept(visitor);
@@ -1667,7 +1523,7 @@
         } else if (state == CacheState.ERROR) {
           return;
         }
-        if (shouldErrorsBeAnalyzed(source, unitEntry)) {
+        if (shouldErrorsBeAnalyzed(source)) {
           state = unitEntry.getState(VERIFY_ERRORS);
           if (state == CacheState.INVALID ||
               (isPriority && state == CacheState.FLUSHED)) {
@@ -1948,7 +1804,6 @@
       PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
           typeProvider,
           unitSource,
-          null,
           sourceEntry,
           unitEntry,
           oldUnit,
@@ -2164,8 +2019,7 @@
       throw new IllegalArgumentException(
           "The source factory for an SDK analysis context must have a DartUriResolver");
     }
-    return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager_new.forSdk(sdk)
-    ]);
+    return new AnalysisCache(
+        <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
   }
 }
diff --git a/pkg/analyzer/lib/src/error.dart b/pkg/analyzer/lib/src/error.dart
index 60f5cf0..35ffb7c 100644
--- a/pkg/analyzer/lib/src/error.dart
+++ b/pkg/analyzer/lib/src/error.dart
@@ -1,11 +1,11 @@
 // Copyright (c) 2013, 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 error;
+library analyzer.src.error;
 
 import 'dart:collection';
 
-import 'generated/error.dart';
+import 'package:analyzer/src/generated/error.dart';
 
 /// The maximum line length when printing extracted source code when converting
 /// an [AnalyzerError] to a string.
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index f04a15e..282b8b7 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -2,19 +2,19 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.ast;
+library analyzer.src.generated.ast;
 
 import 'dart:collection';
 
-import 'element.dart';
-import 'engine.dart' show AnalysisEngine;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart';
-import 'scanner.dart';
-import 'source.dart' show LineInfo, Source;
-import 'utilities_collection.dart' show TokenMap;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisEngine;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
  * Two or more string literals that are implicitly concatenated because of being
@@ -140,15 +140,6 @@
   NodeList<Annotation> get metadata => _metadata;
 
   /**
-   * Set the metadata associated with this node to the given [metadata].
-   */
-  @deprecated // Directly modify the list returned by "this.metadata"
-  void set metadata(List<Annotation> metadata) {
-    _metadata.clear();
-    _metadata.addAll(metadata);
-  }
-
-  /**
    * Return a list containing the comment and annotations associated with this
    * node, sorted in lexical order.
    */
@@ -465,37 +456,6 @@
   @override
   accept(AstVisitor visitor) => visitor.visitArgumentList(this);
 
-  /**
-   * If
-   * * the given [expression] is a child of this list,
-   * * the AST structure has been resolved,
-   * * the function being invoked is known based on propagated type information,
-   *   and
-   * * the expression corresponds to one of the parameters of the function being
-   *   invoked,
-   * then return the parameter element representing the parameter to which the
-   * value of the given expression will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement getPropagatedParameterElementFor(Expression expression) {
-    return _getPropagatedParameterElementFor(expression);
-  }
-
-  /**
-   * If
-   * * the given [expression] is a child of this list,
-   * * the AST structure has been resolved,
-   * * the function being invoked is known based on static type information, and
-   * * the expression corresponds to one of the parameters of the function being
-   *   invoked,
-   * then return the parameter element representing the parameter to which the
-   * value of the given expression will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.staticParameterElement"
-  ParameterElement getStaticParameterElementFor(Expression expression) {
-    return _getStaticParameterElementFor(expression);
-  }
-
   @override
   void visitChildren(AstVisitor visitor) {
     _arguments.accept(visitor);
@@ -656,6 +616,17 @@
   Expression _condition;
 
   /**
+   * The comma, if a message expression was supplied.  Otherwise `null`.
+   */
+  Token comma;
+
+  /**
+   * The message to report if the assertion fails.  `null` if no message was
+   * supplied.
+   */
+  Expression _message;
+
+  /**
    * The right parenthesis.
    */
   Token rightParenthesis;
@@ -668,9 +639,16 @@
   /**
    * Initialize a newly created assert statement.
    */
-  AssertStatement(this.assertKeyword, this.leftParenthesis,
-      Expression condition, this.rightParenthesis, this.semicolon) {
+  AssertStatement(
+      this.assertKeyword,
+      this.leftParenthesis,
+      Expression condition,
+      this.comma,
+      Expression message,
+      this.rightParenthesis,
+      this.semicolon) {
     _condition = _becomeParentOf(condition);
+    _message = _becomeParentOf(message);
   }
 
   @override
@@ -681,6 +659,8 @@
     ..add(assertKeyword)
     ..add(leftParenthesis)
     ..add(_condition)
+    ..add(comma)
+    ..add(_message)
     ..add(rightParenthesis)
     ..add(semicolon);
 
@@ -701,17 +681,16 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token representing the 'assert' keyword.
+   * Return the message to report if the assertion fails.
    */
-  @deprecated // Use "this.assertKeyword"
-  Token get keyword => assertKeyword;
+  Expression get message => _message;
 
   /**
-   * Set the token representing the 'assert' keyword to the given [token].
+   * Set the message to report if the assertion fails to the given
+   * [expression].
    */
-  @deprecated // Use "this.assertKeyword"
-  set keyword(Token token) {
-    assertKeyword = token;
+  void set message(Expression expression) {
+    _message = _becomeParentOf(expression);
   }
 
   @override
@@ -720,6 +699,7 @@
   @override
   void visitChildren(AstVisitor visitor) {
     _safelyVisitChild(_condition, visitor);
+    _safelyVisitChild(message, visitor);
   }
 }
 
@@ -828,17 +808,6 @@
   int get precedence => 1;
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the right operand
-   * will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForRightHandSide {
-    return _propagatedParameterElementForRightHandSide;
-  }
-
-  /**
    * Return the expression used to compute the right hand side.
    */
   Expression get rightHandSide => _rightHandSide;
@@ -853,17 +822,6 @@
 
   /**
    * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the right operand will be
-   * bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.staticParameterElement"
-  ParameterElement get staticParameterElementForRightHandSide {
-    return _staticParameterElementForRightHandSide;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
    * known based on propagated type information, then return the parameter
    * element representing the parameter to which the value of the right operand
    * will be bound. Otherwise, return `null`.
@@ -1037,6 +995,8 @@
       cloneToken(node.assertKeyword),
       cloneToken(node.leftParenthesis),
       cloneNode(node.condition),
+      cloneToken(node.comma),
+      cloneNode(node.message),
       cloneToken(node.rightParenthesis),
       cloneToken(node.semicolon));
 
@@ -1163,6 +1123,16 @@
           cloneNode(node.elseExpression));
 
   @override
+  Configuration visitConfiguration(Configuration node) => new Configuration(
+      cloneToken(node.ifKeyword),
+      cloneToken(node.leftParenthesis),
+      cloneNode(node.name),
+      cloneToken(node.equalToken),
+      cloneNode(node.value),
+      cloneToken(node.rightParenthesis),
+      cloneNode(node.libraryUri));
+
+  @override
   ConstructorDeclaration visitConstructorDeclaration(
           ConstructorDeclaration node) =>
       new ConstructorDeclaration(
@@ -1226,6 +1196,10 @@
       cloneToken(node.semicolon));
 
   @override
+  DottedName visitDottedName(DottedName node) =>
+      new DottedName(cloneNodeList(node.components));
+
+  @override
   DoubleLiteral visitDoubleLiteral(DoubleLiteral node) =>
       new DoubleLiteral(cloneToken(node.literal), node.value);
 
@@ -1260,6 +1234,7 @@
         cloneNodeList(node.metadata),
         cloneToken(node.keyword),
         cloneNode(node.uri),
+        cloneNodeList(node.configurations),
         cloneNodeList(node.combinators),
         cloneToken(node.semicolon));
     directive.source = node.source;
@@ -1430,6 +1405,7 @@
         cloneNodeList(node.metadata),
         cloneToken(node.keyword),
         cloneNode(node.uri),
+        cloneNodeList(node.configurations),
         cloneToken(node.deferredKeyword),
         cloneToken(node.asKeyword),
         cloneNode(node.prefix),
@@ -1893,6 +1869,8 @@
     return isEqualTokens(node.assertKeyword, other.assertKeyword) &&
         isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
         isEqualNodes(node.condition, other.condition) &&
+        isEqualTokens(node.comma, other.comma) &&
+        isEqualNodes(node.message, other.message) &&
         isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
         isEqualTokens(node.semicolon, other.semicolon);
   }
@@ -2039,6 +2017,18 @@
   }
 
   @override
+  bool visitConfiguration(Configuration node) {
+    Configuration other = _other as Configuration;
+    return isEqualTokens(node.ifKeyword, other.ifKeyword) &&
+        isEqualTokens(node.leftParenthesis, other.leftParenthesis) &&
+        isEqualNodes(node.name, other.name) &&
+        isEqualTokens(node.equalToken, other.equalToken) &&
+        isEqualNodes(node.value, other.value) &&
+        isEqualTokens(node.rightParenthesis, other.rightParenthesis) &&
+        isEqualNodes(node.libraryUri, other.libraryUri);
+  }
+
+  @override
   bool visitConstructorDeclaration(ConstructorDeclaration node) {
     ConstructorDeclaration other = _other as ConstructorDeclaration;
     return isEqualNodes(
@@ -2116,6 +2106,12 @@
   }
 
   @override
+  bool visitDottedName(DottedName node) {
+    DottedName other = _other as DottedName;
+    return _isEqualNodeLists(node.components, other.components);
+  }
+
+  @override
   bool visitDoubleLiteral(DoubleLiteral node) {
     DoubleLiteral other = _other as DoubleLiteral;
     return isEqualTokens(node.literal, other.literal) &&
@@ -2868,12 +2864,6 @@
   /**
    * An empty list of AST nodes.
    */
-  @deprecated // Use "AstNode.EMPTY_LIST"
-  static const List<AstNode> EMPTY_ARRAY = EMPTY_LIST;
-
-  /**
-   * An empty list of AST nodes.
-   */
   static const List<AstNode> EMPTY_LIST = const <AstNode>[];
 
   /**
@@ -2883,8 +2873,8 @@
    * the same offset, and a positive value if the offset of the first node is
    * greater than the offset of the second node.
    */
-  static Comparator<AstNode> LEXICAL_ORDER = (AstNode first, AstNode second) =>
-      first.offset - second.offset;
+  static Comparator<AstNode> LEXICAL_ORDER =
+      (AstNode first, AstNode second) => first.offset - second.offset;
 
   /**
    * The parent of the node, or `null` if the node is the root of an AST
@@ -2966,14 +2956,6 @@
   AstNode get parent => _parent;
 
   /**
-   * Set the parent of this node to the [newParent].
-   */
-  @deprecated // Never intended for public use.
-  void set parent(AstNode newParent) {
-    _parent = newParent;
-  }
-
-  /**
    * Return the node at the root of this node's AST structure. Note that this
    * method's performance is linear with respect to the depth of the node in the
    * AST structure (O(depth)).
@@ -2992,15 +2974,7 @@
    * Use the given [visitor] to visit this node. Return the value returned by
    * the visitor as a result of visiting this node.
    */
-  /* <E> E */ accept(AstVisitor /*<E>*/ visitor);
-
-  /**
-   * Make this node the parent of the given [child] node. Return the child node.
-   */
-  @deprecated // Never intended for public use.
-  AstNode becomeParentOf(AstNode child) {
-    return _becomeParentOf(child);
-  }
+  dynamic /*=E*/ accept /*<E>*/ (AstVisitor /*<E>*/ visitor);
 
   /**
    * Return the most immediate ancestor of this node for which the [predicate]
@@ -3028,16 +3002,6 @@
   }
 
   /**
-   * If the given [child] is not `null`, use the given [visitor] to visit it.
-   */
-  @deprecated // Never intended for public use.
-  void safelyVisitChild(AstNode child, AstVisitor visitor) {
-    if (child != null) {
-      child.accept(visitor);
-    }
-  }
-
-  /**
    * Set the value of the property with the given [name] to the given [value].
    * If the value is `null`, the property will effectively be removed.
    */
@@ -3141,6 +3105,8 @@
 
   R visitConditionalExpression(ConditionalExpression node);
 
+  R visitConfiguration(Configuration node);
+
   R visitConstructorDeclaration(ConstructorDeclaration node);
 
   R visitConstructorFieldInitializer(ConstructorFieldInitializer node);
@@ -3155,6 +3121,8 @@
 
   R visitDoStatement(DoStatement node);
 
+  R visitDottedName(DottedName node);
+
   R visitDoubleLiteral(DoubleLiteral node);
 
   R visitEmptyFunctionBody(EmptyFunctionBody node);
@@ -3466,17 +3434,6 @@
   int get precedence => operator.type.precedence;
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the right operand
-   * will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForRightOperand {
-    return _propagatedParameterElementForRightOperand;
-  }
-
-  /**
    * Return the expression used to compute the right operand.
    */
   Expression get rightOperand => _rightOperand;
@@ -3491,17 +3448,6 @@
 
   /**
    * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the right operand will be
-   * bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.staticParameterElement"
-  ParameterElement get staticParameterElementForRightOperand {
-    return _staticParameterElementForRightOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
    * known based on propagated type information, then return the parameter
    * element representing the parameter to which the value of the right operand
    * will be bound. Otherwise, return `null`.
@@ -3828,20 +3774,6 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token representing the 'break' keyword.
-   */
-  @deprecated // Use "this.breakKeyword"
-  Token get keyword => breakKeyword;
-
-  /**
-   * Set the token representing the 'break' keyword to the given [token].
-   */
-  @deprecated // Use "this.breakKeyword"
-  void set keyword(Token token) {
-    breakKeyword = token;
-  }
-
-  /**
    * Return the label associated with the statement, or `null` if there is no
    * label.
    */
@@ -5115,6 +5047,85 @@
   }
 }
 
+/**
+ * A configuration in either an import or export directive.
+ *
+ *     configuration ::=
+ *         'if' '(' test ')' uri
+ *
+ *     test ::=
+ *         dottedName ('==' stringLiteral)?
+ *
+ *     dottedName ::=
+ *         identifier ('.' identifier)*
+ */
+class Configuration extends AstNode {
+  Token ifKeyword;
+  Token leftParenthesis;
+  DottedName _name;
+  Token equalToken;
+  StringLiteral _value;
+  Token rightParenthesis;
+  StringLiteral _libraryUri;
+
+  Configuration(
+      this.ifKeyword,
+      this.leftParenthesis,
+      DottedName name,
+      this.equalToken,
+      StringLiteral value,
+      this.rightParenthesis,
+      StringLiteral libraryUri) {
+    _name = _becomeParentOf(name);
+    _value = _becomeParentOf(value);
+    _libraryUri = _becomeParentOf(libraryUri);
+  }
+
+  @override
+  Token get beginToken => ifKeyword;
+
+  @override
+  Iterable get childEntities => new ChildEntities()
+    ..add(ifKeyword)
+    ..add(leftParenthesis)
+    ..add(_name)
+    ..add(equalToken)
+    ..add(_value)
+    ..add(rightParenthesis)
+    ..add(_libraryUri);
+
+  @override
+  Token get endToken => _libraryUri.endToken;
+
+  StringLiteral get libraryUri => _libraryUri;
+
+  void set libraryUri(StringLiteral libraryUri) {
+    _libraryUri = _becomeParentOf(libraryUri);
+  }
+
+  DottedName get name => _name;
+
+  void set name(DottedName name) {
+    _name = _becomeParentOf(name);
+  }
+
+  StringLiteral get value => _value;
+
+  void set value(StringLiteral value) {
+    _value = _becomeParentOf(value);
+  }
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitConfiguration(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _safelyVisitChild(_name, visitor);
+    _safelyVisitChild(_value, visitor);
+    _safelyVisitChild(_libraryUri, visitor);
+  }
+}
+
 /// Instances of the class [ConstantEvaluator] evaluate constant expressions to
 /// produce their compile-time value.
 ///
@@ -5824,21 +5835,6 @@
     _fieldName = _becomeParentOf(identifier);
   }
 
-  /**
-   * Return the token for the 'this' keyword, or `null` if there is no 'this'
-   * keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get keyword => thisKeyword;
-
-  /**
-   * Set the token for the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set keyword(Token token) {
-    thisKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitConstructorFieldInitializer(this);
 
@@ -6001,21 +5997,6 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token for the 'continue' keyword, or `null` if there is no
-   * 'continue' keyword.
-   */
-  @deprecated // Use "this.continueKeyword"
-  Token get keyword => continueKeyword;
-
-  /**
-   * Set the token for the 'continue' keyword to the given [token].
-   */
-  @deprecated // Use "this.continueKeyword"
-  set keyword(Token token) {
-    continueKeyword = token;
-  }
-
-  /**
    * Return the label associated with the statement, or `null` if there is no
    * label.
    */
@@ -6135,7 +6116,8 @@
   /**
    * Return `true` if this variable was declared with the 'const' modifier.
    */
-  bool get isConst => (keyword is KeywordToken) &&
+  bool get isConst =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   /**
@@ -6143,7 +6125,8 @@
    * Variables that are declared with the 'const' modifier will return `false`
    * even though they are implicitly final.
    */
-  bool get isFinal => (keyword is KeywordToken) &&
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -6450,6 +6433,49 @@
 }
 
 /**
+ * A dotted name, used in a configuration within an import or export directive.
+ *
+ * > dottedName ::=
+ * >     [SimpleIdentifier] ('.' [SimpleIdentifier])*
+ */
+class DottedName extends AstNode {
+  /**
+   * The components of the identifier.
+   */
+  NodeList<SimpleIdentifier> _components;
+
+  /**
+   * Initialize a newly created dotted name.
+   */
+  DottedName(List<SimpleIdentifier> components) {
+    _components = new NodeList<SimpleIdentifier>(this, components);
+  }
+
+  @override
+  Token get beginToken => _components.beginToken;
+
+  @override
+  // TODO(paulberry): add "." tokens.
+  Iterable get childEntities => new ChildEntities()..addAll(_components);
+
+  /**
+   * Return the components of the identifier.
+   */
+  NodeList<SimpleIdentifier> get components => _components;
+
+  @override
+  Token get endToken => _components.endToken;
+
+  @override
+  accept(AstVisitor visitor) => visitor.visitDottedName(this);
+
+  @override
+  void visitChildren(AstVisitor visitor) {
+    _components.accept(visitor);
+  }
+}
+
+/**
  * A floating point literal expression.
  *
  * > doubleLiteral ::=
@@ -6818,21 +6844,6 @@
   @override
   Token get firstTokenAfterCommentAndMetadata => enumKeyword;
 
-  /**
-   * Return the token for the 'enum' keyword, or `null` if there is no
-   * 'enum' keyword.
-   */
-  @deprecated // Use "this.enumKeyword"
-  Token get keyword => enumKeyword;
-
-  /**
-   * Set the token for the 'enum' keyword to the given [token].
-   */
-  @deprecated // Use "this.enumKeyword"
-  set keyword(Token token) {
-    enumKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitEnumDeclaration(this);
 
@@ -6868,9 +6879,16 @@
    * corresponding attribute. The list of [combinators] can be `null` if there
    * are no combinators.
    */
-  ExportDirective(Comment comment, List<Annotation> metadata, Token keyword,
-      StringLiteral libraryUri, List<Combinator> combinators, Token semicolon)
-      : super(comment, metadata, keyword, libraryUri, combinators, semicolon);
+  ExportDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      Token keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      Token semicolon)
+      : super(comment, metadata, keyword, libraryUri, configurations,
+            combinators, semicolon);
 
   @override
   Iterable get childEntities => super._childEntities
@@ -6911,12 +6929,6 @@
   /**
    * An empty list of expressions.
    */
-  @deprecated // Use "Expression.EMPTY_LIST"
-  static const List<Expression> EMPTY_ARRAY = EMPTY_LIST;
-
-  /**
-   * An empty list of expressions.
-   */
   static const List<Expression> EMPTY_LIST = const <Expression>[];
 
   /**
@@ -7239,20 +7251,6 @@
   Token get endToken => _superclass.endToken;
 
   /**
-   * Return the token for the 'extends' keyword.
-   */
-  @deprecated // Use "this.extendsKeyword"
-  Token get keyword => extendsKeyword;
-
-  /**
-   * Set the token for the 'extends' keyword to the given [token].
-   */
-  @deprecated // Use "this.extendsKeyword"
-  set keyword(Token token) {
-    extendsKeyword = token;
-  }
-
-  /**
    * Return the name of the class that is being extended.
    */
   TypeName get superclass => _superclass;
@@ -7448,11 +7446,13 @@
   }
 
   @override
-  bool get isConst => (keyword is KeywordToken) &&
+  bool get isConst =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   @override
-  bool get isFinal => (keyword is KeywordToken) &&
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -7470,20 +7470,6 @@
   }
 
   /**
-   * Return the token representing the 'this' keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get thisToken => thisKeyword;
-
-  /**
-   * Set the token representing the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set thisToken(Token token) {
-    thisKeyword = token;
-  }
-
-  /**
    * Return the name of the declared type of the parameter, or `null` if the
    * parameter does not have a declared type. Note that if this is a
    * function-typed field formal parameter this is the return type of the
@@ -7581,44 +7567,6 @@
   Statement _body;
 
   /**
-   * Initialize a newly created for-each statement. The [awaitKeyword] can be
-   * `null` if this is not an asynchronous for loop.
-   */
-  @deprecated // Use new ForEachStatement.withDeclaration(...)
-  ForEachStatement.con1(
-      this.awaitKeyword,
-      this.forKeyword,
-      this.leftParenthesis,
-      DeclaredIdentifier loopVariable,
-      this.inKeyword,
-      Expression iterator,
-      this.rightParenthesis,
-      Statement body) {
-    _loopVariable = _becomeParentOf(loopVariable);
-    _iterable = _becomeParentOf(iterator);
-    _body = _becomeParentOf(body);
-  }
-
-  /**
-   * Initialize a newly created for-each statement. The [awaitKeyword] can be
-   * `null` if this is not an asynchronous for loop.
-   */
-  @deprecated // Use new ForEachStatement.withReference(...)
-  ForEachStatement.con2(
-      this.awaitKeyword,
-      this.forKeyword,
-      this.leftParenthesis,
-      SimpleIdentifier identifier,
-      this.inKeyword,
-      Expression iterator,
-      this.rightParenthesis,
-      Statement body) {
-    _identifier = _becomeParentOf(identifier);
-    _iterable = _becomeParentOf(iterator);
-    _body = _becomeParentOf(body);
-  }
-
-  /**
    * Initialize a newly created for-each statement whose loop control variable
    * is declared internally (in the for-loop part). The [awaitKeyword] can be
    * `null` if this is not an asynchronous for loop.
@@ -7713,12 +7661,6 @@
   }
 
   /**
-   * Return the expression evaluated to produce the iterator.
-   */
-  @deprecated // Use "this.iterable"
-  Expression get iterator => iterable;
-
-  /**
    * Return the declaration of the loop variable, or `null` if the loop variable
    * is a simple identifier.
    */
@@ -8224,13 +8166,15 @@
   /**
    * Return `true` if this function declares a getter.
    */
-  bool get isGetter => propertyKeyword != null &&
+  bool get isGetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.GET;
 
   /**
    * Return `true` if this function declares a setter.
    */
-  bool get isSetter => propertyKeyword != null &&
+  bool get isSetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.SET;
 
   /**
@@ -8879,6 +8823,9 @@
       visitExpression(node);
 
   @override
+  R visitConfiguration(Configuration node) => visitNode(node);
+
+  @override
   R visitConstructorDeclaration(ConstructorDeclaration node) =>
       visitClassMember(node);
 
@@ -8909,6 +8856,9 @@
   R visitDoStatement(DoStatement node) => visitStatement(node);
 
   @override
+  R visitDottedName(DottedName node) => visitNode(node);
+
+  @override
   R visitDoubleLiteral(DoubleLiteral node) => visitLiteral(node);
 
   @override
@@ -9491,20 +9441,6 @@
    */
   NodeList<TypeName> get interfaces => _interfaces;
 
-  /**
-   * Return the token representing the 'implements' keyword.
-   */
-  @deprecated // Use "this.implementsKeyword"
-  Token get keyword => implementsKeyword;
-
-  /**
-   * Set the token representing the 'implements' keyword to the given [token].
-   */
-  @deprecated // Use "this.implementsKeyword"
-  set keyword(Token token) {
-    implementsKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitImplementsClause(this);
 
@@ -9647,30 +9583,17 @@
       List<Annotation> metadata,
       Token keyword,
       StringLiteral libraryUri,
+      List<Configuration> configurations,
       this.deferredKeyword,
       this.asKeyword,
       SimpleIdentifier prefix,
       List<Combinator> combinators,
       Token semicolon)
-      : super(comment, metadata, keyword, libraryUri, combinators, semicolon) {
+      : super(comment, metadata, keyword, libraryUri, configurations,
+            combinators, semicolon) {
     _prefix = _becomeParentOf(prefix);
   }
 
-  /**
-   * The token representing the 'as' token, or `null` if the imported names are
-   * not prefixed.
-   */
-  @deprecated // Use "this.asKeyword"
-  Token get asToken => asKeyword;
-
-  /**
-   * The token representing the 'as' token to the given token.
-   */
-  @deprecated // Use "this.asKeyword"
-  set asToken(Token token) {
-    asKeyword = token;
-  }
-
   @override
   Iterable get childEntities => super._childEntities
     ..add(_uri)
@@ -9680,21 +9603,6 @@
     ..addAll(combinators)
     ..add(semicolon);
 
-  /**
-   * Return the token representing the 'deferred' token, or `null` if the
-   * imported is not deferred.
-   */
-  @deprecated // Use "this.deferredKeyword"
-  Token get deferredToken => deferredKeyword;
-
-  /**
-   * Set the token representing the 'deferred' token to the given token.
-   */
-  @deprecated // Use "this.deferredKeyword"
-  set deferredToken(Token token) {
-    deferredKeyword = token;
-  }
-
   @override
   ImportElement get element => super.element as ImportElement;
 
@@ -9796,6 +9704,8 @@
       _mapToken(node.assertKeyword),
       _mapToken(node.leftParenthesis),
       _cloneNode(node.condition),
+      _mapToken(node.comma),
+      _cloneNode(node.message),
       _mapToken(node.rightParenthesis),
       _mapToken(node.semicolon));
 
@@ -9949,6 +9859,16 @@
   }
 
   @override
+  Configuration visitConfiguration(Configuration node) => new Configuration(
+      _mapToken(node.ifKeyword),
+      _mapToken(node.leftParenthesis),
+      _cloneNode(node.name),
+      _mapToken(node.equalToken),
+      _cloneNode(node.value),
+      _mapToken(node.rightParenthesis),
+      _cloneNode(node.libraryUri));
+
+  @override
   ConstructorDeclaration visitConstructorDeclaration(
       ConstructorDeclaration node) {
     ConstructorDeclaration copy = new ConstructorDeclaration(
@@ -10018,6 +9938,10 @@
       _mapToken(node.semicolon));
 
   @override
+  DottedName visitDottedName(DottedName node) =>
+      new DottedName(_cloneNodeList(node.components));
+
+  @override
   DoubleLiteral visitDoubleLiteral(DoubleLiteral node) {
     DoubleLiteral copy = new DoubleLiteral(_mapToken(node.literal), node.value);
     copy.propagatedType = node.propagatedType;
@@ -10055,6 +9979,7 @@
         _cloneNodeList(node.metadata),
         _mapToken(node.keyword),
         _cloneNode(node.uri),
+        _cloneNodeList(node.configurations),
         _cloneNodeList(node.combinators),
         _mapToken(node.semicolon));
     copy.element = node.element;
@@ -10239,6 +10164,7 @@
           _cloneNodeList(node.metadata),
           _mapToken(node.keyword),
           _cloneNode(node.uri),
+          _cloneNodeList(node.configurations),
           _mapToken(node.deferredKeyword),
           _mapToken(node.asKeyword),
           _cloneNode(node.prefix),
@@ -10905,17 +10831,6 @@
   int get precedence => 15;
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the index
-   * expression will be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForIndex {
-    return _propagatedParameterElementForIndex;
-  }
-
-  /**
    * Return the expression used to compute the object being indexed. If this
    * index expression is not part of a cascade expression, then this is the same
    * as [target]. If this index expression is part of a cascade expression, then
@@ -10936,17 +10851,6 @@
   }
 
   /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the index expression will
-   * be bound. Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get staticParameterElementForIndex {
-    return _staticParameterElementForIndex;
-  }
-
-  /**
    * Return the expression used to compute the object being indexed, or `null`
    * if this index expression is part of a cascade expression.
    *
@@ -11130,7 +11034,8 @@
    * Return `true` if this creation expression is used to invoke a constant
    * constructor.
    */
-  bool get isConst => keyword is KeywordToken &&
+  bool get isConst =>
+      keyword is KeywordToken &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   @override
@@ -11594,20 +11499,6 @@
   Token get keyword => libraryKeyword;
 
   /**
-   * Return the token representing the 'library' token.
-   */
-  @deprecated // Use "this.libraryKeyword"
-  Token get libraryToken => libraryKeyword;
-
-  /**
-   * Set the token representing the 'library' token to the given [token].
-   */
-  @deprecated // Use "this.libraryKeyword"
-  set libraryToken(Token token) {
-    libraryKeyword = token;
-  }
-
-  /**
    * Return the name of the library being defined.
    */
   LibraryIdentifier get name => _name;
@@ -12096,7 +11987,8 @@
   /**
    * Return `true` if this method declares a getter.
    */
-  bool get isGetter => propertyKeyword != null &&
+  bool get isGetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.GET;
 
   /**
@@ -12107,13 +11999,15 @@
   /**
    * Return `true` if this method declares a setter.
    */
-  bool get isSetter => propertyKeyword != null &&
+  bool get isSetter =>
+      propertyKeyword != null &&
       (propertyKeyword as KeywordToken).keyword == Keyword.SET;
 
   /**
    * Return `true` if this method is declared to be a static method.
    */
-  bool get isStatic => modifierKeyword != null &&
+  bool get isStatic =>
+      modifierKeyword != null &&
       (modifierKeyword as KeywordToken).keyword == Keyword.STATIC;
 
   /**
@@ -12291,26 +12185,6 @@
     _methodName = _becomeParentOf(identifier);
   }
 
-  /**
-   * The operator that separates the target from the method name, or `null`
-   * if there is no target. In an ordinary method invocation this will be a
-   * period ('.'). In a cascade section this will be the cascade operator
-   * ('..').
-   */
-  @deprecated // Use this.operator
-  Token get period => operator;
-
-  /**
-   * The operator that separates the target from the method name, or `null`
-   * if there is no target. In an ordinary method invocation this will be a
-   * period ('.'). In a cascade section this will be the cascade operator
-   * ('..').
-   */
-  @deprecated // Use this.operator
-  void set period(Token value) {
-    operator = value;
-  }
-
   @override
   int get precedence => 15;
 
@@ -12512,6 +12386,12 @@
   Token keyword;
 
   /**
+   * The configurations used to control which library will actually be loaded at
+   * run-time.
+   */
+  NodeList<Configuration> _configurations;
+
+  /**
    * The combinators used to control which names are imported or exported.
    */
   NodeList<Combinator> _combinators;
@@ -12527,9 +12407,16 @@
    * corresponding attribute. The list of [combinators] can be `null` if there
    * are no combinators.
    */
-  NamespaceDirective(Comment comment, List<Annotation> metadata, this.keyword,
-      StringLiteral libraryUri, List<Combinator> combinators, this.semicolon)
+  NamespaceDirective(
+      Comment comment,
+      List<Annotation> metadata,
+      this.keyword,
+      StringLiteral libraryUri,
+      List<Configuration> configurations,
+      List<Combinator> combinators,
+      this.semicolon)
       : super(comment, metadata, libraryUri) {
+    _configurations = new NodeList<Configuration>(this, configurations);
     _combinators = new NodeList<Combinator>(this, combinators);
   }
 
@@ -12538,6 +12425,12 @@
    */
   NodeList<Combinator> get combinators => _combinators;
 
+  /**
+   * Return the configurations used to control which library will actually be
+   * loaded at run-time.
+   */
+  NodeList<Configuration> get configurations => _configurations;
+
   @override
   Token get endToken => semicolon;
 
@@ -12583,20 +12476,6 @@
   Token get endToken => _name.endToken;
 
   /**
-   * Get the token representing the 'native' keyword.
-   */
-  @deprecated // Use "this.nativeKeyword"
-  Token get keyword => nativeKeyword;
-
-  /**
-   * Set the token representing the 'native' keyword to the given [token].
-   */
-  @deprecated // Use "this.nativeKeyword"
-  set keyword(Token token) {
-    nativeKeyword = token;
-  }
-
-  /**
    * Return the name of the native object that implements the class.
    */
   StringLiteral get name => _name;
@@ -12664,22 +12543,6 @@
   Token get endToken => semicolon;
 
   /**
-   * Return the token representing 'native' that marks the start of the function
-   * body.
-   */
-  @deprecated // Use "this.nativeKeyword"
-  Token get nativeToken => nativeKeyword;
-
-  /**
-   * Set the token representing 'native' that marks the start of the function
-   * body to the given [token].
-   */
-  @deprecated // Use "this.nativeKeyword"
-  set nativeToken(Token token) {
-    nativeKeyword = token;
-  }
-
-  /**
    * Return the string literal representing the string after the 'native' token.
    */
   StringLiteral get stringLiteral => _stringLiteral;
@@ -12750,7 +12613,8 @@
   int get length => _elements.length;
 
   @deprecated // Never intended for public use.
-  void set length(int value) {
+  @override
+  void set length(int newLength) {
     throw new UnsupportedError("Cannot resize NodeList.");
   }
 
@@ -12824,12 +12688,6 @@
     _elements.removeAt(index);
     return removedNode;
   }
-
-  /**
-   * Create an empty list with the given [owner].
-   */
-  @deprecated // Use "new NodeList<E>(owner)"
-  static NodeList create(AstNode owner) => new NodeList(owner);
 }
 
 /**
@@ -12865,22 +12723,6 @@
         this._endOffset = endOffset == null ? startOffset : endOffset;
 
   /**
-   * Initialize a newly created locator to locate an [AstNode] by locating the
-   * node within an AST structure that corresponds to the given [offset] in the
-   * source.
-   */
-  @deprecated // Use new NodeLocator(offset)
-  NodeLocator.con1(int offset) : this(offset);
-
-  /**
-   * Initialize a newly created locator to locate an [AstNode] by locating the
-   * node within an AST structure that corresponds to the given range of
-   * characters (between the [startOffset] and [endOffset] in the source.
-   */
-  @deprecated // Use new NodeLocator(startOffset, endOffset)
-  NodeLocator.con2(this._startOffset, this._endOffset);
-
-  /**
    * Return the node that was found that corresponds to the given source range
    * or `null` if there is no such node.
    */
@@ -13120,6 +12962,10 @@
       node.condition = _newNode as Expression;
       return true;
     }
+    if (identical(node._message, _oldNode)) {
+      node.message = _newNode as Expression;
+      return true;
+    }
     return visitNode(node);
   }
 
@@ -13304,6 +13150,21 @@
   }
 
   @override
+  bool visitConfiguration(Configuration node) {
+    if (identical(node.name, _oldNode)) {
+      node.name = _newNode as DottedName;
+      return true;
+    } else if (identical(node.value, _oldNode)) {
+      node.value = _newNode as StringLiteral;
+      return true;
+    } else if (identical(node.libraryUri, _oldNode)) {
+      node.libraryUri = _newNode as StringLiteral;
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitConstructorDeclaration(ConstructorDeclaration node) {
     if (identical(node.returnType, _oldNode)) {
       node.returnType = _newNode as Identifier;
@@ -13396,6 +13257,14 @@
   }
 
   @override
+  bool visitDottedName(DottedName node) {
+    if (_replaceInList(node.components)) {
+      return true;
+    }
+    return visitNode(node);
+  }
+
+  @override
   bool visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
 
   @override
@@ -14479,20 +14348,6 @@
   @override
   Token get keyword => partKeyword;
 
-  /**
-   * Return the token representing the 'part' token.
-   */
-  @deprecated // Use "this.partKeyword"
-  Token get partToken => partKeyword;
-
-  /**
-   * Set the token representing the 'part' token to the given [token].
-   */
-  @deprecated // Use "this.partKeyword"
-  set partToken(Token token) {
-    partKeyword = token;
-  }
-
   @override
   CompilationUnitElement get uriElement => element as CompilationUnitElement;
 
@@ -14568,34 +14423,6 @@
     _libraryName = _becomeParentOf(libraryName);
   }
 
-  /**
-   * Return the token representing the 'of' token.
-   */
-  @deprecated // Use "this.ofKeyword"
-  Token get ofToken => ofKeyword;
-
-  /**
-   * Set the token representing the 'of' token to the given [token].
-   */
-  @deprecated // Use "this.ofKeyword"
-  set ofToken(Token token) {
-    ofKeyword = token;
-  }
-
-  /**
-   * Return the token representing the 'part' token.
-   */
-  @deprecated // Use "this.partKeyword"
-  Token get partToken => partKeyword;
-
-  /**
-   * Set the token representing the 'part' token to the given [token].
-   */
-  @deprecated // Use "this.partKeyword"
-  set partToken(Token token) {
-    partKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitPartOfDirective(this);
 
@@ -14692,28 +14519,6 @@
    * element representing the parameter to which the value of the operand will
    * be bound. Otherwise, return `null`.
    */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForOperand {
-    return _propagatedParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the operand will be bound.
-   * Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get staticParameterElementForOperand {
-    return _staticParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the operand will
-   * be bound. Otherwise, return `null`.
-   */
   ParameterElement get _propagatedParameterElementForOperand {
     if (propagatedElement == null) {
       return null;
@@ -14965,28 +14770,6 @@
    * element representing the parameter to which the value of the operand will
    * be bound. Otherwise, return `null`.
    */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get propagatedParameterElementForOperand {
-    return _propagatedParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on static type information, then return the parameter element
-   * representing the parameter to which the value of the operand will be bound.
-   * Otherwise, return `null`.
-   */
-  @deprecated // Use "expression.propagatedParameterElement"
-  ParameterElement get staticParameterElementForOperand {
-    return _staticParameterElementForOperand;
-  }
-
-  /**
-   * If the AST structure has been resolved, and the function being invoked is
-   * known based on propagated type information, then return the parameter
-   * element representing the parameter to which the value of the operand will
-   * be bound. Otherwise, return `null`.
-   */
   ParameterElement get _propagatedParameterElementForOperand {
     if (propagatedElement == null) {
       return null;
@@ -15279,6 +15062,12 @@
   }
 
   @override
+  R visitConfiguration(Configuration node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitConstructorDeclaration(ConstructorDeclaration node) {
     node.visitChildren(this);
     return null;
@@ -15321,6 +15110,12 @@
   }
 
   @override
+  R visitDottedName(DottedName node) {
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   R visitDoubleLiteral(DoubleLiteral node) {
     node.visitChildren(this);
     return null;
@@ -15883,20 +15678,6 @@
   @override
   Token get endToken => _argumentList.endToken;
 
-  /**
-   * Return the token for the 'this' keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get keyword => thisKeyword;
-
-  /**
-   * Set the token for the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set keyword(Token token) {
-    thisKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) =>
       visitor.visitRedirectingConstructorInvocation(this);
@@ -15934,20 +15715,6 @@
   @override
   Token get endToken => rethrowKeyword;
 
-  /**
-   * Return the token representing the 'rethrow' keyword.
-   */
-  @deprecated // Use "this.rethrowKeyword"
-  Token get keyword => rethrowKeyword;
-
-  /**
-   * Set the token representing the 'rethrow' keyword to the given [token].
-   */
-  @deprecated // Use "this.rethrowKeyword"
-  set keyword(Token token) {
-    rethrowKeyword = token;
-  }
-
   @override
   int get precedence => 0;
 
@@ -16015,20 +15782,6 @@
     _expression = _becomeParentOf(expression);
   }
 
-  /**
-   * Return the token representing the 'return' keyword.
-   */
-  @deprecated // Use "this.returnKeyword"
-  Token get keyword => returnKeyword;
-
-  /**
-   * Set the token representing the 'return' keyword to the given [token].
-   */
-  @deprecated // Use "this.returnKeyword"
-  set keyword(Token token) {
-    returnKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitReturnStatement(this);
 
@@ -16370,6 +16123,9 @@
   R visitConditionalExpression(ConditionalExpression node) => null;
 
   @override
+  R visitConfiguration(Configuration node) => null;
+
+  @override
   R visitConstructorDeclaration(ConstructorDeclaration node) => null;
 
   @override
@@ -16391,6 +16147,9 @@
   R visitDoStatement(DoStatement node) => null;
 
   @override
+  R visitDottedName(DottedName node) => null;
+
+  @override
   R visitDoubleLiteral(DoubleLiteral node) => null;
 
   @override
@@ -16686,11 +16445,13 @@
   Token get endToken => identifier.endToken;
 
   @override
-  bool get isConst => (keyword is KeywordToken) &&
+  bool get isConst =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   @override
-  bool get isFinal => (keyword is KeywordToken) &&
+  bool get isFinal =>
+      (keyword is KeywordToken) &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -17063,12 +16824,6 @@
   String _value;
 
   /**
-   * The toolkit specific element associated with this literal, or `null`.
-   */
-  @deprecated // No replacement
-  Element toolkitElement;
-
-  /**
    * Initialize a newly created simple string literal.
    */
   SimpleStringLiteral(this.literal, String value) {
@@ -17393,14 +17148,6 @@
    * [IllegalArgumentException] if the string is not a constant string without
    * any string interpolation.
    */
-  @deprecated // Use "this.stringValue"
-  void appendStringValue(StringBuffer buffer) => _appendStringValue(buffer);
-
-  /**
-   * Append the value of this string literal to the given [buffer]. Throw an
-   * [IllegalArgumentException] if the string is not a constant string without
-   * any string interpolation.
-   */
   void _appendStringValue(StringBuffer buffer);
 }
 
@@ -17492,20 +17239,6 @@
   @override
   Token get endToken => _argumentList.endToken;
 
-  /**
-   * Return the token for the 'super' keyword.
-   */
-  @deprecated // Use "this.superKeyword"
-  Token get keyword => superKeyword;
-
-  /**
-   * Set the token for the 'super' keyword to the given [token].
-   */
-  @deprecated // Use "this.superKeyword"
-  set keyword(Token token) {
-    superKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitSuperConstructorInvocation(this);
 
@@ -17542,20 +17275,6 @@
   @override
   Token get endToken => superKeyword;
 
-  /**
-   * Return the token for the 'super' keyword.
-   */
-  @deprecated // Use "this.superKeyword"
-  Token get keyword => superKeyword;
-
-  /**
-   * Set the token for the 'super' keyword to the given [token].
-   */
-  @deprecated // Use "this.superKeyword"
-  set keyword(Token token) {
-    superKeyword = token;
-  }
-
   @override
   int get precedence => 16;
 
@@ -17810,20 +17529,6 @@
   }
 
   /**
-   * Return the token representing the 'switch' keyword.
-   */
-  @deprecated // Use "this.switchKeyword"
-  Token get keyword => switchKeyword;
-
-  /**
-   * Set the token representing the 'switch' keyword to the given [token].
-   */
-  @deprecated // Use "this.switchKeyword"
-  set keyword(Token token) {
-    switchKeyword = token;
-  }
-
-  /**
    * Return the switch members that can be selected by the expression.
    */
   NodeList<SwitchMember> get members => _members;
@@ -17907,20 +17612,6 @@
   @override
   Token get endToken => thisKeyword;
 
-  /**
-   * Return the token representing the 'this' keyword.
-   */
-  @deprecated // Use "this.thisKeyword"
-  Token get keyword => thisKeyword;
-
-  /**
-   * Set the token representing the 'this' keyword to the given [token].
-   */
-  @deprecated // Use "this.thisKeyword"
-  set keyword(Token token) {
-    thisKeyword = token;
-  }
-
   @override
   int get precedence => 16;
 
@@ -17985,20 +17676,6 @@
     _expression = _becomeParentOf(expression);
   }
 
-  /**
-   * Return the token representing the 'throw' keyword.
-   */
-  @deprecated // Use "this.throwKeyword"
-  Token get keyword => throwKeyword;
-
-  /**
-   * Set the token representing the 'throw' keyword to the given [token].
-   */
-  @deprecated // Use "this.throwKeyword"
-  set keyword(Token token) {
-    throwKeyword = token;
-  }
-
   @override
   int get precedence => 0;
 
@@ -18127,6 +17804,10 @@
   Object visitAssertStatement(AssertStatement node) {
     _writer.print("assert (");
     _visitNode(node.condition);
+    if (node.message != null) {
+      _writer.print(', ');
+      _visitNode(node.message);
+    }
     _writer.print(");");
     return null;
   }
@@ -18281,6 +17962,16 @@
   }
 
   @override
+  Object visitConfiguration(Configuration node) {
+    _writer.print('if (');
+    _visitNode(node.name);
+    _visitNodeWithPrefix(" == ", node.value);
+    _writer.print(') ');
+    _visitNode(node.libraryUri);
+    return null;
+  }
+
+  @override
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
     _visitNodeListWithSeparatorAndSuffix(node.metadata, " ", " ");
     _visitTokenWithSuffix(node.externalKeyword, " ");
@@ -18350,6 +18041,12 @@
   }
 
   @override
+  Object visitDottedName(DottedName node) {
+    _visitNodeListWithSeparator(node.components, ".");
+    return null;
+  }
+
+  @override
   Object visitDoubleLiteral(DoubleLiteral node) {
     _writer.print(node.literal.lexeme);
     return null;
@@ -19347,20 +19044,6 @@
 
   @override
   Token get firstTokenAfterCommentAndMetadata => typedefKeyword;
-
-  /**
-   * Return the token representing the 'typedef' keyword.
-   */
-  @deprecated // Use "this.typedefKeyword"
-  Token get keyword => typedefKeyword;
-
-  /**
-   * Set the token representing the 'typedef' keyword to the given [token].
-   */
-  @deprecated // Use "this.typedefKeyword"
-  set keyword(Token token) {
-    typedefKeyword = token;
-  }
 }
 
 /**
@@ -19643,21 +19326,6 @@
   Token get firstTokenAfterCommentAndMetadata => _name.beginToken;
 
   /**
-   * Return the token representing the 'extends' keyword, or `null` if there is
-   * no explicit upper bound.
-   */
-  @deprecated // Use "this.extendsKeyword"
-  Token get keyword => extendsKeyword;
-
-  /**
-   * Set the token representing the 'extends' keyword to the given [token].
-   */
-  @deprecated // Use "this.extendsKeyword"
-  set keyword(Token token) {
-    extendsKeyword = token;
-  }
-
-  /**
    * Return the name of the type parameter.
    */
   SimpleIdentifier get name => _name;
@@ -19808,6 +19476,9 @@
   R visitConditionalExpression(ConditionalExpression node) => visitNode(node);
 
   @override
+  R visitConfiguration(Configuration node) => visitNode(node);
+
+  @override
   R visitConstructorDeclaration(ConstructorDeclaration node) => visitNode(node);
 
   @override
@@ -19830,6 +19501,9 @@
   R visitDoStatement(DoStatement node) => visitNode(node);
 
   @override
+  R visitDottedName(DottedName node) => visitNode(node);
+
+  @override
   R visitDoubleLiteral(DoubleLiteral node) => visitNode(node);
 
   @override
@@ -20404,7 +20078,8 @@
    * Return `true` if the variables in this list were declared with the 'const'
    * modifier.
    */
-  bool get isConst => keyword is KeywordToken &&
+  bool get isConst =>
+      keyword is KeywordToken &&
       (keyword as KeywordToken).keyword == Keyword.CONST;
 
   /**
@@ -20413,7 +20088,8 @@
    * `false` even though they are implicitly final. (In other words, this is a
    * syntactic check rather than a semantic check.)
    */
-  bool get isFinal => keyword is KeywordToken &&
+  bool get isFinal =>
+      keyword is KeywordToken &&
       (keyword as KeywordToken).keyword == Keyword.FINAL;
 
   /**
@@ -20583,20 +20259,6 @@
   @override
   Token get endToken => _body.endToken;
 
-  /**
-   * Return the token representing the 'while' keyword.
-   */
-  @deprecated // Use "this.whileKeyword"
-  Token get keyword => whileKeyword;
-
-  /**
-   * Set the token representing the 'while' keyword to the given [token].
-   */
-  @deprecated // Use "this.whileKeyword"
-  set keyword(Token token) {
-    whileKeyword = token;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitWhileStatement(this);
 
@@ -20644,14 +20306,6 @@
   Token get endToken => _mixinTypes.endToken;
 
   /**
-   * Set the token representing the 'with' keyword to the given [token].
-   */
-  @deprecated // Use "this.withKeyword"
-  void set mixinKeyword(Token token) {
-    this.withKeyword = token;
-  }
-
-  /**
    * Return the names of the mixins that were specified.
    */
   NodeList<TypeName> get mixinTypes => _mixinTypes;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 8638c84..f2a8c96 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -2,26 +2,27 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.constant;
+library analyzer.src.generated.constant;
 
 import 'dart:collection';
 
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisEngine, RecordingErrorListener;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
+import 'package:analyzer/src/generated/source.dart' show Source;
+import 'package:analyzer/src/generated/type_system.dart'
+    show TypeSystem, TypeSystemImpl;
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/task/dart.dart';
 
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart' show AnalysisEngine, RecordingErrorListener;
-import 'error.dart';
-import 'java_core.dart';
-import 'resolver.dart' show TypeProvider;
-import 'scanner.dart' show Token, TokenType;
-import 'source.dart' show Source;
-import 'type_system.dart' show TypeSystem, TypeSystemImpl;
-import 'utilities_collection.dart';
-import 'utilities_dart.dart' show ParameterKind;
-
 /**
  * Callback used by [ReferenceFinder] to report that a dependency was found.
  */
@@ -57,9 +58,6 @@
   BoolState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : (value ? 2 : 3);
 
   @override
@@ -1972,33 +1970,6 @@
  */
 abstract class DartObject {
   /**
-   * Return the boolean value of this object, or `null` if either the value of
-   * this object is not known or this object is not of type 'bool'.
-   *
-   * Deprecated. Use [toBoolValue].
-   */
-  @deprecated
-  bool get boolValue;
-
-  /**
-   * Return the floating point value of this object, or `null` if either the
-   * value of this object is not known or this object is not of type 'double'.
-   *
-   * Deprecated. Use [toDoubleValue].
-   */
-  @deprecated
-  double get doubleValue;
-
-  /**
-   * Return `true` if this object's value can be represented exactly.
-   *
-   * Deprecated. The semantics of this method were not clear. One semantic is
-   * covered by [hasKnownValue].
-   */
-  @deprecated
-  bool get hasExactValue;
-
-  /**
    * Return `true` if the value of the object being represented is known.
    *
    * This method will return `false` if
@@ -2017,45 +1988,11 @@
   bool get hasKnownValue;
 
   /**
-   * Return the integer value of this object, or `null` if either the value of
-   * this object is not known or this object is not of type 'int'.
-   *
-   * Deprecated. Use [toIntValue].
-   */
-  @deprecated
-  int get intValue;
-
-  /**
-   * Return `true` if this object represents the value 'false'.
-   *
-   * Deprecated. Use `object.toBoolValue() == false`.
-   */
-  @deprecated
-  bool get isFalse;
-
-  /**
    * Return `true` if the object being represented represents the value 'null'.
    */
   bool get isNull;
 
   /**
-   * Return `true` if this object represents the value 'true'.
-   *
-   * Deprecated. Use `object.toBoolValue() == true`.
-   */
-  @deprecated
-  bool get isTrue;
-
-  /**
-   * Return the string value of this object, or `null` if either the value of
-   * this object is not known or this object is not of type 'String'.
-   *
-   * Deprecated. Use [toStringValue].
-   */
-  @deprecated
-  String get stringValue;
-
-  /**
    * Return a representation of the type of the object being represented.
    *
    * For values resulting from the invocation of a 'const' constructor, this
@@ -2080,16 +2017,6 @@
   ParameterizedType get type;
 
   /**
-   * Return this object's value if it can be represented exactly, or `null` if
-   * either the value cannot be represented exactly or if the value is `null`.
-   * Clients should use `hasExactValue` to distinguish between these two cases.
-   *
-   * Deprecated. Use one of the `isXValue()` methods.
-   */
-  @deprecated
-  Object get value;
-
-  /**
    * Return a representation of the value of the field with the given [name].
    *
    * Return `null` if either the object being represented does not have a field
@@ -2169,7 +2096,7 @@
    * * this object is not of type 'Type', or
    * * the value of the object being represented is `null`.
    */
-  ParameterizedType toTypeValue();
+  DartType toTypeValue();
 }
 
 /**
@@ -2566,30 +2493,14 @@
     return new DartObjectImpl(type, GenericState.UNKNOWN_VALUE);
   }
 
-  @deprecated
-  @override
-  bool get boolValue => toBoolValue();
-
-  @deprecated
-  @override
-  double get doubleValue => toDoubleValue();
-
   HashMap<String, DartObjectImpl> get fields => _state.fields;
 
-  @deprecated
-  @override
-  bool get hasExactValue => _state.hasExactValue;
-
   @override
   int get hashCode => JenkinsSmiHash.hash2(type.hashCode, _state.hashCode);
 
   @override
   bool get hasKnownValue => !_state.isUnknown;
 
-  @deprecated
-  @override
-  int get intValue => toIntValue();
-
   /**
    * Return `true` if this object represents an object whose type is 'bool'.
    */
@@ -2601,18 +2512,9 @@
    */
   bool get isBoolNumStringOrNull => _state.isBoolNumStringOrNull;
 
-  @deprecated
-  @override
-  bool get isFalse => toBoolValue() == false;
-
   @override
   bool get isNull => _state is NullState;
 
-  @deprecated
-  @override
-  bool get isTrue =>
-      _state is BoolState && identical((_state as BoolState).value, true);
-
   /**
    * Return `true` if this object represents an unknown value.
    */
@@ -2624,14 +2526,6 @@
    */
   bool get isUserDefinedObject => _state is GenericState;
 
-  @deprecated
-  @override
-  String get stringValue => toStringValue();
-
-  @deprecated
-  @override
-  Object get value => _state.value;
-
   @override
   bool operator ==(Object object) {
     if (object is! DartObjectImpl) {
@@ -3130,13 +3024,10 @@
   }
 
   @override
-  ParameterizedType toTypeValue() {
+  DartType toTypeValue() {
     if (_state is TypeState) {
-      Element element = (_state as TypeState).value;
-      if (element is ClassElement) {
-        return element.type;
-      }
-      if (element is FunctionElement) {
+      Element element = (_state as TypeState)._element;
+      if (element is TypeDefiningElement) {
         return element.type;
       }
     }
@@ -3240,9 +3131,6 @@
   DoubleState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -3817,14 +3705,6 @@
     this._errors = errors == null ? <AnalysisError>[] : errors;
   }
 
-  @deprecated // Use new EvaluationResultImpl(value)
-  EvaluationResultImpl.con1(this.value) {
-    this._errors = new List<AnalysisError>(0);
-  }
-
-  @deprecated // Use new EvaluationResultImpl(value, errors)
-  EvaluationResultImpl.con2(this.value, List<AnalysisError> this._errors);
-
   List<AnalysisError> get errors => _errors;
 
   bool equalValues(TypeProvider typeProvider, EvaluationResultImpl result) {
@@ -4021,11 +3901,6 @@
   HashMap<String, DartObjectImpl> get fields => null;
 
   /**
-   * Return `true` if this object's value can be represented exactly.
-   */
-  bool get hasExactValue => false;
-
-  /**
    * Return `true` if this object represents an object whose type is 'bool'.
    */
   bool get isBool => false;
@@ -4047,13 +3922,6 @@
   String get typeName;
 
   /**
-   * Return this object's value if it can be represented exactly, or `null` if
-   * either the value cannot be represented exactly or if the value is `null`.
-   * Clients should use [hasExactValue] to distinguish between these two cases.
-   */
-  Object get value => null;
-
-  /**
    * Return the result of invoking the '+' operator on this object with the
    * [rightOperand].
    *
@@ -4448,9 +4316,6 @@
   IntState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -4907,17 +4772,6 @@
   ListState(this._elements);
 
   @override
-  bool get hasExactValue {
-    int count = _elements.length;
-    for (int i = 0; i < count; i++) {
-      if (!_elements[i].hasExactValue) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
   int get hashCode {
     int value = 0;
     int count = _elements.length;
@@ -4931,20 +4785,6 @@
   String get typeName => "List";
 
   @override
-  List<Object> get value {
-    int count = _elements.length;
-    List<Object> result = new List<Object>(count);
-    for (int i = 0; i < count; i++) {
-      DartObjectImpl element = _elements[i];
-      if (!element.hasExactValue) {
-        return null;
-      }
-      result[i] = element.value;
-    }
-    return result;
-  }
-
-  @override
   bool operator ==(Object object) {
     if (object is! ListState) {
       return false;
@@ -5015,16 +4855,6 @@
   MapState(this._entries);
 
   @override
-  bool get hasExactValue {
-    for (DartObjectImpl key in _entries.keys) {
-      if (!key.hasExactValue || !_entries[key].hasExactValue) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  @override
   int get hashCode {
     int value = 0;
     for (DartObjectImpl key in _entries.keys.toSet()) {
@@ -5037,19 +4867,6 @@
   String get typeName => "Map";
 
   @override
-  Map<Object, Object> get value {
-    HashMap<Object, Object> result = new HashMap<Object, Object>();
-    for (DartObjectImpl key in _entries.keys) {
-      DartObjectImpl value = _entries[key];
-      if (!key.hasExactValue || !value.hasExactValue) {
-        return null;
-      }
-      result[key.value] = value.value;
-    }
-    return result;
-  }
-
-  @override
   bool operator ==(Object object) {
     if (object is! MapState) {
       return false;
@@ -5119,9 +4936,6 @@
   static NullState NULL_STATE = new NullState();
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => 0;
 
   @override
@@ -5378,9 +5192,6 @@
   StringState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -5466,9 +5277,6 @@
   SymbolState(this.value);
 
   @override
-  bool get hasExactValue => true;
-
-  @override
   int get hashCode => value == null ? 0 : value.hashCode;
 
   @override
@@ -5534,9 +5342,6 @@
   String get typeName => "Type";
 
   @override
-  Element get value => _element;
-
-  @override
   bool operator ==(Object object) =>
       object is TypeState && (_element == object._element);
 
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 334f4e8..fcf2511 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -2,28 +2,28 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.element;
+library analyzer.src.generated.element;
 
 import 'dart:collection';
 import 'dart:math' show min;
 
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart'
+    show DartObject, EvaluationResultImpl;
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisContext, AnalysisEngine, AnalysisException;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Keyword;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/task/model.dart' show AnalysisTarget;
 
-import 'ast.dart';
-import 'constant.dart' show DartObject, EvaluationResultImpl;
-import 'engine.dart' show AnalysisContext, AnalysisEngine;
-import 'html.dart' show XmlAttributeNode, XmlTagNode;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'resolver.dart';
-import 'scanner.dart' show Keyword;
-import 'sdk.dart' show DartSdk;
-import 'source.dart';
-import 'utilities_collection.dart';
-import 'utilities_dart.dart';
-
 /**
  * For AST nodes that could be in both the getter and setter contexts
  * ([IndexExpression]s and [SimpleIdentifier]s), the additional resolved
@@ -215,13 +215,6 @@
   bool get isProxy;
 
   /**
-   * Return `true` if this class is a mixin application.  Deprecated--please
-   * use [isMixinApplication] instead.
-   */
-  @deprecated
-  bool get isTypedef;
-
-  /**
    * Return `true` if this class can validly be used as a mixin when defining
    * another class. The behavior of this method is defined by the Dart Language
    * Specification in section 9:
@@ -483,12 +476,6 @@
  */
 class ClassElementImpl extends ElementImpl implements ClassElement {
   /**
-   * An empty list of class elements.
-   */
-  @deprecated // Use ClassElement.EMPTY_LIST
-  static const List<ClassElement> EMPTY_ARRAY = const <ClassElement>[];
-
-  /**
    * A list containing all of the accessors (getters and setters) contained in
    * this class.
    */
@@ -765,10 +752,6 @@
   }
 
   @override
-  @deprecated
-  bool get isTypedef => isMixinApplication;
-
-  @override
   bool get isValidMixin => hasModifier(Modifier.MIXIN);
 
   @override
@@ -1424,13 +1407,6 @@
 class CompilationUnitElementImpl extends UriReferencedElementImpl
     implements CompilationUnitElement {
   /**
-   * An empty list of compilation unit elements.
-   */
-  @deprecated // Use CompilationUnitElement.EMPTY_LIST
-  static const List<CompilationUnitElement> EMPTY_ARRAY =
-      const <CompilationUnitElement>[];
-
-  /**
    * The source that corresponds to this compilation unit.
    */
   Source source;
@@ -1735,19 +1711,6 @@
   /**
    * Initialize a newly created field element to have the given [name].
    */
-  @deprecated // Use new ConstFieldElementImpl.forNode(name)
-  ConstFieldElementImpl.con1(Identifier name) : super.forNode(name);
-
-  /**
-   * Initialize a newly created synthetic field element to have the given
-   * [name] and [offset].
-   */
-  @deprecated // Use new ConstFieldElementImpl(name, offset)
-  ConstFieldElementImpl.con2(String name, int offset) : super(name, offset);
-
-  /**
-   * Initialize a newly created field element to have the given [name].
-   */
   ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
 
   @override
@@ -1860,13 +1823,6 @@
 class ConstructorElementImpl extends ExecutableElementImpl
     implements ConstructorElement {
   /**
-   * An empty list of constructor elements.
-   */
-  @deprecated // Use ConstructorElement.EMPTY_LIST
-  static const List<ConstructorElement> EMPTY_ARRAY =
-      const <ConstructorElement>[];
-
-  /**
    * The constructor to which this constructor is redirecting.
    */
   ConstructorElement redirectedConstructor;
@@ -1990,10 +1946,13 @@
 class ConstructorMember extends ExecutableMember implements ConstructorElement {
   /**
    * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
+   * [baseElement], defined by the [definingType]. If [type] is passed, it
+   * represents the full type of the member, and will take precedence over
+   * the [definingType].
    */
-  ConstructorMember(ConstructorElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
+  ConstructorMember(ConstructorElement baseElement, InterfaceType definingType,
+      [FunctionType type])
+      : super(baseElement, definingType, type);
 
   @override
   ConstructorElement get baseElement => super.baseElement as ConstructorElement;
@@ -2081,10 +2040,7 @@
     if (baseType == substitutedType) {
       return constructor;
     }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new ConstructorMember(constructor, definingType);
+    return new ConstructorMember(constructor, definingType, substitutedType);
   }
 }
 
@@ -2202,17 +2158,6 @@
   String get name;
 
   /**
-   * Return the least upper bound of this type and the given [type], or `null`
-   * if there is no least upper bound.
-   *
-   * Deprecated, since it is impossible to implement the correct algorithm
-   * without access to a [TypeProvider].  Please use
-   * [TypeSystem.getLeastUpperBound] instead.
-   */
-  @deprecated
-  DartType getLeastUpperBound(DartType type);
-
-  /**
    * Return `true` if this type is assignable to the given [type]. A type
    * <i>T</i> may be assigned to a type <i>S</i>, written <i>T</i> &hArr;
    * <i>S</i>, iff either <i>T</i> <: <i>S</i> or <i>S</i> <: <i>T</i>.
@@ -2449,9 +2394,9 @@
    * Elements with a smaller offset will be sorted to be before elements with a
    * larger name offset.
    */
-  static final Comparator<Element> SORT_BY_OFFSET = (Element firstElement,
-          Element secondElement) =>
-      firstElement.nameOffset - secondElement.nameOffset;
+  static final Comparator<Element> SORT_BY_OFFSET =
+      (Element firstElement, Element secondElement) =>
+          firstElement.nameOffset - secondElement.nameOffset;
 
   /**
    * Return the analysis context in which this element is defined.
@@ -2562,21 +2507,6 @@
   int get nameOffset;
 
   /**
-   * **DEPRECATED** Use `computeNode()` instead.
-   *
-   * Return the resolved [AstNode] node that declares this element, or `null` if
-   * this element is synthetic or isn't contained in a compilation unit, such as
-   * a [LibraryElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  @deprecated
-  AstNode get node;
-
-  /**
    * Return the source that contains this element, or `null` if this element is
    * not contained in a source.
    */
@@ -2702,13 +2632,6 @@
  */
 class ElementAnnotationImpl implements ElementAnnotation {
   /**
-   * An empty list of annotations.
-   */
-  @deprecated // Use ElementAnnotation.EMPTY_LIST
-  static const List<ElementAnnotationImpl> EMPTY_ARRAY =
-      const <ElementAnnotationImpl>[];
-
-  /**
    * The name of the class used to mark an element as being deprecated.
    */
   static String _DEPRECATED_CLASS_NAME = "Deprecated";
@@ -3001,10 +2924,6 @@
     _cachedLocation = null;
   }
 
-  @deprecated
-  @override
-  AstNode get node => computeNode();
-
   @override
   Source get source {
     if (_enclosingElement == null) {
@@ -3475,14 +3394,8 @@
 
   R visitConstructorElement(ConstructorElement element);
 
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element);
-
   R visitExportElement(ExportElement element);
 
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element);
-
   R visitFieldElement(FieldElement element);
 
   R visitFieldFormalParameterElement(FieldFormalParameterElement element);
@@ -3491,9 +3404,6 @@
 
   R visitFunctionTypeAliasElement(FunctionTypeAliasElement element);
 
-  @deprecated
-  R visitHtmlElement(HtmlElement element);
-
   R visitImportElement(ImportElement element);
 
   R visitLabelElement(LabelElement element);
@@ -3518,62 +3428,10 @@
 }
 
 /**
- * A script tag in an HTML file having content that defines a Dart library.
- */
-@deprecated
-abstract class EmbeddedHtmlScriptElement implements HtmlScriptElement {
-  /**
-   * Return the library element defined by the content of the script tag.
-   */
-  LibraryElement get scriptLibrary;
-}
-
-/**
- * A concrete implementation of an [EmbeddedHtmlScriptElement].
- */
-@deprecated
-class EmbeddedHtmlScriptElementImpl extends HtmlScriptElementImpl
-    implements EmbeddedHtmlScriptElement {
-  /**
-   * The library defined by the script tag's content.
-   */
-  LibraryElement _scriptLibrary;
-
-  /**
-   * Initialize a newly created script element to represent the given [node].
-   */
-  EmbeddedHtmlScriptElementImpl(XmlTagNode node) : super(node);
-
-  @override
-  ElementKind get kind => ElementKind.EMBEDDED_HTML_SCRIPT;
-
-  @override
-  LibraryElement get scriptLibrary => _scriptLibrary;
-
-  /**
-   * Set the script library defined by the script tag's content to the given
-   * [library].
-   */
-  void set scriptLibrary(LibraryElementImpl library) {
-    library.enclosingElement = this;
-    _scriptLibrary = library;
-  }
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitEmbeddedHtmlScriptElement(this);
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    safelyVisitChild(_scriptLibrary, visitor);
-  }
-}
-
-/**
  * An element representing an executable object, including functions, methods,
  * constructors, getters, and setters.
  */
-abstract class ExecutableElement implements TypeParameterizedElement {
+abstract class ExecutableElement implements FunctionTypedElement {
   /**
    * An empty list of executable elements.
    */
@@ -3649,24 +3507,6 @@
    * executable element.
    */
   List<LocalVariableElement> get localVariables;
-
-  /**
-   * Return a list containing all of the parameters defined by this executable
-   * element.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return the return type defined by this executable element. If the element
-   * model is fully populated, then the [returnType] will not be `null`, even
-   * if no return type was explicitly specified.
-   */
-  DartType get returnType;
-
-  /**
-   * Return the type of function defined by this executable element.
-   */
-  FunctionType get type;
 }
 
 /**
@@ -3675,13 +3515,6 @@
 abstract class ExecutableElementImpl extends ElementImpl
     implements ExecutableElement {
   /**
-   * An empty list of executable elements.
-   */
-  @deprecated // Use ExecutableElement.EMPTY_LIST
-  static const List<ExecutableElement> EMPTY_ARRAY =
-      const <ExecutableElement>[];
-
-  /**
    * A list containing all of the functions defined within this executable
    * element.
    */
@@ -3941,12 +3774,21 @@
  * type parameters are known.
  */
 abstract class ExecutableMember extends Member implements ExecutableElement {
+  @override
+  final FunctionType type;
+
   /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
+   * Initialize a newly created element to represent a callable element (like a
+   * method or function or property), based on the [baseElement], defined by the
+   * [definingType]. If [type] is passed, it represents the full type of the
+   * member, and will take precedence over the [definingType].
    */
-  ExecutableMember(ExecutableElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
+  ExecutableMember(ExecutableElement baseElement, InterfaceType definingType,
+      [FunctionType type])
+      : type = type ??
+            baseElement.type.substitute2(definingType.typeArguments,
+                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+        super(baseElement, definingType);
 
   @override
   ExecutableElement get baseElement => super.baseElement as ExecutableElement;
@@ -3999,26 +3841,10 @@
   }
 
   @override
-  List<ParameterElement> get parameters {
-    List<ParameterElement> baseParameters = baseElement.parameters;
-    int parameterCount = baseParameters.length;
-    if (parameterCount == 0) {
-      return baseParameters;
-    }
-    List<ParameterElement> parameterizedParameters =
-        new List<ParameterElement>(parameterCount);
-    for (int i = 0; i < parameterCount; i++) {
-      parameterizedParameters[i] =
-          ParameterMember.from(baseParameters[i], definingType);
-    }
-    return parameterizedParameters;
-  }
+  List<ParameterElement> get parameters => type.parameters;
 
   @override
-  DartType get returnType => substituteFor(baseElement.returnType);
-
-  @override
-  FunctionType get type => substituteFor(baseElement.type);
+  DartType get returnType => type.returnType;
 
   @override
   List<TypeParameterElement> get typeParameters => baseElement.typeParameters;
@@ -4042,12 +3868,6 @@
   /**
    * An empty list of export elements.
    */
-  @deprecated // Use ExportElement.EMPTY_LIST
-  static const List<ExportElement> EMPTY_ARRAY = const <ExportElement>[];
-
-  /**
-   * An empty list of export elements.
-   */
   static const List<ExportElement> EMPTY_LIST = const <ExportElement>[];
 
   /**
@@ -4101,44 +3921,6 @@
 }
 
 /**
- * A script tag in an HTML file having a `source` attribute that references a
- * Dart library source file.
- */
-@deprecated
-abstract class ExternalHtmlScriptElement implements HtmlScriptElement {
-  /**
-   * Return the source referenced by this element, or `null` if this element
-   * does not reference a Dart library source file.
-   */
-  Source get scriptSource;
-}
-
-/**
- * A concrete implementation of an [ExternalHtmlScriptElement].
- */
-@deprecated
-class ExternalHtmlScriptElementImpl extends HtmlScriptElementImpl
-    implements ExternalHtmlScriptElement {
-  /**
-   * The source specified in the `source` attribute or `null` if unspecified.
-   */
-  Source scriptSource;
-
-  /**
-   * Initialize a newly created script element to correspond to the given
-   * [node].
-   */
-  ExternalHtmlScriptElementImpl(XmlTagNode node) : super(node);
-
-  @override
-  ElementKind get kind => ElementKind.EXTERNAL_HTML_SCRIPT;
-
-  @override
-  accept(ElementVisitor visitor) =>
-      visitor.visitExternalHtmlScriptElement(this);
-}
-
-/**
  * A field defined within a type.
  */
 abstract class FieldElement
@@ -4170,12 +3952,6 @@
 class FieldElementImpl extends PropertyInducingElementImpl
     implements FieldElement {
   /**
-   * An empty list of field elements.
-   */
-  @deprecated // Use FieldElement.EMPTY_LIST
-  static const List<FieldElement> EMPTY_ARRAY = const <FieldElement>[];
-
-  /**
    * Initialize a newly created synthetic field element to have the given [name]
    * at the given [offset].
    */
@@ -4258,18 +4034,21 @@
 class FieldFormalParameterMember extends ParameterMember
     implements FieldFormalParameterElement {
   /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
+   * Initialize a newly created element to represent a field formal parameter,
+   * based on the [baseElement], defined by the [definingType]. If [type]
+   * is passed it will be used as the substituted type for this member.
    */
   FieldFormalParameterMember(
-      FieldFormalParameterElement baseElement, ParameterizedType definingType)
-      : super(baseElement, definingType);
+      FieldFormalParameterElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : super(baseElement, definingType, type);
 
   @override
   FieldElement get field {
     FieldElement field = (baseElement as FieldFormalParameterElement).field;
     if (field is FieldElement) {
-      return FieldMember.from(field, definingType);
+      return FieldMember.from(
+          field, substituteFor(field.enclosingElement.type));
     }
     return field;
   }
@@ -4285,7 +4064,7 @@
  */
 class FieldMember extends VariableMember implements FieldElement {
   /**
-   * Initialize a newly created element to represent a constructor, based on the
+   * Initialize a newly created element to represent a field, based on the
    * [baseElement], defined by the [definingType].
    */
   FieldMember(FieldElement baseElement, InterfaceType definingType)
@@ -4295,9 +4074,6 @@
   FieldElement get baseElement => super.baseElement as FieldElement;
 
   @override
-  InterfaceType get definingType => super.definingType as InterfaceType;
-
-  @override
   ClassElement get enclosingElement => baseElement.enclosingElement;
 
   @override
@@ -4330,7 +4106,7 @@
    * field. Return the member that was created, or the base field if no member
    * was created.
    */
-  static FieldElement from(FieldElement field, InterfaceType definingType) {
+  static FieldElement from(FieldElement field, ParameterizedType definingType) {
     if (!_isChangedByTypeSubstitution(field, definingType)) {
       return field;
     }
@@ -4346,11 +4122,12 @@
    * arguments from the defining type.
    */
   static bool _isChangedByTypeSubstitution(
-      FieldElement field, InterfaceType definingType) {
+      FieldElement field, ParameterizedType definingType) {
     List<DartType> argumentTypes = definingType.typeArguments;
     if (field != null && argumentTypes.length != 0) {
       DartType baseType = field.type;
-      List<DartType> parameterTypes = definingType.element.type.typeArguments;
+      List<DartType> parameterTypes =
+          TypeParameterTypeImpl.getTypes(definingType.typeParameters);
       if (baseType != null) {
         DartType substitutedType =
             baseType.substitute2(argumentTypes, parameterTypes);
@@ -4428,12 +4205,6 @@
 class FunctionElementImpl extends ExecutableElementImpl
     implements FunctionElement {
   /**
-   * An empty list of function elements.
-   */
-  @deprecated // Use FunctionElement.EMPTY_LIST
-  static const List<FunctionElement> EMPTY_ARRAY = const <FunctionElement>[];
-
-  /**
    * The offset to the beginning of the visible range for this element.
    */
   int _visibleRangeOffset = 0;
@@ -4525,6 +4296,70 @@
 }
 
 /**
+ * An element of a generic function, where the type parameters are known.
+ */
+// TODO(jmesserly): the term "function member" is a bit weird, but it allows
+// a certain consistency.
+class FunctionMember extends ExecutableMember implements FunctionElement {
+  /**
+   * Initialize a newly created element to represent a function, based on the
+   * [baseElement], with the corresponding function [type].
+   */
+  FunctionMember(FunctionElement baseElement, [DartType type])
+      : super(baseElement, null, type);
+
+  @override
+  FunctionElement get baseElement => super.baseElement as FunctionElement;
+
+  @override
+  Element get enclosingElement => baseElement.enclosingElement;
+
+  @override
+  bool get isEntryPoint => baseElement.isEntryPoint;
+
+  @override
+  SourceRange get visibleRange => baseElement.visibleRange;
+
+  @override
+  accept(ElementVisitor visitor) => visitor.visitFunctionElement(this);
+
+  @override
+  FunctionDeclaration computeNode() => baseElement.computeNode();
+
+  @override
+  String toString() {
+    StringBuffer buffer = new StringBuffer();
+    buffer.write(baseElement.displayName);
+    (type as FunctionTypeImpl).appendTo(buffer);
+    return buffer.toString();
+  }
+
+  /**
+   * If the given [method]'s type is different when any type parameters from the
+   * defining type's declaration are replaced with the actual type arguments
+   * from the [definingType], create a method member representing the given
+   * method. Return the member that was created, or the base method if no member
+   * was created.
+   */
+  static MethodElement from(
+      MethodElement method, ParameterizedType definingType) {
+    if (method == null || definingType.typeArguments.length == 0) {
+      return method;
+    }
+    FunctionType baseType = method.type;
+    List<DartType> argumentTypes = definingType.typeArguments;
+    List<DartType> parameterTypes =
+        TypeParameterTypeImpl.getTypes(definingType.typeParameters);
+    FunctionType substitutedType =
+        baseType.substitute2(argumentTypes, parameterTypes);
+    if (baseType == substitutedType) {
+      return method;
+    }
+    return new MethodMember(method, definingType, substitutedType);
+  }
+}
+
+/**
  * The type of a function, method, constructor, getter, or setter. Function
  * types come in three variations:
  *
@@ -4669,7 +4504,7 @@
  * A function type alias (`typedef`).
  */
 abstract class FunctionTypeAliasElement
-    implements TypeDefiningElement, TypeParameterizedElement {
+    implements TypeDefiningElement, FunctionTypedElement {
   /**
    * An empty array of type alias elements.
    */
@@ -4683,19 +4518,6 @@
   CompilationUnitElement get enclosingElement;
 
   /**
-   * Return a list containing all of the parameters defined by this type alias.
-   */
-  List<ParameterElement> get parameters;
-
-  /**
-   * Return the return type defined by this type alias.
-   */
-  DartType get returnType;
-
-  @override
-  FunctionType get type;
-
-  /**
    * Return the resolved function type alias node that declares this element.
    *
    * This method is expensive, because resolved AST might be evicted from cache,
@@ -4711,13 +4533,6 @@
 class FunctionTypeAliasElementImpl extends ElementImpl
     implements FunctionTypeAliasElement {
   /**
-   * An empty array of type alias elements.
-   */
-  @deprecated // Use FunctionTypeAliasElement.EMPTY_LIST
-  static List<FunctionTypeAliasElement> EMPTY_ARRAY =
-      new List<FunctionTypeAliasElement>(0);
-
-  /**
    * A list containing all of the parameters defined by this type alias.
    */
   List<ParameterElement> _parameters = ParameterElement.EMPTY_LIST;
@@ -4853,6 +4668,31 @@
 }
 
 /**
+ * An element that has a [FunctionType] as its [type].
+ *
+ * This also provides convenient access to the parameters and return type.
+ */
+abstract class FunctionTypedElement implements TypeParameterizedElement {
+  /**
+   * Return a list containing all of the parameters defined by this executable
+   * element.
+   */
+  List<ParameterElement> get parameters;
+
+  /**
+   * Return the return type defined by this element. If the element model is
+   * fully populated, then the [returnType] will not be `null`, even
+   * if no return type was explicitly specified.
+   */
+  DartType get returnType;
+
+  /**
+   * Return the type of function defined by this element.
+   */
+  FunctionType get type;
+}
+
+/**
  * The type of a function, method, constructor, getter, or setter.
  */
 class FunctionTypeImpl extends TypeImpl implements FunctionType {
@@ -4890,21 +4730,6 @@
    * Initialize a newly created function type to be declared by the given
    * [element].
    */
-  @deprecated // Use new FunctionTypeImpl(element)
-  FunctionTypeImpl.con1(ExecutableElement element) : this(element);
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element].
-   */
-  @deprecated // Use new FunctionTypeImpl.forTypedef(element)
-  FunctionTypeImpl.con2(FunctionTypeAliasElement element)
-      : this.forTypedef(element);
-
-  /**
-   * Initialize a newly created function type to be declared by the given
-   * [element].
-   */
   FunctionTypeImpl.forTypedef(FunctionTypeAliasElement element,
       [List<FunctionTypeAliasElement> prunedTypedefs])
       : this._(element, element?.name, prunedTypedefs, null, null, null);
@@ -4957,26 +4782,12 @@
   /**
    * Return the base parameter elements of this function element.
    */
-  List<ParameterElement> get baseParameters {
-    Element element = this.element;
-    if (element is ExecutableElement) {
-      return element.parameters;
-    } else {
-      return (element as FunctionTypeAliasElement).parameters;
-    }
-  }
+  List<ParameterElement> get baseParameters => element.parameters;
 
   /**
    * Return the return type defined by this function's element.
    */
-  DartType get baseReturnType {
-    Element element = this.element;
-    if (element is ExecutableElement) {
-      return element.returnType;
-    } else {
-      return (element as FunctionTypeAliasElement).returnType;
-    }
-  }
+  DartType get baseReturnType => element.returnType;
 
   @override
   List<TypeParameterElement> get boundTypeParameters => _boundTypeParameters;
@@ -5053,6 +4864,9 @@
   }
 
   @override
+  FunctionTypedElement get element => super.element;
+
+  @override
   int get hashCode {
     if (element == null) {
       return 0;
@@ -5075,6 +4889,26 @@
     return code;
   }
 
+  /**
+   * The type arguments that were used to instantiate this function type, if
+   * any, otherwise this will return an empty list.
+   *
+   * Given a function type `f`:
+   *
+   *     f == f.originalFunction.instantiate(f.instantiatedTypeArguments)
+   *
+   * Will always hold.
+   */
+  List<DartType> get instantiatedTypeArguments {
+    int typeParameterCount = element.type.boundTypeParameters.length;
+    if (typeParameterCount == 0) {
+      return DartType.EMPTY_LIST;
+    }
+    // The substituted types at the end should be our bound type parameters.
+    int skipCount = typeArguments.length - typeParameterCount;
+    return new List<DartType>.from(typeArguments.skip(skipCount));
+  }
+
   @override
   Map<String, DartType> get namedParameterTypes {
     LinkedHashMap<String, DartType> namedParameterTypes =
@@ -5172,6 +5006,20 @@
     return types;
   }
 
+  /**
+   * If this is an instantiation of a generic function type, this will get
+   * the original function from which it was instantiated.
+   *
+   * Otherwise, this will return `this`.
+   */
+  FunctionTypeImpl get originalFunction {
+    if (element.type.boundTypeParameters.isEmpty) {
+      return this;
+    }
+    return (element.type as FunctionTypeImpl).substitute2(typeArguments,
+        TypeParameterTypeImpl.getTypes(typeParameters), prunedTypedefs);
+  }
+
   @override
   List<ParameterElement> get parameters {
     List<ParameterElement> baseParameters = this.baseParameters;
@@ -5229,9 +5077,22 @@
     // variables, and see if the result is equal.
     if (boundTypeParameters.isNotEmpty) {
       List<DartType> instantiateTypeArgs = new List<DartType>();
-      for (TypeParameterElement e in boundTypeParameters) {
-        instantiateTypeArgs.add(new TypeParameterTypeImpl(
-            new TypeParameterElementImpl(e.name, -1)));
+      List<DartType> variablesThis = new List<DartType>();
+      List<DartType> variablesOther = new List<DartType>();
+      for (int i = 0; i < boundTypeParameters.length; i++) {
+        TypeParameterElement pThis = boundTypeParameters[i];
+        TypeParameterElement pOther = otherType.boundTypeParameters[i];
+        TypeParameterTypeImpl pFresh = new TypeParameterTypeImpl(
+            new TypeParameterElementImpl(pThis.name, -1));
+        instantiateTypeArgs.add(pFresh);
+        variablesThis.add(pThis.type);
+        variablesOther.add(pOther.type);
+        // Check that the bounds are equal after equating the previous
+        // bound variables.
+        if (pThis.bound?.substitute2(instantiateTypeArgs, variablesThis) !=
+            pOther.bound?.substitute2(instantiateTypeArgs, variablesOther)) {
+          return false;
+        }
       }
       // After instantiation, they will no longer have boundTypeParameters,
       // so we will continue below.
@@ -5263,6 +5124,7 @@
       }
 
       List<DartType> instantiateTypeArgs = new List<DartType>();
+      List<DartType> variables = new List<DartType>();
       buffer.write("<");
       for (TypeParameterElement e in boundTypeParameters) {
         if (e != boundTypeParameters[0]) {
@@ -5283,6 +5145,13 @@
             new TypeParameterTypeImpl(new TypeParameterElementImpl(name, -1));
         t.appendTo(buffer);
         instantiateTypeArgs.add(t);
+        variables.add(e.type);
+        if (e.bound != null) {
+          buffer.write(" extends ");
+          TypeImpl renamed =
+              e.bound.substitute2(instantiateTypeArgs, variables);
+          renamed.appendTo(buffer);
+        }
       }
       buffer.write(">");
 
@@ -5813,22 +5682,12 @@
     return null;
   }
 
-  @override
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) =>
-      visitHtmlScriptElement(element);
-
   R visitExecutableElement(ExecutableElement element) => visitElement(element);
 
   @override
   R visitExportElement(ExportElement element) => visitElement(element);
 
   @override
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) =>
-      visitHtmlScriptElement(element);
-
-  @override
   R visitFieldElement(FieldElement element) =>
       visitPropertyInducingElement(element);
 
@@ -5844,13 +5703,6 @@
       visitElement(element);
 
   @override
-  @deprecated
-  R visitHtmlElement(HtmlElement element) => visitElement(element);
-
-  @deprecated
-  R visitHtmlScriptElement(HtmlScriptElement element) => visitElement(element);
-
-  @override
   R visitImportElement(ImportElement element) => visitElement(element);
 
   @override
@@ -5945,156 +5797,12 @@
 }
 
 /**
- * An HTML file.
- */
-@deprecated
-abstract class HtmlElement implements Element {
-  /**
-   * An empty list of HTML file elements.
-   */
-  static const List<HtmlElement> EMPTY_LIST = const <HtmlElement>[];
-
-  /**
-   * Return a list containing all of the script elements contained in the HTML
-   * file. This includes scripts with libraries that are defined by the content
-   * of a script tag as well as libraries that are referenced in the `source`
-   * attribute of a script tag.
-   */
-  List<HtmlScriptElement> get scripts;
-}
-
-/**
- * A concrete implementation of an [HtmlElement].
- */
-@deprecated
-class HtmlElementImpl extends ElementImpl implements HtmlElement {
-  /**
-   * An empty list of HTML file elements.
-   */
-  @deprecated // Use HtmlElement.EMPTY_LIST
-  static const List<HtmlElement> EMPTY_ARRAY = const <HtmlElement>[];
-
-  /**
-   * The analysis context in which this library is defined.
-   */
-  final AnalysisContext context;
-
-  /**
-   * The scripts contained in or referenced from script tags in the HTML file.
-   */
-  List<HtmlScriptElement> _scripts = HtmlScriptElement.EMPTY_LIST;
-
-  /**
-   * The source that corresponds to this HTML file.
-   */
-  Source source;
-
-  /**
-   * Initialize a newly created HTML element in the given [context] to have the
-   * given [name].
-   */
-  HtmlElementImpl(this.context, String name) : super(name, -1);
-
-  @override
-  int get hashCode => source.hashCode;
-
-  @override
-  String get identifier => source.encoding;
-
-  @override
-  ElementKind get kind => ElementKind.HTML;
-
-  @override
-  List<HtmlScriptElement> get scripts => _scripts;
-
-  /**
-   * Set the scripts contained in the HTML file to the given [scripts].
-   */
-  void set scripts(List<HtmlScriptElement> scripts) {
-    if (scripts.length == 0) {
-      this._scripts = HtmlScriptElement.EMPTY_LIST;
-      return;
-    }
-    for (HtmlScriptElement script in scripts) {
-      (script as HtmlScriptElementImpl).enclosingElement = this;
-    }
-    this._scripts = scripts;
-  }
-
-  @override
-  bool operator ==(Object object) {
-    if (identical(object, this)) {
-      return true;
-    }
-    return object is HtmlElementImpl && source == object.source;
-  }
-
-  @override
-  accept(ElementVisitor visitor) => visitor.visitHtmlElement(this);
-
-  @override
-  void appendTo(StringBuffer buffer) {
-    if (source == null) {
-      buffer.write("{HTML file}");
-    } else {
-      buffer.write(source.fullName);
-    }
-  }
-
-  @override
-  void visitChildren(ElementVisitor visitor) {
-    super.visitChildren(visitor);
-    safelyVisitChildren(_scripts, visitor);
-  }
-}
-
-/**
- * A script tag in an HTML file.
- *
- * See [EmbeddedHtmlScriptElement], and [ExternalHtmlScriptElement].
- */
-@deprecated
-abstract class HtmlScriptElement implements Element {
-  /**
-   * An empty list of HTML script elements.
-   */
-  static const List<HtmlScriptElement> EMPTY_LIST = const <HtmlScriptElement>[];
-}
-
-/**
- * A concrete implementation of an [HtmlScriptElement].
- */
-@deprecated
-abstract class HtmlScriptElementImpl extends ElementImpl
-    implements HtmlScriptElement {
-  /**
-   * An empty list of HTML script elements.
-   */
-  @deprecated // Use HtmlScriptElement.EMPTY_LIST
-  static const List<HtmlScriptElement> EMPTY_ARRAY =
-      const <HtmlScriptElement>[];
-
-  /**
-   * Initialize a newly created script element corresponding to the given
-   * [node].
-   */
-  HtmlScriptElementImpl(XmlTagNode node)
-      : super(node.tag, node.tagToken.offset);
-}
-
-/**
  * A single import directive within a library.
  */
 abstract class ImportElement implements Element, UriReferencedElement {
   /**
    * An empty list of import elements.
    */
-  @deprecated // Use ImportElement.EMPTY_LIST
-  static const List<ImportElement> EMPTY_ARRAY = const <ImportElement>[];
-
-  /**
-   * An empty list of import elements.
-   */
   static const List<ImportElement> EMPTY_LIST = const <ImportElement>[];
 
   /**
@@ -6203,12 +5911,6 @@
   /**
    * An empty list of types.
    */
-  @deprecated // Use InterfaceType.EMPTY_LIST
-  static const List<InterfaceType> EMPTY_ARRAY = const <InterfaceType>[];
-
-  /**
-   * An empty list of types.
-   */
   static const List<InterfaceType> EMPTY_LIST = const <InterfaceType>[];
 
   /**
@@ -6264,24 +5966,6 @@
   PropertyAccessorElement getGetter(String name);
 
   /**
-   * Return the least upper bound of this type and the given [type], or `null`
-   * if there is no least upper bound.
-   *
-   * Given two interfaces <i>I</i> and <i>J</i>, let <i>S<sub>I</sub></i> be the
-   * set of superinterfaces of <i>I<i>, let <i>S<sub>J</sub></i> be the set of
-   * superinterfaces of <i>J</i> and let <i>S = (I &cup; S<sub>I</sub>) &cap;
-   * (J &cup; S<sub>J</sub>)</i>. Furthermore, we define <i>S<sub>n</sub> =
-   * {T | T &isin; S &and; depth(T) = n}</i> for any finite <i>n</i>, where
-   * <i>depth(T)</i> is the number of steps in the longest inheritance path from
-   * <i>T</i> to <i>Object</i>. Let <i>q</i> be the largest number such that
-   * <i>S<sub>q</sub></i> has cardinality one. The least upper bound of <i>I</i>
-   * and <i>J</i> is the sole element of <i>S<sub>q</sub></i>.
-   */
-  @override
-  @deprecated
-  DartType getLeastUpperBound(DartType type);
-
-  /**
    * Return the element representing the method with the given [name] that is
    * declared in this class, or `null` if this class does not declare a method
    * with the given name.
@@ -6551,7 +6235,9 @@
     if (first.element == second.element) {
       return _leastUpperBound(first, second);
     }
-    return first.getLeastUpperBound(second);
+    AnalysisContext context = first.element.context;
+    return context.typeSystem
+        .getLeastUpperBound(context.typeProvider, first, second);
   }
 
   /**
@@ -6622,23 +6308,6 @@
       : super(element, element.displayName);
 
   /**
-   * Initialize a newly created type to be declared by the given [element].
-   */
-  @deprecated // Use new InterfaceTypeImpl(element)
-  InterfaceTypeImpl.con1(ClassElement element)
-      : prunedTypedefs = null,
-        super(element, element.displayName);
-
-  /**
-   * Initialize a newly created type to have the given [name]. This constructor
-   * should only be used in cases where there is no declaration of the type.
-   */
-  @deprecated // Use new InterfaceTypeImpl.named(name)
-  InterfaceTypeImpl.con2(String name)
-      : prunedTypedefs = null,
-        super(null, name);
-
-  /**
    * Initialize a newly created type to have the given [name]. This constructor
    * should only be used in cases where there is no declaration of the type.
    */
@@ -6824,26 +6493,6 @@
       .from((element as ClassElementImpl).getGetter(getterName), this);
 
   @override
-  @deprecated
-  DartType getLeastUpperBound(DartType type) {
-    // quick check for self
-    if (identical(type, this)) {
-      return this;
-    }
-    // dynamic
-    DartType dynamicType = DynamicTypeImpl.instance;
-    if (identical(this, dynamicType) || identical(type, dynamicType)) {
-      return dynamicType;
-    }
-    // TODO (jwren) opportunity here for a better, faster algorithm if this
-    // turns out to be a bottle-neck
-    if (type is! InterfaceType) {
-      return null;
-    }
-    return computeLeastUpperBound(this, type);
-  }
-
-  @override
   MethodElement getMethod(String methodName) => MethodMember.from(
       (element as ClassElementImpl).getMethod(methodName), this);
 
@@ -7469,12 +7118,6 @@
  */
 class LabelElementImpl extends ElementImpl implements LabelElement {
   /**
-   * An empty list of label elements.
-   */
-  @deprecated // Use LabelElement.EMPTY_LIST
-  static const List<LabelElement> EMPTY_ARRAY = const <LabelElement>[];
-
-  /**
    * A flag indicating whether this label is associated with a `switch`
    * statement.
    */
@@ -7663,12 +7306,6 @@
  */
 class LibraryElementImpl extends ElementImpl implements LibraryElement {
   /**
-   * An empty list of library elements.
-   */
-  @deprecated // Use LibraryElement.EMPTY_LIST
-  static const List<LibraryElement> EMPTY_ARRAY = const <LibraryElement>[];
-
-  /**
    * The analysis context in which this library is defined.
    */
   final AnalysisContext context;
@@ -8014,7 +7651,8 @@
   }
 
   @override
-  bool operator ==(Object object) => object is LibraryElementImpl &&
+  bool operator ==(Object object) =>
+      object is LibraryElementImpl &&
       _definingCompilationUnit == object.definingCompilationUnit;
 
   @override
@@ -8253,16 +7891,6 @@
    */
   static const List<LocalVariableElement> EMPTY_LIST =
       const <LocalVariableElement>[];
-
-  /**
-   * Return the resolved [VariableDeclaration] node that declares this
-   * [LocalVariableElement].
-   *
-   * This method is expensive, because resolved AST might be evicted from cache,
-   * so parsing and resolving will be performed.
-   */
-  @override
-  VariableDeclaration computeNode();
 }
 
 /**
@@ -8271,13 +7899,6 @@
 class LocalVariableElementImpl extends VariableElementImpl
     implements LocalVariableElement {
   /**
-   * An empty list of field elements.
-   */
-  @deprecated // Use LocalVariableElement.EMPTY_LIST
-  static const List<LocalVariableElement> EMPTY_ARRAY =
-      const <LocalVariableElement>[];
-
-  /**
    * The offset to the beginning of the visible range for this element.
    */
   int _visibleRangeOffset = 0;
@@ -8380,7 +8001,7 @@
   final ParameterizedType _definingType;
 
   /**
-   * Initialize a newly created element to represent a constructor, based on the
+   * Initialize a newly created element to represent a member, based on the
    * [baseElement], defined by the [definingType].
    */
   Member(this._baseElement, this._definingType);
@@ -8442,10 +8063,6 @@
   @override
   int get nameOffset => _baseElement.nameOffset;
 
-  @deprecated
-  @override
-  AstNode get node => computeNode();
-
   @override
   Source get source => _baseElement.source;
 
@@ -8497,6 +8114,7 @@
    * Return the type that results from replacing the type parameters in the
    * given [type] with the type arguments associated with this member.
    */
+  @deprecated
   DartType substituteFor(DartType type) {
     if (type == null) {
       return null;
@@ -8507,20 +8125,6 @@
     return type.substitute2(argumentTypes, parameterTypes);
   }
 
-  /**
-   * Return the list of types that results from replacing the type parameters in
-   * the given [types] with the type arguments associated with this member.
-   */
-  @deprecated
-  List<InterfaceType> substituteFor2(List<InterfaceType> types) {
-    int count = types.length;
-    List<InterfaceType> substitutedTypes = new List<InterfaceType>(count);
-    for (int i = 0; i < count; i++) {
-      substitutedTypes[i] = substituteFor(types[i]);
-    }
-    return substitutedTypes;
-  }
-
   @override
   void visitChildren(ElementVisitor visitor) {
     // There are no children to visit
@@ -8552,12 +8156,6 @@
  */
 class MethodElementImpl extends ExecutableElementImpl implements MethodElement {
   /**
-   * An empty list of method elements.
-   */
-  @deprecated // Use MethodElement.EMPTY_LIST
-  static const List<MethodElement> EMPTY_ARRAY = const <MethodElement>[];
-
-  /**
    * Initialize a newly created method element to have the given [name] at the
    * given [offset].
    */
@@ -8644,11 +8242,14 @@
  */
 class MethodMember extends ExecutableMember implements MethodElement {
   /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
+   * Initialize a newly created element to represent a method, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed, it
+   * represents the full type of the member, and will take precedence over
+   * the [definingType].
    */
-  MethodMember(MethodElement baseElement, InterfaceType definingType)
-      : super(baseElement, definingType);
+  MethodMember(MethodElement baseElement, InterfaceType definingType,
+      [DartType type])
+      : super(baseElement, definingType, type);
 
   @override
   MethodElement get baseElement => super.baseElement as MethodElement;
@@ -8706,10 +8307,7 @@
     if (baseType == substitutedType) {
       return method;
     }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    return new MethodMember(method, definingType);
+    return new MethodMember(method, definingType, substitutedType);
   }
 }
 
@@ -8962,10 +8560,6 @@
   @override
   int get nameOffset => -1;
 
-  @deprecated
-  @override
-  AstNode get node => null;
-
   @override
   Source get source => null;
 
@@ -9142,13 +8736,6 @@
   /**
    * An empty list of namespace combinators.
    */
-  @deprecated // Use NamespaceCombinator.EMPTY_LIST
-  static const List<NamespaceCombinator> EMPTY_ARRAY =
-      const <NamespaceCombinator>[];
-
-  /**
-   * An empty list of namespace combinators.
-   */
   static const List<NamespaceCombinator> EMPTY_LIST =
       const <NamespaceCombinator>[];
 }
@@ -9209,12 +8796,6 @@
     with ParameterElementMixin
     implements ParameterElement {
   /**
-   * An empty list of parameter elements.
-   */
-  @deprecated // Use ParameterElement.EMPTY_LIST
-  static const List<ParameterElement> EMPTY_ARRAY = const <ParameterElement>[];
-
-  /**
    * A list containing all of the parameters defined by this parameter element.
    * There will only be parameters if this parameter is a function typed
    * parameter.
@@ -9436,11 +9017,13 @@
     with ParameterElementMixin
     implements ParameterElement {
   /**
-   * Initialize a newly created element to represent a constructor, based on the
-   * [baseElement], defined by the [definingType].
+   * Initialize a newly created element to represent a parameter, based on the
+   * [baseElement], defined by the [definingType]. If [type] is passed it will
+   * represent the already substituted type.
    */
-  ParameterMember(ParameterElement baseElement, ParameterizedType definingType)
-      : super(baseElement, definingType);
+  ParameterMember(ParameterElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : super._(baseElement, definingType, type);
 
   @override
   ParameterElement get baseElement => super.baseElement as ParameterElement;
@@ -9462,18 +9045,11 @@
 
   @override
   List<ParameterElement> get parameters {
-    List<ParameterElement> baseParameters = baseElement.parameters;
-    int parameterCount = baseParameters.length;
-    if (parameterCount == 0) {
-      return baseParameters;
+    DartType type = this.type;
+    if (type is FunctionType) {
+      return type.parameters;
     }
-    List<ParameterElement> parameterizedParameters =
-        new List<ParameterElement>(parameterCount);
-    for (int i = 0; i < parameterCount; i++) {
-      parameterizedParameters[i] =
-          ParameterMember.from(baseParameters[i], definingType);
-    }
-    return parameterizedParameters;
+    return ParameterElement.EMPTY_LIST;
   }
 
   @override
@@ -9482,6 +9058,8 @@
   @override
   SourceRange get visibleRange => baseElement.visibleRange;
 
+  // TODO(jmesserly): this equality is broken. It should consider the defining
+  // type as well, otherwise we're dropping the substitution.
   @override
   bool operator ==(Object object) =>
       object is ParameterMember && baseElement == object.baseElement;
@@ -9548,8 +9126,9 @@
     // Check if parameter type depends on defining type type arguments.
     // It is possible that we did not resolve field formal parameter yet,
     // so skip this check for it.
-    bool isFieldFormal = parameter is FieldFormalParameterElement;
-    if (!isFieldFormal) {
+    if (parameter is FieldFormalParameterElement) {
+      return new FieldFormalParameterMember(parameter, definingType);
+    } else {
       DartType baseType = parameter.type;
       List<DartType> argumentTypes = definingType.typeArguments;
       List<DartType> parameterTypes =
@@ -9559,15 +9138,8 @@
       if (baseType == substitutedType) {
         return parameter;
       }
+      return new ParameterMember(parameter, definingType, substitutedType);
     }
-    // TODO(brianwilkerson) Consider caching the substituted type in the
-    // instance. It would use more memory but speed up some operations.
-    // We need to see how often the type is being re-computed.
-    if (isFieldFormal) {
-      return new FieldFormalParameterMember(
-          parameter as FieldFormalParameterElement, definingType);
-    }
-    return new ParameterMember(parameter, definingType);
   }
 }
 
@@ -9599,12 +9171,6 @@
  */
 class PrefixElementImpl extends ElementImpl implements PrefixElement {
   /**
-   * An empty list of prefix elements.
-   */
-  @deprecated // Use PrefixElement.EMPTY_LIST
-  static const List<PrefixElement> EMPTY_ARRAY = const <PrefixElement>[];
-
-  /**
    * A list containing all of the libraries that are imported using this prefix.
    */
   List<LibraryElement> _importedLibraries = LibraryElement.EMPTY_LIST;
@@ -9712,13 +9278,6 @@
 class PropertyAccessorElementImpl extends ExecutableElementImpl
     implements PropertyAccessorElement {
   /**
-   * An empty list of property accessor elements.
-   */
-  @deprecated // Use PropertyAccessorElement.EMPTY_LIST
-  static const List<PropertyAccessorElement> EMPTY_ARRAY =
-      const <PropertyAccessorElement>[];
-
-  /**
    * The variable associated with this accessor.
    */
   PropertyInducingElement variable;
@@ -9820,7 +9379,8 @@
   }
 
   @override
-  bool operator ==(Object object) => super == object &&
+  bool operator ==(Object object) =>
+      super == object &&
       isGetter == (object as PropertyAccessorElement).isGetter;
 
   @override
@@ -9855,7 +9415,7 @@
 class PropertyAccessorMember extends ExecutableMember
     implements PropertyAccessorElement {
   /**
-   * Initialize a newly created element to represent a constructor, based on the
+   * Initialize a newly created element to represent a property, based on the
    * [baseElement], defined by the [definingType].
    */
   PropertyAccessorMember(
@@ -10041,13 +9601,6 @@
 abstract class PropertyInducingElementImpl extends VariableElementImpl
     implements PropertyInducingElement {
   /**
-   * An empty list of elements.
-   */
-  @deprecated // Use PropertyInducingElement.EMPTY_LIST
-  static const List<PropertyInducingElement> EMPTY_ARRAY =
-      const <PropertyInducingElement>[];
-
-  /**
    * The getter associated with this element.
    */
   PropertyAccessorElement getter;
@@ -10108,26 +9661,12 @@
   }
 
   @override
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
   R visitExportElement(ExportElement element) {
     element.visitChildren(this);
     return null;
   }
 
   @override
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
   R visitFieldElement(FieldElement element) {
     element.visitChildren(this);
     return null;
@@ -10152,13 +9691,6 @@
   }
 
   @override
-  @deprecated
-  R visitHtmlElement(HtmlElement element) {
-    element.visitChildren(this);
-    return null;
-  }
-
-  @override
   R visitImportElement(ImportElement element) {
     element.visitChildren(this);
     return null;
@@ -10301,17 +9833,9 @@
   R visitConstructorElement(ConstructorElement element) => null;
 
   @override
-  @deprecated
-  R visitEmbeddedHtmlScriptElement(EmbeddedHtmlScriptElement element) => null;
-
-  @override
   R visitExportElement(ExportElement element) => null;
 
   @override
-  @deprecated
-  R visitExternalHtmlScriptElement(ExternalHtmlScriptElement element) => null;
-
-  @override
   R visitFieldElement(FieldElement element) => null;
 
   @override
@@ -10325,10 +9849,6 @@
   R visitFunctionTypeAliasElement(FunctionTypeAliasElement element) => null;
 
   @override
-  @deprecated
-  R visitHtmlElement(HtmlElement element) => null;
-
-  @override
   R visitImportElement(ImportElement element) => null;
 
   @override
@@ -10382,13 +9902,6 @@
 class TopLevelVariableElementImpl extends PropertyInducingElementImpl
     implements TopLevelVariableElement {
   /**
-   * An empty list of top-level variable elements.
-   */
-  @deprecated // Use TopLevelVariableElement.EMPTY_LIST
-  static const List<TopLevelVariableElement> EMPTY_ARRAY =
-      const <TopLevelVariableElement>[];
-
-  /**
    * Initialize a newly created synthetic top-level variable element to have the
    * given [name] and [offset].
    */
@@ -10430,12 +9943,6 @@
  */
 abstract class TypeImpl implements DartType {
   /**
-   * An empty list of types.
-   */
-  @deprecated // Use DartType.EMPTY_LIST
-  static const List<DartType> EMPTY_ARRAY = const <DartType>[];
-
-  /**
    * The element representing the declaration of this type, or `null` if the
    * type has not, or cannot, be associated with an element.
    */
@@ -10488,9 +9995,6 @@
     }
   }
 
-  @override
-  DartType getLeastUpperBound(DartType type) => null;
-
   /**
    * Return `true` if this type is assignable to the given [type] (written in
    * the spec as "T <=> S", where T=[this] and S=[type]).
@@ -10658,13 +10162,6 @@
 class TypeParameterElementImpl extends ElementImpl
     implements TypeParameterElement {
   /**
-   * An empty list of type parameter elements.
-   */
-  @deprecated // Use TypeParameterElement.EMPTY_LIST
-  static const List<TypeParameterElement> EMPTY_ARRAY =
-      const <TypeParameterElement>[];
-
-  /**
    * The type defined by this type parameter.
    */
   TypeParameterType type;
@@ -10734,13 +10231,6 @@
  */
 class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
   /**
-   * An empty list of type parameter types.
-   */
-  @deprecated // Use TypeParameterType.EMPTY_LIST
-  static const List<TypeParameterType> EMPTY_ARRAY =
-      const <TypeParameterType>[];
-
-  /**
    * Initialize a newly created type parameter type to be declared by the given
    * [element] and to have the given name.
    */
@@ -11064,12 +10554,6 @@
 abstract class VariableElementImpl extends ElementImpl
     implements VariableElement {
   /**
-   * An empty list of variable elements.
-   */
-  @deprecated // Use VariableElement.EMPTY_LIST
-  static const List<VariableElement> EMPTY_ARRAY = const <VariableElement>[];
-
-  /**
    * The declared type of this variable.
    */
   DartType type;
@@ -11194,12 +10678,25 @@
  * type parameters are known.
  */
 abstract class VariableMember extends Member implements VariableElement {
+  @override
+  final DartType type;
+
   /**
-   * Initialize a newly created element to represent a constructor, based on the
+   * Initialize a newly created element to represent a variable, based on the
    * [baseElement], defined by the [definingType].
    */
-  VariableMember(VariableElement baseElement, ParameterizedType definingType)
-      : super(baseElement, definingType);
+  VariableMember(VariableElement baseElement, ParameterizedType definingType,
+      [DartType type])
+      : type = type ??
+            baseElement.type.substitute2(definingType.typeArguments,
+                TypeParameterTypeImpl.getTypes(definingType.typeParameters)),
+        super(baseElement, definingType);
+
+  // TODO(jmesserly): this is temporary to allow the ParameterMember subclass.
+  // Apparently mixins don't work with optional params.
+  VariableMember._(VariableElement baseElement, ParameterizedType definingType,
+      DartType type)
+      : this(baseElement, definingType, type);
 
   @override
   VariableElement get baseElement => super.baseElement as VariableElement;
@@ -11238,9 +10735,6 @@
   bool get isStatic => baseElement.isStatic;
 
   @override
-  DartType get type => substituteFor(baseElement.type);
-
-  @override
   void visitChildren(ElementVisitor visitor) {
     // TODO(brianwilkerson) We need to finish implementing the accessors used
     // below so that we can safely invoke them.
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index f496602..09e23c0 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.element_handle;
+library analyzer.src.generated.element_handle;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
@@ -68,10 +68,6 @@
   bool get isProxy => actualElement.isProxy;
 
   @override
-  @deprecated
-  bool get isTypedef => actualElement.isMixinApplication;
-
-  @override
   bool get isValidMixin => actualElement.isValidMixin;
 
   @override
@@ -380,10 +376,6 @@
   @override
   int get nameOffset => actualElement.nameOffset;
 
-  @deprecated
-  @override
-  AstNode get node => computeNode();
-
   @override
   Source get source => actualElement.source;
 
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 8c981ff..70defdf 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -2,17 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver.element_resolver;
+library analyzer.src.generated.element_resolver;
 
 import 'dart:collection';
 
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
  * An object used by instances of [ResolverVisitor] to resolve references within
@@ -102,7 +102,7 @@
   /**
    * The type representing the type 'type'.
    */
-  DartType _typeType;
+  InterfaceType _typeType;
 
   /**
    * A utility class for the resolver to answer the question of "what are my
@@ -594,8 +594,6 @@
     }
     Element staticElement;
     Element propagatedElement;
-    DartType staticType = null;
-    DartType propagatedType = null;
     if (target == null) {
       staticElement = _resolveInvokedElement(methodName);
       propagatedElement = null;
@@ -611,8 +609,6 @@
       methodName.staticElement = importedLibrary.loadLibraryFunction;
       return null;
     } else {
-      staticType = _getStaticType(target);
-      propagatedType = _getPropagatedType(target);
       //
       // If this method invocation is of the form 'C.m' where 'C' is a class,
       // then we don't call resolveInvokedElement(...) which walks up the class
@@ -622,8 +618,13 @@
       bool isConditional = node.operator.type == sc.TokenType.QUESTION_PERIOD;
       ClassElementImpl typeReference = getTypeReference(target);
       if (typeReference != null) {
+        if (node.isCascaded) {
+          typeReference = _typeType.element;
+        }
         staticElement = _resolveElement(typeReference, methodName);
       } else {
+        DartType staticType = _getStaticType(target);
+        DartType propagatedType = _getPropagatedType(target);
         staticElement = _resolveInvokedElementWithTarget(
             target, staticType, methodName, isConditional);
         // If we have propagated type information use it (since it should
@@ -635,6 +636,46 @@
         }
       }
     }
+    //
+    // Check for a generic method & apply type arguments if any were passed.
+    //
+    if (staticElement is MethodElement || staticElement is FunctionElement) {
+      FunctionType type = (staticElement as ExecutableElement).type;
+      List<TypeParameterElement> parameters = type.boundTypeParameters;
+
+      NodeList<TypeName> arguments = node.typeArguments?.arguments;
+      if (arguments != null && arguments.length != parameters.length) {
+        // Wrong number of type arguments. Ignore them
+        arguments = null;
+        _resolver.reportErrorForNode(
+            StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
+            methodName,
+            [type, parameters.length, arguments.length]);
+      }
+      if (parameters.isNotEmpty) {
+        List<DartType> typeArgs;
+        if (arguments == null) {
+          typeArgs = new List<DartType>.filled(
+              parameters.length, DynamicTypeImpl.instance);
+        } else {
+          typeArgs = new List<DartType>.from(arguments.map((n) => n.type));
+        }
+        type = type.instantiate(typeArgs);
+
+        if (staticElement is MethodMember) {
+          MethodMember member = staticElement;
+          staticElement =
+              new MethodMember(member.baseElement, member.definingType, type);
+        } else if (staticElement is MethodElement) {
+          ClassElement clazz = staticElement.enclosingElement;
+          staticElement = new MethodMember(staticElement, clazz.type, type);
+        } else {
+          staticElement =
+              new FunctionMember(staticElement as FunctionElement, type);
+        }
+      }
+    }
+
     staticElement = _convertSetterToGetter(staticElement);
     propagatedElement = _convertSetterToGetter(propagatedElement);
     //
@@ -733,17 +774,19 @@
 //          resolveArgumentsToParameters(node.getArgumentList(), invokedFunction);
           return null;
         }
-        ClassElementImpl typeReference = getTypeReference(target);
-        if (typeReference != null) {
-          ConstructorElement constructor =
-              typeReference.getNamedConstructor(methodName.name);
-          if (constructor != null) {
-            _recordUndefinedNode(
-                typeReference,
-                StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
-                methodName,
-                [methodName.name, typeReference.name]);
-            return null;
+        if (!node.isCascaded) {
+          ClassElementImpl typeReference = getTypeReference(target);
+          if (typeReference != null) {
+            ConstructorElement constructor =
+                typeReference.getNamedConstructor(methodName.name);
+            if (constructor != null) {
+              _recordUndefinedNode(
+                  typeReference,
+                  StaticTypeWarningCode.UNDEFINED_METHOD_WITH_CONSTRUCTOR,
+                  methodName,
+                  [methodName.name, typeReference.name]);
+              return null;
+            }
           }
         }
         targetTypeName = targetType == null ? null : targetType.displayName;
@@ -883,7 +926,7 @@
     // Otherwise, the prefix is really an expression that happens to be a simple
     // identifier and this is really equivalent to a property access node.
     //
-    _resolvePropertyAccess(prefix, identifier);
+    _resolvePropertyAccess(prefix, identifier, false);
     return null;
   }
 
@@ -939,7 +982,7 @@
       return null;
     }
     SimpleIdentifier propertyName = node.propertyName;
-    _resolvePropertyAccess(target, propertyName);
+    _resolvePropertyAccess(target, propertyName, node.isCascaded);
     return null;
   }
 
@@ -2211,7 +2254,7 @@
   }
 
   void _resolvePropertyAccess(
-      Expression target, SimpleIdentifier propertyName) {
+      Expression target, SimpleIdentifier propertyName, bool isCascaded) {
     DartType staticType = _getStaticType(target);
     DartType propagatedType = _getPropagatedType(target);
     Element staticElement = null;
@@ -2224,6 +2267,9 @@
     //
     ClassElementImpl typeReference = getTypeReference(target);
     if (typeReference != null) {
+      if (isCascaded) {
+        typeReference = _typeType.element;
+      }
       // TODO(brianwilkerson) Why are we setting the propagated element here?
       // It looks wrong.
       staticElement =
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index fbb9825..bafc908 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -2,50 +2,36 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine;
+library analyzer.src.generated.engine;
 
 import 'dart:async';
 import 'dart:collection';
-import 'dart:math' as math;
 
+import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/cache.dart' as cache;
-import 'package:analyzer/src/context/context.dart' as newContext;
-import 'package:analyzer/src/generated/incremental_resolution_validator.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.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_general.dart';
 import 'package:analyzer/src/plugin/command_line_plugin.dart';
 import 'package:analyzer/src/plugin/engine_plugin.dart';
 import 'package:analyzer/src/plugin/options_plugin.dart';
-import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/task/manager.dart';
 import 'package:analyzer/task/dart.dart';
-import 'package:analyzer/task/model.dart' as newContext;
 import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
 import 'package:path/path.dart' as pathos;
 import 'package:plugin/manager.dart';
 import 'package:plugin/plugin.dart';
 
-import '../../instrumentation/instrumentation.dart';
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'error.dart';
-import 'error_verifier.dart';
-import 'html.dart' as ht;
-import 'incremental_resolver.dart'
-    show IncrementalResolver, PoorMansIncrementalResolver;
-import 'incremental_scanner.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser, IncrementalParser;
-import 'resolver.dart';
-import 'scanner.dart';
-import 'sdk.dart' show DartSdk;
-import 'source.dart';
-import 'utilities_collection.dart';
-import 'utilities_general.dart';
-
 /**
  * Used by [AnalysisOptions] to allow function bodies to be analyzed in some
  * sources but not others.
@@ -53,226 +39,6 @@
 typedef bool AnalyzeFunctionBodiesPredicate(Source source);
 
 /**
- * Type of callback functions used by PendingFuture.  Functions of this type
- * should perform a computation based on the data in [sourceEntry] and return
- * it.  If the computation can't be performed yet because more analysis is
- * needed, null should be returned.
- *
- * The function may also throw an exception, in which case the corresponding
- * future will be completed with failure.
- *
- * Since this function is called while the state of analysis is being updated,
- * it should be free of side effects so that it doesn't cause reentrant
- * changes to the analysis state.
- */
-typedef T PendingFutureComputer<T>(SourceEntry sourceEntry);
-
-/**
- * An LRU cache of information related to analysis.
- */
-class AnalysisCache {
-  /**
-   * A flag used to control whether trace information should be produced when
-   * the content of the cache is modified.
-   */
-  static bool _TRACE_CHANGES = false;
-
-  /**
-   * A list containing the partitions of which this cache is comprised.
-   */
-  final List<CachePartition> _partitions;
-
-  /**
-   * Initialize a newly created cache to have the given [_partitions]. The
-   * partitions will be searched in the order in which they appear in the list,
-   * so the most specific partition (usually an [SdkCachePartition]) should be
-   * first and the most general (usually a [UniversalCachePartition]) last.
-   */
-  AnalysisCache(this._partitions);
-
-  /**
-   * Return the number of entries in this cache that have an AST associated with
-   * them.
-   */
-  int get astSize => _partitions[_partitions.length - 1].astSize;
-
-  /**
-   * Return information about each of the partitions in this cache.
-   */
-  List<AnalysisContextStatistics_PartitionData> get partitionData {
-    int count = _partitions.length;
-    List<AnalysisContextStatistics_PartitionData> data =
-        new List<AnalysisContextStatistics_PartitionData>(count);
-    for (int i = 0; i < count; i++) {
-      CachePartition partition = _partitions[i];
-      data[i] = new AnalysisContextStatisticsImpl_PartitionDataImpl(
-          partition.astSize, partition.map.length);
-    }
-    return data;
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just read from
-   * the cache.
-   */
-  void accessedAst(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        _partitions[i].accessedAst(source);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Return the entry associated with the given [source].
-   */
-  SourceEntry get(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        return _partitions[i].get(source);
-      }
-    }
-    //
-    // We should never get to this point because the last partition should
-    // always be a universal partition, except in the case of the SDK context,
-    // in which case the source should always be part of the SDK.
-    //
-    return null;
-  }
-
-  /**
-   * Return context that owns the given [source].
-   */
-  InternalAnalysisContext getContextFor(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        return _partitions[i].context;
-      }
-    }
-    //
-    // We should never get to this point because the last partition should
-    // always be a universal partition, except in the case of the SDK context,
-    // in which case the source should always be part of the SDK.
-    //
-    AnalysisEngine.instance.logger.logInformation(
-        "Could not find context for ${source.fullName}",
-        new CaughtException(new AnalysisException(), null));
-    return null;
-  }
-
-  /**
-   * Return an iterator returning all of the map entries mapping sources to
-   * cache entries.
-   */
-  MapIterator<Source, SourceEntry> iterator() {
-    int count = _partitions.length;
-    List<Map<Source, SourceEntry>> maps =
-        new List<Map<Source, SourceEntry>>(count);
-    for (int i = 0; i < count; i++) {
-      maps[i] = _partitions[i].map;
-    }
-    return new MultipleMapIterator<Source, SourceEntry>(maps);
-  }
-
-  /**
-   * Associate the given [entry] with the given [source].
-   */
-  void put(Source source, SourceEntry entry) {
-    entry.fixExceptionState();
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        if (_TRACE_CHANGES) {
-          try {
-            SourceEntry oldEntry = _partitions[i].get(source);
-            if (oldEntry == null) {
-              AnalysisEngine.instance.logger.logInformation(
-                  "Added a cache entry for '${source.fullName}'.");
-            } else {
-              AnalysisEngine.instance.logger.logInformation(
-                  "Modified the cache entry for ${source.fullName}'. Diff = ${entry.getDiff(oldEntry)}");
-            }
-          } catch (exception) {
-            // Ignored
-            JavaSystem.currentTimeMillis();
-          }
-        }
-        _partitions[i].put(source, entry);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Remove all information related to the given [source] from this cache.
-   * Return the entry associated with the source, or `null` if there was cache
-   * entry for the source.
-   */
-  SourceEntry remove(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        if (_TRACE_CHANGES) {
-          try {
-            AnalysisEngine.instance.logger.logInformation(
-                "Removed the cache entry for ${source.fullName}'.");
-          } catch (exception) {
-            // Ignored
-            JavaSystem.currentTimeMillis();
-          }
-        }
-        return _partitions[i].remove(source);
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just removed
-   * from the cache.
-   */
-  void removedAst(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        _partitions[i].removedAst(source);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Return the number of sources that are mapped to cache entries.
-   */
-  int size() {
-    int size = 0;
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      size += _partitions[i].size();
-    }
-    return size;
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just stored to
-   * the cache.
-   */
-  void storedAst(Source source) {
-    int count = _partitions.length;
-    for (int i = 0; i < count; i++) {
-      if (_partitions[i].contains(source)) {
-        _partitions[i].storedAst(source);
-        return;
-      }
-    }
-  }
-}
-
-/**
  * A context in which a single analysis can be performed and incrementally
  * maintained. The context includes such information as the version of the SDK
  * being analyzed against as well as the package-root used to resolve 'package:'
@@ -486,24 +252,6 @@
   List<AnalysisError> computeErrors(Source source);
 
   /**
-   * Return the element model corresponding to the HTML file defined by the
-   * given [source]. If the element model does not yet exist it will be created.
-   * The process of creating an element model for an HTML file can be
-   * long-running, depending on the size of the file and the number of libraries
-   * that are defined in it (via script tags) that also need to have a model
-   * built for them.
-   *
-   * Throws AnalysisException if the element model could not be determined
-   * because the analysis could not be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   *
-   * See [getHtmlElement].
-   */
-  @deprecated
-  HtmlElement computeHtmlElement(Source source);
-
-  /**
    * Return the kind of the given [source], computing it's kind if it is not
    * already known. Return [SourceKind.UNKNOWN] if the source is not contained
    * in this context.
@@ -564,7 +312,7 @@
    * Perform work until the given [result] has been computed for the given
    * [target]. Return the computed value.
    */
-  Object /*V*/ computeResult(
+  Object /*=V*/ computeResult /*<V>*/ (
       AnalysisTarget target, ResultDescriptor /*<V>*/ result);
 
   /**
@@ -629,17 +377,6 @@
   AnalysisErrorInfo getErrors(Source source);
 
   /**
-   * Return the element model corresponding to the HTML file defined by the
-   * given [source], or `null` if the source does not represent an HTML file,
-   * the element representing the file has not yet been created, or the analysis
-   * of the HTML file failed for some reason.
-   *
-   * See [computeHtmlElement].
-   */
-  @deprecated
-  HtmlElement getHtmlElement(Source source);
-
-  /**
    * Return the sources for the HTML files that reference the compilation unit
    * with the given [source]. If the source does not represent a Dart source or
    * is not known to this context, the returned list will be empty. The contents
@@ -732,21 +469,12 @@
       Source unitSource, Source librarySource);
 
   /**
-   * Return the fully resolved HTML unit defined by the given [htmlSource], or
-   * `null` if the resolved unit is not already computed.
-   *
-   * See [resolveHtmlUnit].
-   */
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource);
-
-  /**
    * Return the value of the given [result] for the given [target].
    *
    * If the corresponding [target] does not exist, or the [result] is not
    * computed yet, then the default value is returned.
    */
-  Object /*V*/ getResult(
+  Object /*=V*/ getResult /*<V>*/ (
       AnalysisTarget target, ResultDescriptor /*<V>*/ result);
 
   /**
@@ -811,18 +539,6 @@
   Document parseHtmlDocument(Source source);
 
   /**
-   * Parse a single HTML [source] to produce an AST structure. The resulting
-   * HTML AST structure may or may not be resolved, and may have a slightly
-   * different structure depending upon whether it is resolved.
-   *
-   * Throws an [AnalysisException] if the analysis could not be performed
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  @deprecated // use parseHtmlDocument(source)
-  ht.HtmlUnit parseHtmlUnit(Source source);
-
-  /**
    * Perform the next unit of work required to keep the analysis results
    * up-to-date and return information about the consequent changes to the
    * analysis results. This method can be long running.
@@ -877,17 +593,6 @@
       Source unitSource, Source librarySource);
 
   /**
-   * Parse and resolve a single [htmlSource] within the given context to produce
-   * a fully resolved AST.
-   *
-   * Throws an [AnalysisException] if the analysis could not be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource);
-
-  /**
    * Set the contents of the given [source] to the given [contents] and mark the
    * source as having changed. The additional [offset] and [length] information
    * is used by the context to determine what reanalysis is necessary.
@@ -920,4880 +625,6 @@
 }
 
 /**
- * An [AnalysisContext].
- */
-class AnalysisContextImpl implements InternalAnalysisContext {
-  /**
-   * The difference between the maximum cache size and the maximum priority
-   * order size. The priority list must be capped so that it is less than the
-   * cache size. Failure to do so can result in an infinite loop in
-   * performAnalysisTask() because re-caching one AST structure can cause
-   * another priority source's AST structure to be flushed.
-   */
-  static int _PRIORITY_ORDER_SIZE_DELTA = 4;
-
-  /**
-   * A flag indicating whether trace output should be produced as analysis tasks
-   * are performed. Used for debugging.
-   */
-  static bool _TRACE_PERFORM_TASK = false;
-
-  /**
-   * The next context identifier.
-   */
-  static int _NEXT_ID = 0;
-
-  /**
-   * The unique identifier of this context.
-   */
-  final int _id = _NEXT_ID++;
-
-  /**
-   * A client-provided name used to identify this context, or `null` if the
-   * client has not provided a name.
-   */
-  String name;
-
-  /**
-   * Configuration data associated with this context.
-   */
-  final HashMap<ResultDescriptor, Object> _configurationData =
-      new HashMap<ResultDescriptor, Object>();
-
-  /**
-   * The set of analysis options controlling the behavior of this context.
-   */
-  AnalysisOptionsImpl _options = new AnalysisOptionsImpl();
-
-  /// The embedder yaml locator for this context.
-  EmbedderYamlLocator _embedderYamlLocator = new EmbedderYamlLocator(null);
-
-  /**
-   * A flag indicating whether errors related to implicitly analyzed sources
-   * should be generated and reported.
-   */
-  bool _generateImplicitErrors = true;
-
-  /**
-   * A flag indicating whether errors related to sources in the SDK should be
-   * generated and reported.
-   */
-  bool _generateSdkErrors = true;
-
-  /**
-   * A flag indicating whether this context is disposed.
-   */
-  bool _disposed = false;
-
-  /**
-   * A cache of content used to override the default content of a source.
-   */
-  ContentCache _contentCache = new ContentCache();
-
-  /**
-   * The source factory used to create the sources that can be analyzed in this
-   * context.
-   */
-  SourceFactory _sourceFactory;
-
-  /**
-   * The set of declared variables used when computing constant values.
-   */
-  DeclaredVariables _declaredVariables = new DeclaredVariables();
-
-  /**
-   * A source representing the core library.
-   */
-  Source _coreLibrarySource;
-
-  /**
-   * A source representing the async library.
-   */
-  Source _asyncLibrarySource;
-
-  /**
-   * The partition that contains analysis results that are not shared with other
-   * contexts.
-   */
-  CachePartition _privatePartition;
-
-  /**
-   * A table mapping the sources known to the context to the information known
-   * about the source.
-   */
-  AnalysisCache _cache;
-
-  /**
-   * A list containing sources for which data should not be flushed.
-   */
-  List<Source> _priorityOrder = Source.EMPTY_LIST;
-
-  /**
-   * A map from all sources for which there are futures pending to a list of
-   * the corresponding PendingFuture objects.  These sources will be analyzed
-   * in the same way as priority sources, except with higher priority.
-   *
-   * TODO(paulberry): since the size of this map is not constrained (as it is
-   * for _priorityOrder), we run the risk of creating an analysis loop if
-   * re-caching one AST structure causes the AST structure for another source
-   * with pending futures to be flushed.  However, this is unlikely to happen
-   * in practice since sources are removed from this hash set as soon as their
-   * futures have completed.
-   */
-  HashMap<Source, List<PendingFuture>> _pendingFutureSources =
-      new HashMap<Source, List<PendingFuture>>();
-
-  /**
-   * A list containing sources whose AST structure is needed in order to resolve
-   * the next library to be resolved.
-   */
-  HashSet<Source> _neededForResolution = null;
-
-  /**
-   * A table mapping sources to the change notices that are waiting to be
-   * returned related to that source.
-   */
-  HashMap<Source, ChangeNoticeImpl> _pendingNotices =
-      new HashMap<Source, ChangeNoticeImpl>();
-
-  /**
-   * The object used to record the results of performing an analysis task.
-   */
-  AnalysisContextImpl_AnalysisTaskResultRecorder _resultRecorder;
-
-  /**
-   * Cached information used in incremental analysis or `null` if none.
-   */
-  IncrementalAnalysisCache _incrementalAnalysisCache;
-
-  /**
-   * The [TypeProvider] for this context, `null` if not yet created.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * The [TypeSystem] for this context, `null` if not yet created.
-   */
-  TypeSystem _typeSystem;
-
-  /**
-   * The object used to manage the list of sources that need to be analyzed.
-   */
-  WorkManager _workManager = new WorkManager();
-
-  /**
-   * The [Stopwatch] of the current "perform tasks cycle".
-   */
-  Stopwatch _performAnalysisTaskStopwatch;
-
-  /**
-   * The controller for sending [SourcesChangedEvent]s.
-   */
-  StreamController<SourcesChangedEvent> _onSourcesChangedController;
-
-  /**
-   * A subscription for a stream of events indicating when files are (and are
-   * not) being implicitly analyzed.
-   */
-  StreamController<ImplicitAnalysisEvent> _implicitAnalysisEventsController;
-
-  /**
-   * The listeners that are to be notified when various analysis results are
-   * produced in this context.
-   */
-  List<AnalysisListener> _listeners = new List<AnalysisListener>();
-
-  /**
-   * The most recently incrementally resolved source, or `null` when it was
-   * already validated, or the most recent change was not incrementally resolved.
-   */
-  Source incrementalResolutionValidation_lastUnitSource;
-
-  /**
-   * The most recently incrementally resolved library source, or `null` when it
-   * was already validated, or the most recent change was not incrementally
-   * resolved.
-   */
-  Source incrementalResolutionValidation_lastLibrarySource;
-
-  /**
-   * The result of incremental resolution result of
-   * [incrementalResolutionValidation_lastSource].
-   */
-  CompilationUnit incrementalResolutionValidation_lastUnit;
-
-  /**
-   * A factory to override how the [ResolverVisitor] is created.
-   */
-  ResolverVisitorFactory resolverVisitorFactory;
-
-  /**
-   * A factory to override how the [TypeResolverVisitor] is created.
-   */
-  TypeResolverVisitorFactory typeResolverVisitorFactory;
-
-  /**
-   * A factory to override how [LibraryResolver] is created.
-   */
-  LibraryResolverFactory libraryResolverFactory;
-
-  /**
-   * Initialize a newly created analysis context.
-   */
-  AnalysisContextImpl() {
-    _resultRecorder = new AnalysisContextImpl_AnalysisTaskResultRecorder(this);
-    _privatePartition = new UniversalCachePartition(
-        this,
-        AnalysisOptionsImpl.DEFAULT_CACHE_SIZE,
-        new AnalysisContextImpl_ContextRetentionPolicy(this));
-    _cache = createCacheFromSourceFactory(null);
-    _onSourcesChangedController =
-        new StreamController<SourcesChangedEvent>.broadcast();
-    _implicitAnalysisEventsController =
-        new StreamController<ImplicitAnalysisEvent>.broadcast();
-  }
-
-  @override
-  AnalysisCache get analysisCache => _cache;
-
-  @override
-  AnalysisOptions get analysisOptions => _options;
-
-  @override
-  void set analysisOptions(AnalysisOptions options) {
-    bool needsRecompute = this._options.analyzeFunctionBodiesPredicate !=
-            options.analyzeFunctionBodiesPredicate ||
-        this._options.generateImplicitErrors !=
-            options.generateImplicitErrors ||
-        this._options.generateSdkErrors != options.generateSdkErrors ||
-        this._options.dart2jsHint != options.dart2jsHint ||
-        (this._options.hint && !options.hint) ||
-        this._options.preserveComments != options.preserveComments ||
-        this._options.strongMode != options.strongMode ||
-        ((options is AnalysisOptionsImpl)
-            ? this._options.strongModeHints != options.strongModeHints
-            : false) ||
-        this._options.enableStrictCallChecks !=
-            options.enableStrictCallChecks ||
-        this._options.enableSuperMixins != options.enableSuperMixins;
-    int cacheSize = options.cacheSize;
-    if (this._options.cacheSize != cacheSize) {
-      this._options.cacheSize = cacheSize;
-      //cache.setMaxCacheSize(cacheSize);
-      _privatePartition.maxCacheSize = cacheSize;
-      //
-      // Cap the size of the priority list to being less than the cache size.
-      // Failure to do so can result in an infinite loop in
-      // performAnalysisTask() because re-caching one AST structure
-      // can cause another priority source's AST structure to be flushed.
-      //
-      // TODO(brianwilkerson) Remove this constraint when the new task model is
-      // implemented.
-      //
-      int maxPriorityOrderSize = cacheSize - _PRIORITY_ORDER_SIZE_DELTA;
-      if (_priorityOrder.length > maxPriorityOrderSize) {
-        _priorityOrder = _priorityOrder.sublist(0, maxPriorityOrderSize);
-      }
-    }
-    this._options.analyzeFunctionBodiesPredicate =
-        options.analyzeFunctionBodiesPredicate;
-    this._options.generateImplicitErrors = options.generateImplicitErrors;
-    this._options.generateSdkErrors = options.generateSdkErrors;
-    this._options.dart2jsHint = options.dart2jsHint;
-    this._options.enableStrictCallChecks = options.enableStrictCallChecks;
-    this._options.enableSuperMixins = options.enableSuperMixins;
-    this._options.hint = options.hint;
-    this._options.incremental = options.incremental;
-    this._options.incrementalApi = options.incrementalApi;
-    this._options.incrementalValidation = options.incrementalValidation;
-    this._options.lint = options.lint;
-    this._options.preserveComments = options.preserveComments;
-    this._options.strongMode = options.strongMode;
-    if (options is AnalysisOptionsImpl) {
-      this._options.strongModeHints = options.strongModeHints;
-    }
-    _generateImplicitErrors = options.generateImplicitErrors;
-    _generateSdkErrors = options.generateSdkErrors;
-    if (needsRecompute) {
-      _invalidateAllLocalResolutionInformation(false);
-    }
-  }
-
-  @override
-  void set analysisPriorityOrder(List<Source> sources) {
-    if (sources == null || sources.isEmpty) {
-      _priorityOrder = Source.EMPTY_LIST;
-    } else {
-      while (sources.remove(null)) {
-        // Nothing else to do.
-      }
-      if (sources.isEmpty) {
-        _priorityOrder = Source.EMPTY_LIST;
-      }
-      //
-      // Cap the size of the priority list to being less than the cache size.
-      // Failure to do so can result in an infinite loop in
-      // performAnalysisTask() because re-caching one AST structure
-      // can cause another priority source's AST structure to be flushed.
-      //
-      int count = math.min(
-          sources.length, _options.cacheSize - _PRIORITY_ORDER_SIZE_DELTA);
-      _priorityOrder = new List<Source>(count);
-      for (int i = 0; i < count; i++) {
-        _priorityOrder[i] = sources[i];
-      }
-      // Ensure entries for every priority source.
-      for (var source in _priorityOrder) {
-        SourceEntry entry = _getReadableSourceEntry(source);
-        if (entry == null) {
-          _createSourceEntry(source, false);
-        }
-      }
-    }
-  }
-
-  @override
-  set contentCache(ContentCache value) {
-    _contentCache = value;
-  }
-
-  @override
-  DeclaredVariables get declaredVariables => _declaredVariables;
-
-  @override
-  EmbedderYamlLocator get embedderYamlLocator => _embedderYamlLocator;
-
-  @override
-  List<AnalysisTarget> get explicitTargets {
-    List<AnalysisTarget> targets = <AnalysisTarget>[];
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.value.explicitlyAdded) {
-        targets.add(iterator.key);
-      }
-    }
-    return targets;
-  }
-
-  @override
-  List<Source> get htmlSources => _getSources(SourceKind.HTML);
-
-  @override
-  Stream<ImplicitAnalysisEvent> get implicitAnalysisEvents =>
-      _implicitAnalysisEventsController.stream;
-
-  @override
-  bool get isDisposed => _disposed;
-
-  @override
-  List<Source> get launchableClientLibrarySources {
-    // TODO(brianwilkerson) This needs to filter out libraries that do not
-    // reference dart:html, either directly or indirectly.
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
-//          DartEntry dartEntry = (DartEntry) sourceEntry;
-//          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && dartEntry.getValue(DartEntry.IS_CLIENT)) {
-        sources.add(source);
-//          }
-      }
-    }
-    return sources;
-  }
-
-  @override
-  List<Source> get launchableServerLibrarySources {
-    // TODO(brianwilkerson) This needs to filter out libraries that reference
-    // dart:html, either directly or indirectly.
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry.kind == SourceKind.LIBRARY && !source.isInSystemLibrary) {
-//          DartEntry dartEntry = (DartEntry) sourceEntry;
-//          if (dartEntry.getValue(DartEntry.IS_LAUNCHABLE) && !dartEntry.getValue(DartEntry.IS_CLIENT)) {
-        sources.add(source);
-//          }
-      }
-    }
-    return sources;
-  }
-
-  @override
-  List<Source> get librarySources => _getSources(SourceKind.LIBRARY);
-
-  /**
-   * Look through the cache for a task that needs to be performed. Return the
-   * task that was found, or `null` if there is no more work to be done.
-   */
-  AnalysisTask get nextAnalysisTask {
-    bool hintsEnabled = _options.hint;
-    bool lintsEnabled = _options.lint;
-    bool hasBlockedTask = false;
-    //
-    // Look for incremental analysis
-    //
-    if (_incrementalAnalysisCache != null &&
-        _incrementalAnalysisCache.hasWork) {
-      AnalysisTask task =
-          new IncrementalAnalysisTask(this, _incrementalAnalysisCache);
-      _incrementalAnalysisCache = null;
-      return task;
-    }
-    //
-    // Look for a source that needs to be analyzed because it has futures
-    // pending.
-    //
-    if (_pendingFutureSources.isNotEmpty) {
-      List<Source> sourcesToRemove = <Source>[];
-      AnalysisTask task;
-      for (Source source in _pendingFutureSources.keys) {
-        SourceEntry sourceEntry = _cache.get(source);
-        List<PendingFuture> pendingFutures = _pendingFutureSources[source];
-        for (int i = 0; i < pendingFutures.length;) {
-          if (pendingFutures[i].evaluate(sourceEntry)) {
-            pendingFutures.removeAt(i);
-          } else {
-            i++;
-          }
-        }
-        if (pendingFutures.isEmpty) {
-          sourcesToRemove.add(source);
-          continue;
-        }
-        AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
-            source, sourceEntry, true, hintsEnabled, lintsEnabled);
-        task = taskData.task;
-        if (task != null) {
-          break;
-        } else if (taskData.isBlocked) {
-          hasBlockedTask = true;
-        } else {
-          // There is no more work to do for this task, so forcibly complete
-          // all its pending futures.
-          for (PendingFuture pendingFuture in pendingFutures) {
-            pendingFuture.forciblyComplete();
-          }
-          sourcesToRemove.add(source);
-        }
-      }
-      for (Source source in sourcesToRemove) {
-        _pendingFutureSources.remove(source);
-      }
-      if (task != null) {
-        return task;
-      }
-    }
-    //
-    // Look for a priority source that needs to be analyzed.
-    //
-    int priorityCount = _priorityOrder.length;
-    for (int i = 0; i < priorityCount; i++) {
-      Source source = _priorityOrder[i];
-      AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
-          source, _cache.get(source), true, hintsEnabled, lintsEnabled);
-      AnalysisTask task = taskData.task;
-      if (task != null) {
-        return task;
-      } else if (taskData.isBlocked) {
-        hasBlockedTask = true;
-      }
-    }
-    if (_neededForResolution != null) {
-      List<Source> sourcesToRemove = new List<Source>();
-      for (Source source in _neededForResolution) {
-        SourceEntry sourceEntry = _cache.get(source);
-        if (sourceEntry is DartEntry) {
-          DartEntry dartEntry = sourceEntry;
-          if (!dartEntry.hasResolvableCompilationUnit) {
-            if (dartEntry.getState(DartEntry.PARSED_UNIT) == CacheState.ERROR) {
-              sourcesToRemove.add(source);
-            } else {
-              AnalysisContextImpl_TaskData taskData =
-                  _createParseDartTask(source, dartEntry);
-              AnalysisTask task = taskData.task;
-              if (task != null) {
-                return task;
-              } else if (taskData.isBlocked) {
-                hasBlockedTask = true;
-              }
-            }
-          }
-        }
-      }
-      int count = sourcesToRemove.length;
-      for (int i = 0; i < count; i++) {
-        _neededForResolution.remove(sourcesToRemove[i]);
-      }
-    }
-    //
-    // Look for a non-priority source that needs to be analyzed.
-    //
-    List<Source> sourcesToRemove = new List<Source>();
-    WorkManager_WorkIterator sources = _workManager.iterator();
-    try {
-      while (sources.hasNext) {
-        Source source = sources.next();
-        AnalysisContextImpl_TaskData taskData = _getNextAnalysisTaskForSource(
-            source, _cache.get(source), false, hintsEnabled, lintsEnabled);
-        AnalysisTask task = taskData.task;
-        if (task != null) {
-          return task;
-        } else if (taskData.isBlocked) {
-          hasBlockedTask = true;
-        } else {
-          sourcesToRemove.add(source);
-        }
-      }
-    } finally {
-      int count = sourcesToRemove.length;
-      for (int i = 0; i < count; i++) {
-        _workManager.remove(sourcesToRemove[i]);
-      }
-    }
-    if (hasBlockedTask) {
-      // All of the analysis work is blocked waiting for an asynchronous task
-      // to complete.
-      return WaitForAsyncTask.instance;
-    }
-    return null;
-  }
-
-  @override
-  Stream<SourcesChangedEvent> get onSourcesChanged =>
-      _onSourcesChangedController.stream;
-
-  /**
-   * Make _pendingFutureSources available to unit tests.
-   */
-  HashMap<Source, List<PendingFuture>> get pendingFutureSources_forTesting =>
-      _pendingFutureSources;
-
-  @override
-  List<Source> get prioritySources => _priorityOrder;
-
-  @override
-  List<AnalysisTarget> get priorityTargets => prioritySources;
-
-  @override
-  CachePartition get privateAnalysisCachePartition => _privatePartition;
-
-  @override
-  SourceFactory get sourceFactory => _sourceFactory;
-
-  @override
-  void set sourceFactory(SourceFactory factory) {
-    if (identical(_sourceFactory, factory)) {
-      return;
-    } else if (factory.context != null) {
-      throw new IllegalStateException(
-          "Source factories cannot be shared between contexts");
-    }
-    if (_sourceFactory != null) {
-      _sourceFactory.context = null;
-    }
-    factory.context = this;
-    _sourceFactory = factory;
-    _coreLibrarySource = _sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource = _sourceFactory.forUri(DartSdk.DART_ASYNC);
-    _cache = createCacheFromSourceFactory(factory);
-    _invalidateAllLocalResolutionInformation(true);
-  }
-
-  @override
-  List<Source> get sources {
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      sources.add(iterator.key);
-    }
-    return sources;
-  }
-
-  /**
-   * Return a list of the sources that would be processed by
-   * [performAnalysisTask]. This method duplicates, and must therefore be kept
-   * in sync with, [getNextAnalysisTask]. This method is intended to be used for
-   * testing purposes only.
-   */
-  List<Source> get sourcesNeedingProcessing {
-    HashSet<Source> sources = new HashSet<Source>();
-    bool hintsEnabled = _options.hint;
-    bool lintsEnabled = _options.lint;
-
-    //
-    // Look for priority sources that need to be analyzed.
-    //
-    for (Source source in _priorityOrder) {
-      _getSourcesNeedingProcessing(source, _cache.get(source), true,
-          hintsEnabled, lintsEnabled, sources);
-    }
-    //
-    // Look for non-priority sources that need to be analyzed.
-    //
-    WorkManager_WorkIterator iterator = _workManager.iterator();
-    while (iterator.hasNext) {
-      Source source = iterator.next();
-      _getSourcesNeedingProcessing(source, _cache.get(source), false,
-          hintsEnabled, lintsEnabled, sources);
-    }
-    return new List<Source>.from(sources);
-  }
-
-  @override
-  AnalysisContextStatistics get statistics {
-    AnalysisContextStatisticsImpl statistics =
-        new AnalysisContextStatisticsImpl();
-    visitCacheItems(statistics._internalPutCacheItem);
-    statistics.partitionData = _cache.partitionData;
-    return statistics;
-  }
-
-  IncrementalAnalysisCache get test_incrementalAnalysisCache {
-    return _incrementalAnalysisCache;
-  }
-
-  set test_incrementalAnalysisCache(IncrementalAnalysisCache value) {
-    _incrementalAnalysisCache = value;
-  }
-
-  List<Source> get test_priorityOrder => _priorityOrder;
-
-  @override
-  TypeProvider get typeProvider {
-    if (_typeProvider != null) {
-      return _typeProvider;
-    }
-    Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
-    if (coreSource == null) {
-      throw new AnalysisException("Could not create a source for dart:core");
-    }
-    LibraryElement coreElement = computeLibraryElement(coreSource);
-    if (coreElement == null) {
-      throw new AnalysisException("Could not create an element for dart:core");
-    }
-    Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
-    if (asyncSource == null) {
-      throw new AnalysisException("Could not create a source for dart:async");
-    }
-    LibraryElement asyncElement = computeLibraryElement(asyncSource);
-    if (asyncElement == null) {
-      throw new AnalysisException("Could not create an element for dart:async");
-    }
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    return _typeProvider;
-  }
-
-  /**
-   * Sets the [TypeProvider] for this context.
-   */
-  void set typeProvider(TypeProvider typeProvider) {
-    _typeProvider = typeProvider;
-  }
-
-  @override
-  TypeSystem get typeSystem {
-    if (_typeSystem == null) {
-      _typeSystem = TypeSystem.create(this);
-    }
-    return _typeSystem;
-  }
-
-  @override
-  List<newContext.WorkManager> get workManagers {
-    throw new NotImplementedException('In not task-based AnalysisContext.');
-  }
-
-  @override
-  void addListener(AnalysisListener listener) {
-    if (!_listeners.contains(listener)) {
-      _listeners.add(listener);
-    }
-  }
-
-  @override
-  void applyAnalysisDelta(AnalysisDelta delta) {
-    ChangeSet changeSet = new ChangeSet();
-    delta.analysisLevels.forEach((Source source, AnalysisLevel level) {
-      if (level == AnalysisLevel.NONE) {
-        changeSet.removedSource(source);
-      } else {
-        changeSet.addedSource(source);
-      }
-    });
-    applyChanges(changeSet);
-  }
-
-  @override
-  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
-    if (changeSet.isEmpty) {
-      return new ApplyChangesStatus(false);
-    }
-    //
-    // First, compute the list of sources that have been removed.
-    //
-    List<Source> removedSources =
-        new List<Source>.from(changeSet.removedSources);
-    for (SourceContainer container in changeSet.removedContainers) {
-      _addSourcesInContainer(removedSources, container);
-    }
-    //
-    // Then determine which cached results are no longer valid.
-    //
-    for (Source source in changeSet.addedSources) {
-      _sourceAvailable(source);
-    }
-    for (Source source in changeSet.changedSources) {
-      if (_contentCache.getContents(source) != null) {
-        // This source is overridden in the content cache, so the change will
-        // have no effect. Just ignore it to avoid wasting time doing
-        // re-analysis.
-        continue;
-      }
-      _sourceChanged(source);
-    }
-    changeSet.changedContents.forEach((Source key, String value) {
-      _contentsChanged(key, value, false);
-    });
-    changeSet.changedRanges
-        .forEach((Source source, ChangeSet_ContentChange change) {
-      _contentRangeChanged(source, change.contents, change.offset,
-          change.oldLength, change.newLength);
-    });
-    for (Source source in changeSet.deletedSources) {
-      _sourceDeleted(source);
-    }
-    for (Source source in removedSources) {
-      _sourceRemoved(source);
-    }
-    _onSourcesChangedController.add(new SourcesChangedEvent(changeSet));
-    return new ApplyChangesStatus(true);
-  }
-
-  @override
-  String computeDocumentationComment(Element element) {
-    if (element == null) {
-      return null;
-    }
-    Source source = element.source;
-    if (source == null) {
-      return null;
-    }
-    SourceRange docRange = element.docRange;
-    if (docRange == null) {
-      return null;
-    }
-    String code = getContents(source).data;
-    String comment = code.substring(docRange.offset, docRange.end);
-    return comment.replaceAll('\r\n', '\n');
-  }
-
-  @override
-  List<AnalysisError> computeErrors(Source source) {
-    bool enableHints = _options.hint;
-    bool enableLints = _options.lint;
-
-    SourceEntry sourceEntry = _getReadableSourceEntry(source);
-    if (sourceEntry is DartEntry) {
-      List<AnalysisError> errors = new List<AnalysisError>();
-      try {
-        DartEntry dartEntry = sourceEntry;
-        ListUtilities.addAll(
-            errors, _getDartScanData(source, dartEntry, DartEntry.SCAN_ERRORS));
-        dartEntry = _getReadableDartEntry(source);
-        ListUtilities.addAll(errors,
-            _getDartParseData(source, dartEntry, DartEntry.PARSE_ERRORS));
-        dartEntry = _getReadableDartEntry(source);
-        if (dartEntry.getValue(DartEntry.SOURCE_KIND) == SourceKind.LIBRARY) {
-          ListUtilities.addAll(
-              errors,
-              _getDartResolutionData(
-                  source, source, dartEntry, DartEntry.RESOLUTION_ERRORS));
-          dartEntry = _getReadableDartEntry(source);
-          ListUtilities.addAll(
-              errors,
-              _getDartVerificationData(
-                  source, source, dartEntry, DartEntry.VERIFICATION_ERRORS));
-          if (enableHints) {
-            dartEntry = _getReadableDartEntry(source);
-            ListUtilities.addAll(errors,
-                _getDartHintData(source, source, dartEntry, DartEntry.HINTS));
-          }
-          if (enableLints) {
-            dartEntry = _getReadableDartEntry(source);
-            ListUtilities.addAll(errors,
-                _getDartLintData(source, source, dartEntry, DartEntry.LINTS));
-          }
-        } else {
-          List<Source> libraries = getLibrariesContaining(source);
-          for (Source librarySource in libraries) {
-            ListUtilities.addAll(
-                errors,
-                _getDartResolutionData(source, librarySource, dartEntry,
-                    DartEntry.RESOLUTION_ERRORS));
-            dartEntry = _getReadableDartEntry(source);
-            ListUtilities.addAll(
-                errors,
-                _getDartVerificationData(source, librarySource, dartEntry,
-                    DartEntry.VERIFICATION_ERRORS));
-            if (enableHints) {
-              dartEntry = _getReadableDartEntry(source);
-              ListUtilities.addAll(
-                  errors,
-                  _getDartHintData(
-                      source, librarySource, dartEntry, DartEntry.HINTS));
-            }
-            if (enableLints) {
-              dartEntry = _getReadableDartEntry(source);
-              ListUtilities.addAll(
-                  errors,
-                  _getDartLintData(
-                      source, librarySource, dartEntry, DartEntry.LINTS));
-            }
-          }
-        }
-      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logInformation(
-            "Could not compute errors",
-            new CaughtException(exception, stackTrace));
-      }
-      if (errors.isEmpty) {
-        return AnalysisError.NO_ERRORS;
-      }
-      return errors;
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      try {
-        return _getHtmlResolutionData2(
-            source, htmlEntry, HtmlEntry.RESOLUTION_ERRORS);
-      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logInformation(
-            "Could not compute errors",
-            new CaughtException(exception, stackTrace));
-      }
-    }
-    return AnalysisError.NO_ERRORS;
-  }
-
-  @override
-  List<Source> computeExportedLibraries(Source source) => _getDartParseData2(
-      source, DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_LIST);
-
-  @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) =>
-      _getHtmlResolutionData(source, HtmlEntry.ELEMENT, null);
-
-  @override
-  List<Source> computeImportedLibraries(Source source) => _getDartParseData2(
-      source, DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_LIST);
-
-  @override
-  SourceKind computeKindOf(Source source) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(source);
-    if (sourceEntry == null) {
-      return SourceKind.UNKNOWN;
-    } else if (sourceEntry is DartEntry) {
-      try {
-        return _getDartParseData(source, sourceEntry, DartEntry.SOURCE_KIND);
-      } on AnalysisException {
-        return SourceKind.UNKNOWN;
-      }
-    }
-    return sourceEntry.kind;
-  }
-
-  @override
-  LibraryElement computeLibraryElement(Source source) =>
-      _getDartResolutionData2(source, source, DartEntry.ELEMENT, null);
-
-  @override
-  LineInfo computeLineInfo(Source source) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(source);
-    try {
-      if (sourceEntry is HtmlEntry) {
-        return _getHtmlParseData(source, SourceEntry.LINE_INFO, null);
-      } else if (sourceEntry is DartEntry) {
-        return _getDartScanData2(source, SourceEntry.LINE_INFO, null);
-      }
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute ${SourceEntry.LINE_INFO}",
-          new CaughtException(exception, stackTrace));
-    }
-    return null;
-  }
-
-  @override
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      throw new AnalysisException(
-          "computeResolvableCompilationUnit for non-Dart: ${source.fullName}");
-    }
-    dartEntry = _cacheDartParseData(source, dartEntry, DartEntry.PARSED_UNIT);
-    CompilationUnit unit = dartEntry.resolvableCompilationUnit;
-    if (unit == null) {
-      throw new AnalysisException(
-          "Internal error: computeResolvableCompilationUnit could not parse ${source.fullName}",
-          new CaughtException(dartEntry.exception, null));
-    }
-    return unit;
-  }
-
-  @override
-  CancelableFuture<CompilationUnit> computeResolvedCompilationUnitAsync(
-      Source unitSource, Source librarySource) {
-    return new _AnalysisFutureHelper<CompilationUnit>(this)
-        .computeAsync(unitSource, (SourceEntry sourceEntry) {
-      if (sourceEntry is DartEntry) {
-        if (sourceEntry.getStateInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource) ==
-            CacheState.ERROR) {
-          throw sourceEntry.exception;
-        }
-        return sourceEntry.getValueInLibrary(
-            DartEntry.RESOLVED_UNIT, librarySource);
-      }
-      throw new AnalysisNotScheduledError();
-    });
-  }
-
-  @override
-  Object computeResult(AnalysisTarget target, ResultDescriptor result) {
-    return result.defaultValue;
-  }
-
-  /**
-   * Create an analysis cache based on the given source [factory].
-   */
-  AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
-    if (factory == null) {
-      return new AnalysisCache(<CachePartition>[_privatePartition]);
-    }
-    DartSdk sdk = factory.dartSdk;
-    if (sdk == null) {
-      return new AnalysisCache(<CachePartition>[_privatePartition]);
-    }
-    return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager.forSdk(sdk),
-      _privatePartition
-    ]);
-  }
-
-  @override
-  void dispose() {
-    _disposed = true;
-    for (List<PendingFuture> pendingFutures in _pendingFutureSources.values) {
-      for (PendingFuture pendingFuture in pendingFutures) {
-        pendingFuture.forciblyComplete();
-      }
-    }
-    _pendingFutureSources.clear();
-  }
-
-  @override
-  List<CompilationUnit> ensureResolvedDartUnits(Source unitSource) {
-    SourceEntry sourceEntry = _cache.get(unitSource);
-    if (sourceEntry is! DartEntry) {
-      return null;
-    }
-    DartEntry dartEntry = sourceEntry;
-    // Check every library.
-    List<CompilationUnit> units = <CompilationUnit>[];
-    List<Source> containingLibraries = dartEntry.containingLibraries;
-    for (Source librarySource in containingLibraries) {
-      CompilationUnit unit =
-          dartEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
-      if (unit == null) {
-        units = null;
-        break;
-      }
-      units.add(unit);
-    }
-    // Invalidate the flushed RESOLVED_UNIT to force it eventually.
-    if (units == null) {
-      bool shouldBeScheduled = false;
-      for (Source librarySource in containingLibraries) {
-        if (dartEntry.getStateInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource) ==
-            CacheState.FLUSHED) {
-          dartEntry.setStateInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource, CacheState.INVALID);
-          shouldBeScheduled = true;
-        }
-      }
-      if (shouldBeScheduled) {
-        _workManager.add(unitSource, SourcePriority.UNKNOWN);
-      }
-      // We cannot provide resolved units right now,
-      // but the future analysis will.
-      return null;
-    }
-    // done
-    return units;
-  }
-
-  @override
-  bool exists(Source source) {
-    if (source == null) {
-      return false;
-    }
-    if (_contentCache.getContents(source) != null) {
-      return true;
-    }
-    return source.exists();
-  }
-
-  @override
-  cache.CacheEntry getCacheEntry(AnalysisTarget target) {
-    return null;
-  }
-
-  @override
-  CompilationUnitElement getCompilationUnitElement(
-      Source unitSource, Source librarySource) {
-    LibraryElement libraryElement = getLibraryElement(librarySource);
-    if (libraryElement != null) {
-      // try defining unit
-      CompilationUnitElement definingUnit =
-          libraryElement.definingCompilationUnit;
-      if (definingUnit.source == unitSource) {
-        return definingUnit;
-      }
-      // try parts
-      for (CompilationUnitElement partUnit in libraryElement.parts) {
-        if (partUnit.source == unitSource) {
-          return partUnit;
-        }
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object getConfigurationData(ResultDescriptor key) => _configurationData[key];
-
-  @override
-  TimestampedData<String> getContents(Source source) {
-    String contents = _contentCache.getContents(source);
-    if (contents != null) {
-      return new TimestampedData<String>(
-          _contentCache.getModificationStamp(source), contents);
-    }
-    return source.contents;
-  }
-
-  @override
-  InternalAnalysisContext getContextFor(Source source) {
-    InternalAnalysisContext context = _cache.getContextFor(source);
-    return context == null ? this : context;
-  }
-
-  @override
-  Element getElement(ElementLocation location) {
-    // TODO(brianwilkerson) This should not be a "get" method.
-    try {
-      List<String> components = location.components;
-      Source source = _computeSourceFromEncoding(components[0]);
-      String sourceName = source.shortName;
-      if (AnalysisEngine.isDartFileName(sourceName)) {
-        ElementImpl element = computeLibraryElement(source) as ElementImpl;
-        for (int i = 1; i < components.length; i++) {
-          if (element == null) {
-            return null;
-          }
-          element = element.getChild(components[i]);
-        }
-        return element;
-      }
-      if (AnalysisEngine.isHtmlFileName(sourceName)) {
-        return computeHtmlElement(source);
-      }
-    } catch (exception) {
-      // If the location cannot be decoded for some reason then the underlying
-      // cause should have been logged already and we can fall though to return
-      // null.
-    }
-    return null;
-  }
-
-  @override
-  AnalysisErrorInfo getErrors(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      return new AnalysisErrorInfoImpl(
-          dartEntry.allErrors, dartEntry.getValue(SourceEntry.LINE_INFO));
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      return new AnalysisErrorInfoImpl(
-          htmlEntry.allErrors, htmlEntry.getValue(SourceEntry.LINE_INFO));
-    }
-    return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
-  }
-
-  @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is HtmlEntry) {
-      return sourceEntry.getValue(HtmlEntry.ELEMENT);
-    }
-    return null;
-  }
-
-  @override
-  List<Source> getHtmlFilesReferencing(Source source) {
-    SourceKind sourceKind = getKindOf(source);
-    if (sourceKind == null) {
-      return Source.EMPTY_LIST;
-    }
-    List<Source> htmlSources = new List<Source>();
-    while (true) {
-      if (sourceKind == SourceKind.PART) {
-        List<Source> librarySources = getLibrariesContaining(source);
-        MapIterator<Source, SourceEntry> partIterator = _cache.iterator();
-        while (partIterator.moveNext()) {
-          SourceEntry sourceEntry = partIterator.value;
-          if (sourceEntry.kind == SourceKind.HTML) {
-            List<Source> referencedLibraries = (sourceEntry as HtmlEntry)
-                .getValue(HtmlEntry.REFERENCED_LIBRARIES);
-            if (_containsAny(referencedLibraries, librarySources)) {
-              htmlSources.add(partIterator.key);
-            }
-          }
-        }
-      } else {
-        MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-        while (iterator.moveNext()) {
-          SourceEntry sourceEntry = iterator.value;
-          if (sourceEntry.kind == SourceKind.HTML) {
-            List<Source> referencedLibraries = (sourceEntry as HtmlEntry)
-                .getValue(HtmlEntry.REFERENCED_LIBRARIES);
-            if (_contains(referencedLibraries, source)) {
-              htmlSources.add(iterator.key);
-            }
-          }
-        }
-      }
-      break;
-    }
-    if (htmlSources.isEmpty) {
-      return Source.EMPTY_LIST;
-    }
-    return htmlSources;
-  }
-
-  @override
-  SourceKind getKindOf(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry == null) {
-      return SourceKind.UNKNOWN;
-    }
-    return sourceEntry.kind;
-  }
-
-  @override
-  List<Source> getLibrariesContaining(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is DartEntry) {
-      return sourceEntry.containingLibraries;
-    }
-    return Source.EMPTY_LIST;
-  }
-
-  @override
-  List<Source> getLibrariesDependingOn(Source librarySource) {
-    List<Source> dependentLibraries = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry.kind == SourceKind.LIBRARY) {
-        if (_contains(
-            (sourceEntry as DartEntry).getValue(DartEntry.EXPORTED_LIBRARIES),
-            librarySource)) {
-          dependentLibraries.add(iterator.key);
-        }
-        if (_contains(
-            (sourceEntry as DartEntry).getValue(DartEntry.IMPORTED_LIBRARIES),
-            librarySource)) {
-          dependentLibraries.add(iterator.key);
-        }
-      }
-    }
-    if (dependentLibraries.isEmpty) {
-      return Source.EMPTY_LIST;
-    }
-    return dependentLibraries;
-  }
-
-  @override
-  List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(htmlSource);
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      return htmlEntry.getValue(HtmlEntry.REFERENCED_LIBRARIES);
-    }
-    return Source.EMPTY_LIST;
-  }
-
-  @override
-  LibraryElement getLibraryElement(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry is DartEntry) {
-      return sourceEntry.getValue(DartEntry.ELEMENT);
-    }
-    return null;
-  }
-
-  @override
-  LineInfo getLineInfo(Source source) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(source);
-    if (sourceEntry != null) {
-      return sourceEntry.getValue(SourceEntry.LINE_INFO);
-    }
-    return null;
-  }
-
-  @override
-  int getModificationStamp(Source source) {
-    int stamp = _contentCache.getModificationStamp(source);
-    if (stamp != null) {
-      return stamp;
-    }
-    return source.modificationStamp;
-  }
-
-  @override
-  ChangeNoticeImpl getNotice(Source source) {
-    ChangeNoticeImpl notice = _pendingNotices[source];
-    if (notice == null) {
-      notice = new ChangeNoticeImpl(source);
-      _pendingNotices[source] = notice;
-    }
-    return notice;
-  }
-
-  @override
-  Namespace getPublicNamespace(LibraryElement library) {
-    // TODO(brianwilkerson) Rename this to not start with 'get'.
-    // Note that this is not part of the API of the interface.
-    Source source = library.definingCompilationUnit.source;
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      return null;
-    }
-    Namespace namespace = null;
-    if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
-      namespace = dartEntry.getValue(DartEntry.PUBLIC_NAMESPACE);
-    }
-    if (namespace == null) {
-      NamespaceBuilder builder = new NamespaceBuilder();
-      namespace = builder.createPublicNamespaceForLibrary(library);
-      if (dartEntry == null) {
-        AnalysisEngine.instance.logger.logError(
-            "Could not compute the public namespace for ${library.source.fullName}",
-            new CaughtException(
-                new AnalysisException(
-                    "A Dart file became a non-Dart file: ${source.fullName}"),
-                null));
-        return null;
-      }
-      if (identical(dartEntry.getValue(DartEntry.ELEMENT), library)) {
-        dartEntry.setValue(DartEntry.PUBLIC_NAMESPACE, namespace);
-      }
-    }
-    return namespace;
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], or `null` if
-   * there is no entry associated with the source.
-   */
-  SourceEntry getReadableSourceEntryOrNull(Source source) => _cache.get(source);
-
-  @override
-  CompilationUnit getResolvedCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    if (library == null) {
-      return null;
-    }
-    return getResolvedCompilationUnit2(unitSource, library.source);
-  }
-
-  @override
-  CompilationUnit getResolvedCompilationUnit2(
-      Source unitSource, Source librarySource) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(unitSource);
-    if (sourceEntry is DartEntry) {
-      return sourceEntry.getValueInLibrary(
-          DartEntry.RESOLVED_UNIT, librarySource);
-    }
-    return null;
-  }
-
-  @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    SourceEntry sourceEntry = getReadableSourceEntryOrNull(htmlSource);
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      return htmlEntry.getValue(HtmlEntry.RESOLVED_UNIT);
-    }
-    return null;
-  }
-
-  @override
-  Object getResult(AnalysisTarget target, ResultDescriptor result) {
-    return result.defaultValue;
-  }
-
-  @override
-  List<Source> getSourcesWithFullName(String path) {
-    List<Source> sources = <Source>[];
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.key.fullName == path) {
-        sources.add(iterator.key);
-      }
-    }
-    return sources;
-  }
-
-  @override
-  bool handleContentsChanged(
-      Source source, String originalContents, String newContents, bool notify) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      return false;
-    }
-    bool changed = newContents != originalContents;
-    if (newContents != null) {
-      if (changed) {
-        _incrementalAnalysisCache =
-            IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
-        if (!analysisOptions.incremental ||
-            !_tryPoorMansIncrementalResolution(source, newContents)) {
-          _sourceChanged(source);
-        }
-        sourceEntry.modificationTime =
-            _contentCache.getModificationStamp(source);
-        sourceEntry.setValue(SourceEntry.CONTENT, newContents);
-      } else {
-        sourceEntry.modificationTime =
-            _contentCache.getModificationStamp(source);
-      }
-    } else if (originalContents != null) {
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
-      // We are removing the overlay for the file, check if the file's
-      // contents is the same as it was in the overlay.
-      try {
-        TimestampedData<String> fileContents = getContents(source);
-        newContents = fileContents.data;
-        sourceEntry.modificationTime = fileContents.modificationTime;
-        if (newContents == originalContents) {
-          sourceEntry.setValue(SourceEntry.CONTENT, newContents);
-          changed = false;
-        }
-      } catch (e) {}
-      // If not the same content (e.g. the file is being closed without save),
-      // then force analysis.
-      if (changed) {
-        if (!analysisOptions.incremental ||
-            !_tryPoorMansIncrementalResolution(source, newContents)) {
-          _sourceChanged(source);
-        }
-      }
-    }
-    if (notify && changed) {
-      _onSourcesChangedController
-          .add(new SourcesChangedEvent.changedContent(source, newContents));
-    }
-    return changed;
-  }
-
-  @override
-  void invalidateLibraryHints(Source librarySource) {
-    SourceEntry sourceEntry = _cache.get(librarySource);
-    if (sourceEntry is! DartEntry) {
-      return;
-    }
-    DartEntry dartEntry = sourceEntry;
-    // Prepare sources to invalidate hints in.
-    List<Source> sources = <Source>[librarySource];
-    sources.addAll(dartEntry.getValue(DartEntry.INCLUDED_PARTS));
-    // Invalidate hints and lints.
-    for (Source source in sources) {
-      DartEntry dartEntry = _cache.get(source);
-      if (dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource) ==
-          CacheState.VALID) {
-        dartEntry.setStateInLibrary(
-            DartEntry.HINTS, librarySource, CacheState.INVALID);
-      }
-      if (dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource) ==
-          CacheState.VALID) {
-        dartEntry.setStateInLibrary(
-            DartEntry.LINTS, librarySource, CacheState.INVALID);
-      }
-    }
-  }
-
-  @override
-  bool isClientLibrary(Source librarySource) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(librarySource);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      return dartEntry.getValue(DartEntry.IS_CLIENT) &&
-          dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
-    }
-    return false;
-  }
-
-  @override
-  bool isServerLibrary(Source librarySource) {
-    SourceEntry sourceEntry = _getReadableSourceEntry(librarySource);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      return !dartEntry.getValue(DartEntry.IS_CLIENT) &&
-          dartEntry.getValue(DartEntry.IS_LAUNCHABLE);
-    }
-    return false;
-  }
-
-  @override
-  Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
-    throw new NotImplementedException('In not task-based AnalysisContext.');
-  }
-
-  @override
-  CompilationUnit parseCompilationUnit(Source source) =>
-      _getDartParseData2(source, DartEntry.PARSED_UNIT, null);
-
-  @override
-  Document parseHtmlDocument(Source source) {
-    return null;
-  }
-
-  @override
-  @deprecated
-  ht.HtmlUnit parseHtmlUnit(Source source) =>
-      _getHtmlParseData(source, HtmlEntry.PARSED_UNIT, null);
-
-  @override
-  AnalysisResult performAnalysisTask() {
-    if (_TRACE_PERFORM_TASK) {
-      print("----------------------------------------");
-    }
-    return PerformanceStatistics.performAnaysis.makeCurrentWhile(() {
-      int getStart = JavaSystem.currentTimeMillis();
-      AnalysisTask task = PerformanceStatistics.nextTask
-          .makeCurrentWhile(() => nextAnalysisTask);
-      int getEnd = JavaSystem.currentTimeMillis();
-      if (task == null) {
-        _validateLastIncrementalResolutionResult();
-        if (_performAnalysisTaskStopwatch != null) {
-          AnalysisEngine.instance.instrumentationService.logPerformance(
-              AnalysisPerformanceKind.FULL,
-              _performAnalysisTaskStopwatch,
-              'context_id=$_id');
-          _performAnalysisTaskStopwatch = null;
-        }
-        return new AnalysisResult(
-            _getChangeNotices(true), getEnd - getStart, null, -1);
-      }
-      if (_performAnalysisTaskStopwatch == null) {
-        _performAnalysisTaskStopwatch = new Stopwatch()..start();
-      }
-      String taskDescription = task.toString();
-      _notifyAboutToPerformTask(taskDescription);
-      if (_TRACE_PERFORM_TASK) {
-        print(taskDescription);
-      }
-      int performStart = JavaSystem.currentTimeMillis();
-      try {
-        task.perform(_resultRecorder);
-      } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logInformation(
-            "Could not perform analysis task: $taskDescription",
-            new CaughtException(exception, stackTrace));
-      } on AnalysisException catch (exception, stackTrace) {
-        if (exception.cause is! JavaIOException) {
-          AnalysisEngine.instance.logger.logError(
-              "Internal error while performing the task: $task",
-              new CaughtException(exception, stackTrace));
-        }
-      }
-      int performEnd = JavaSystem.currentTimeMillis();
-      List<ChangeNotice> notices = _getChangeNotices(false);
-      int noticeCount = notices.length;
-      for (int i = 0; i < noticeCount; i++) {
-        ChangeNotice notice = notices[i];
-        Source source = notice.source;
-        // TODO(brianwilkerson) Figure out whether the compilation unit is
-        // always resolved, or whether we need to decide whether to invoke the
-        // "parsed" or "resolved" method. This might be better done when
-        // recording task results in order to reduce the chance of errors.
-//        if (notice.getCompilationUnit() != null) {
-//          notifyResolvedDart(source, notice.getCompilationUnit());
-//        } else if (notice.getHtmlUnit() != null) {
-//          notifyResolvedHtml(source, notice.getHtmlUnit());
-//        }
-        _notifyErrors(source, notice.errors, notice.lineInfo);
-      }
-      return new AnalysisResult(notices, getEnd - getStart,
-          task.runtimeType.toString(), performEnd - performStart);
-    });
-  }
-
-  @override
-  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-    Source htmlSource = _sourceFactory.forUri(DartSdk.DART_HTML);
-    elementMap.forEach((Source librarySource, LibraryElement library) {
-      //
-      // Cache the element in the library's info.
-      //
-      DartEntry dartEntry = _getReadableDartEntry(librarySource);
-      if (dartEntry != null) {
-        _recordElementData(dartEntry, library, library.source, htmlSource);
-        dartEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-        dartEntry.setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
-        // DartEntry.ELEMENT - set in recordElementData
-        dartEntry.setValue(DartEntry.EXPORTED_LIBRARIES, Source.EMPTY_LIST);
-        dartEntry.setValue(DartEntry.IMPORTED_LIBRARIES, Source.EMPTY_LIST);
-        dartEntry.setValue(DartEntry.INCLUDED_PARTS, Source.EMPTY_LIST);
-        // DartEntry.IS_CLIENT - set in recordElementData
-        // DartEntry.IS_LAUNCHABLE - set in recordElementData
-        dartEntry.setValue(DartEntry.PARSE_ERRORS, AnalysisError.NO_ERRORS);
-        dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-        dartEntry.setState(DartEntry.PUBLIC_NAMESPACE, CacheState.FLUSHED);
-        dartEntry.setValue(DartEntry.SCAN_ERRORS, AnalysisError.NO_ERRORS);
-        dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-        dartEntry.setState(DartEntry.TOKEN_STREAM, CacheState.FLUSHED);
-        dartEntry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource,
-            AnalysisError.NO_ERRORS);
-        dartEntry.setStateInLibrary(
-            DartEntry.RESOLVED_UNIT, librarySource, CacheState.FLUSHED);
-        dartEntry.setValueInLibrary(DartEntry.VERIFICATION_ERRORS,
-            librarySource, AnalysisError.NO_ERRORS);
-        dartEntry.setValueInLibrary(
-            DartEntry.HINTS, librarySource, AnalysisError.NO_ERRORS);
-        dartEntry.setValueInLibrary(
-            DartEntry.LINTS, librarySource, AnalysisError.NO_ERRORS);
-      }
-    });
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry recordResolveDartLibraryCycleTaskResults(
-      ResolveDartLibraryCycleTask task) {
-    LibraryResolver2 resolver = task.libraryResolver;
-    CaughtException thrownException = task.exception;
-    Source unitSource = task.unitSource;
-    DartEntry unitEntry = _getReadableDartEntry(unitSource);
-    if (resolver != null) {
-      //
-      // The resolver should only be null if an exception was thrown before (or
-      // while) it was being created.
-      //
-      List<ResolvableLibrary> resolvedLibraries = resolver.resolvedLibraries;
-      if (resolvedLibraries == null) {
-        //
-        // The resolved libraries should only be null if an exception was thrown
-        // during resolution.
-        //
-        if (thrownException == null) {
-          var message = "In recordResolveDartLibraryCycleTaskResults, "
-              "resolvedLibraries was null and there was no thrown exception";
-          unitEntry.recordResolutionError(
-              new CaughtException(new AnalysisException(message), null));
-        } else {
-          unitEntry.recordResolutionError(thrownException);
-        }
-        _removeFromCache(unitSource);
-        if (thrownException != null) {
-          throw new AnalysisException('<rethrow>', thrownException);
-        }
-        return unitEntry;
-      }
-      Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
-      RecordingErrorListener errorListener = resolver.errorListener;
-      for (ResolvableLibrary library in resolvedLibraries) {
-        Source librarySource = library.librarySource;
-        for (Source source in library.compilationUnitSources) {
-          CompilationUnit unit = library.getAST(source);
-          List<AnalysisError> errors = errorListener.getErrorsForSource(source);
-          LineInfo lineInfo = getLineInfo(source);
-          DartEntry dartEntry = _cache.get(source);
-          if (thrownException == null) {
-            dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource, unit);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLUTION_ERRORS, librarySource, errors);
-            if (source == librarySource) {
-              _recordElementData(
-                  dartEntry, library.libraryElement, librarySource, htmlSource);
-            }
-            _cache.storedAst(source);
-          } else {
-            dartEntry.recordResolutionErrorInLibrary(
-                librarySource, thrownException);
-          }
-          if (source != librarySource) {
-            _workManager.add(source, SourcePriority.PRIORITY_PART);
-          }
-          ChangeNoticeImpl notice = getNotice(source);
-          notice.resolvedDartUnit = unit;
-          notice.setErrors(dartEntry.allErrors, lineInfo);
-        }
-      }
-    }
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return unitEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
-    LibraryResolver resolver = task.libraryResolver;
-    CaughtException thrownException = task.exception;
-    Source unitSource = task.unitSource;
-    DartEntry unitEntry = _getReadableDartEntry(unitSource);
-    if (resolver != null) {
-      //
-      // The resolver should only be null if an exception was thrown before (or
-      // while) it was being created.
-      //
-      Set<Library> resolvedLibraries = resolver.resolvedLibraries;
-      if (resolvedLibraries == null) {
-        //
-        // The resolved libraries should only be null if an exception was thrown
-        // during resolution.
-        //
-        if (thrownException == null) {
-          String message = "In recordResolveDartLibraryTaskResults, "
-              "resolvedLibraries was null and there was no thrown exception";
-          unitEntry.recordResolutionError(
-              new CaughtException(new AnalysisException(message), null));
-        } else {
-          unitEntry.recordResolutionError(thrownException);
-        }
-        _removeFromCache(unitSource);
-        if (thrownException != null) {
-          throw new AnalysisException('<rethrow>', thrownException);
-        }
-        return unitEntry;
-      }
-      Source htmlSource = sourceFactory.forUri(DartSdk.DART_HTML);
-      RecordingErrorListener errorListener = resolver.errorListener;
-      for (Library library in resolvedLibraries) {
-        Source librarySource = library.librarySource;
-        for (Source source in library.compilationUnitSources) {
-          CompilationUnit unit = library.getAST(source);
-          List<AnalysisError> errors = errorListener.getErrorsForSource(source);
-          LineInfo lineInfo = getLineInfo(source);
-          DartEntry dartEntry = _cache.get(source);
-          if (thrownException == null) {
-            dartEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
-            dartEntry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource, unit);
-            dartEntry.setValueInLibrary(
-                DartEntry.RESOLUTION_ERRORS, librarySource, errors);
-            if (source == librarySource) {
-              _recordElementData(
-                  dartEntry, library.libraryElement, librarySource, htmlSource);
-            }
-            _cache.storedAst(source);
-          } else {
-            dartEntry.recordResolutionErrorInLibrary(
-                librarySource, thrownException);
-            _removeFromCache(source);
-          }
-          if (source != librarySource) {
-            _workManager.add(source, SourcePriority.PRIORITY_PART);
-          }
-          ChangeNoticeImpl notice = getNotice(source);
-          notice.resolvedDartUnit = unit;
-          notice.setErrors(dartEntry.allErrors, lineInfo);
-        }
-      }
-    }
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return unitEntry;
-  }
-
-  @override
-  void removeListener(AnalysisListener listener) {
-    _listeners.remove(listener);
-  }
-
-  @override
-  CompilationUnit resolveCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    if (library == null) {
-      return null;
-    }
-    return resolveCompilationUnit2(unitSource, library.source);
-  }
-
-  @override
-  CompilationUnit resolveCompilationUnit2(
-          Source unitSource, Source librarySource) =>
-      _getDartResolutionData2(
-          unitSource, librarySource, DartEntry.RESOLVED_UNIT, null);
-
-  @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    computeHtmlElement(htmlSource);
-    return parseHtmlUnit(htmlSource);
-  }
-
-  @override
-  void setChangedContents(Source source, String contents, int offset,
-      int oldLength, int newLength) {
-    if (_contentRangeChanged(source, contents, offset, oldLength, newLength)) {
-      _onSourcesChangedController.add(new SourcesChangedEvent.changedRange(
-          source, contents, offset, oldLength, newLength));
-    }
-  }
-
-  @override
-  void setConfigurationData(ResultDescriptor key, Object data) {
-    _configurationData[key] = data;
-  }
-
-  @override
-  void setContents(Source source, String contents) {
-    _contentsChanged(source, contents, true);
-  }
-
-  @override
-  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
-    DartEntry dartEntry = entry;
-    if (source.isInSystemLibrary) {
-      return _generateSdkErrors;
-    } else if (!dartEntry.explicitlyAdded) {
-      return _generateImplicitErrors;
-    } else {
-      return true;
-    }
-  }
-
-  @override
-  void test_flushAstStructures(Source source) {
-    DartEntry dartEntry = getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-  }
-
-  @override
-  bool validateCacheConsistency() {
-    int consistencyCheckStart = JavaSystem.nanoTime();
-    List<Source> changedSources = new List<Source>();
-    List<Source> missingSources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      int sourceTime = getModificationStamp(source);
-      if (sourceTime != sourceEntry.modificationTime) {
-        changedSources.add(source);
-      }
-      if (sourceEntry.exception != null) {
-        if (!exists(source)) {
-          missingSources.add(source);
-        }
-      }
-    }
-    int count = changedSources.length;
-    for (int i = 0; i < count; i++) {
-      _sourceChanged(changedSources[i]);
-    }
-    int removalCount = 0;
-    for (Source source in missingSources) {
-      if (getLibrariesContaining(source).isEmpty &&
-          getLibrariesDependingOn(source).isEmpty) {
-        _removeFromCache(source);
-        removalCount++;
-      }
-    }
-    int consistencyCheckEnd = JavaSystem.nanoTime();
-    if (changedSources.length > 0 || missingSources.length > 0) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("Consistency check took ");
-      buffer.write((consistencyCheckEnd - consistencyCheckStart) / 1000000.0);
-      buffer.writeln(" ms and found");
-      buffer.write("  ");
-      buffer.write(changedSources.length);
-      buffer.writeln(" inconsistent entries");
-      buffer.write("  ");
-      buffer.write(missingSources.length);
-      buffer.write(" missing sources (");
-      buffer.write(removalCount);
-      buffer.writeln(" removed");
-      for (Source source in missingSources) {
-        buffer.write("    ");
-        buffer.writeln(source.fullName);
-      }
-      _logInformation(buffer.toString());
-    }
-    return changedSources.length > 0;
-  }
-
-  @deprecated
-  @override
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state)) {
-    bool hintsEnabled = _options.hint;
-    bool lintsEnabled = _options.lint;
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      for (DataDescriptor descriptor in sourceEntry.descriptors) {
-        if (descriptor == DartEntry.SOURCE_KIND) {
-          // The source kind is always valid, so the state isn't interesting.
-          continue;
-        } else if (descriptor == DartEntry.CONTAINING_LIBRARIES) {
-          // The list of containing libraries is always valid, so the state
-          // isn't interesting.
-          continue;
-        } else if (descriptor == DartEntry.PUBLIC_NAMESPACE) {
-          // The public namespace isn't computed by performAnalysisTask()
-          // and therefore isn't interesting.
-          continue;
-        } else if (descriptor == HtmlEntry.HINTS) {
-          // We are not currently recording any hints related to HTML.
-          continue;
-        }
-        callback(
-            source, sourceEntry, descriptor, sourceEntry.getState(descriptor));
-      }
-      if (sourceEntry is DartEntry) {
-        // get library-specific values
-        List<Source> librarySources = getLibrariesContaining(source);
-        for (Source librarySource in librarySources) {
-          for (DataDescriptor descriptor in sourceEntry.libraryDescriptors) {
-            if (descriptor == DartEntry.BUILT_ELEMENT ||
-                descriptor == DartEntry.BUILT_UNIT) {
-              // These values are not currently being computed, so their state
-              // is not interesting.
-              continue;
-            } else if (!sourceEntry.explicitlyAdded &&
-                !_generateImplicitErrors &&
-                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-                    descriptor == DartEntry.HINTS ||
-                    descriptor == DartEntry.LINTS)) {
-              continue;
-            } else if (source.isInSystemLibrary &&
-                !_generateSdkErrors &&
-                (descriptor == DartEntry.VERIFICATION_ERRORS ||
-                    descriptor == DartEntry.HINTS ||
-                    descriptor == DartEntry.LINTS)) {
-              continue;
-            } else if (!hintsEnabled && descriptor == DartEntry.HINTS) {
-              continue;
-            } else if (!lintsEnabled && descriptor == DartEntry.LINTS) {
-              continue;
-            }
-            callback(librarySource, sourceEntry, descriptor,
-                sourceEntry.getStateInLibrary(descriptor, librarySource));
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  void visitContentCache(ContentCacheVisitor visitor) {
-    _contentCache.accept(visitor);
-  }
-
-  /**
-   * Record that we have accessed the AST structure associated with the given
-   * [source]. At the moment, there is no differentiation between the parsed and
-   * resolved forms of the AST.
-   */
-  void _accessedAst(Source source) {
-    _cache.accessedAst(source);
-  }
-
-  /**
-   * Add all of the sources contained in the given source [container] to the
-   * given list of [sources].
-   */
-  void _addSourcesInContainer(List<Source> sources, SourceContainer container) {
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      if (container.contains(source)) {
-        sources.add(source);
-      }
-    }
-  }
-
-  /**
-   * Given the [unitSource] of a Dart file and the [librarySource] of the
-   * library that contains it, return a cache entry in which the state of the
-   * data represented by the given [descriptor] is either [CacheState.VALID] or
-   * [CacheState.ERROR]. This method assumes that the data can be produced by
-   * generating hints for the library if the data is not already cached. The
-   * [dartEntry] is the cache entry associated with the Dart file.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   */
-  DartEntry _cacheDartHintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information.
-      // Unless the modification date of the source continues to change,
-      // this loop will eventually terminate.
-      //
-      DartEntry libraryEntry = _getReadableDartEntry(librarySource);
-      libraryEntry = _cacheDartResolutionData(
-          librarySource, librarySource, libraryEntry, DartEntry.ELEMENT);
-      LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-      CompilationUnitElement definingUnit =
-          libraryElement.definingCompilationUnit;
-      List<CompilationUnitElement> parts = libraryElement.parts;
-      List<TimestampedData<CompilationUnit>> units =
-          new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-      units[0] = _getResolvedUnit(definingUnit, librarySource);
-      if (units[0] == null) {
-        Source source = definingUnit.source;
-        units[0] = new TimestampedData<CompilationUnit>(
-            getModificationStamp(source),
-            resolveCompilationUnit(source, libraryElement));
-      }
-      for (int i = 0; i < parts.length; i++) {
-        units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-        if (units[i + 1] == null) {
-          Source source = parts[i].source;
-          units[i + 1] = new TimestampedData<CompilationUnit>(
-              getModificationStamp(source),
-              resolveCompilationUnit(source, libraryElement));
-        }
-      }
-      dartEntry = new GenerateDartHintsTask(
-              this, units, getLibraryElement(librarySource))
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return a
-   * cache entry in which the state of the data represented by the given
-   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
-   * assumes that the data can be produced by generating lints for the library
-   * if the data is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartLintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information.
-      // Unless the modification date of the source continues to change,
-      // this loop will eventually terminate.
-      //
-      DartEntry libraryEntry = _getReadableDartEntry(librarySource);
-      libraryEntry = _cacheDartResolutionData(
-          librarySource, librarySource, libraryEntry, DartEntry.ELEMENT);
-      LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-      CompilationUnitElement definingUnit =
-          libraryElement.definingCompilationUnit;
-      List<CompilationUnitElement> parts = libraryElement.parts;
-      List<TimestampedData<CompilationUnit>> units =
-          new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-      units[0] = _getResolvedUnit(definingUnit, librarySource);
-      if (units[0] == null) {
-        Source source = definingUnit.source;
-        units[0] = new TimestampedData<CompilationUnit>(
-            getModificationStamp(source),
-            resolveCompilationUnit(source, libraryElement));
-      }
-      for (int i = 0; i < parts.length; i++) {
-        units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-        if (units[i + 1] == null) {
-          Source source = parts[i].source;
-          units[i + 1] = new TimestampedData<CompilationUnit>(
-              getModificationStamp(source),
-              resolveCompilationUnit(source, libraryElement));
-        }
-      }
-      //TODO(pquitslund): revisit if we need all units or whether one will do
-      dartEntry = new GenerateDartLintsTask(
-              this, units, getLibraryElement(librarySource))
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file, return a cache entry in which the state of
-   * the data represented by the given descriptor is either [CacheState.VALID]
-   * or [CacheState.ERROR]. This method assumes that the data can be produced by
-   * parsing the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartParseData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    if (identical(descriptor, DartEntry.PARSED_UNIT)) {
-      if (dartEntry.hasResolvableCompilationUnit) {
-        return dartEntry;
-      }
-    }
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      dartEntry = _cacheDartScanData(source, dartEntry, DartEntry.TOKEN_STREAM);
-      dartEntry = new ParseDartTask(
-              this,
-              source,
-              dartEntry.getValue(DartEntry.TOKEN_STREAM),
-              dartEntry.getValue(SourceEntry.LINE_INFO))
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getState(descriptor);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return a
-   * cache entry in which the state of the data represented by the given
-   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
-   * assumes that the data can be produced by resolving the source in the
-   * context of the library if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartResolutionData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = (identical(descriptor, DartEntry.ELEMENT))
-        ? dartEntry.getState(descriptor)
-        : dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      // TODO(brianwilkerson) As an optimization, if we already have the
-      // element model for the library we can use ResolveDartUnitTask to produce
-      // the resolved AST structure much faster.
-      dartEntry = new ResolveDartLibraryTask(this, unitSource, librarySource)
-          .perform(_resultRecorder) as DartEntry;
-      state = (identical(descriptor, DartEntry.ELEMENT))
-          ? dartEntry.getState(descriptor)
-          : dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file, return a cache entry in which the state of
-   * the data represented by the given descriptor is either [CacheState.VALID]
-   * or [CacheState.ERROR]. This method assumes that the data can be produced by
-   * scanning the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartScanData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      try {
-        if (dartEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-          dartEntry = new GetContentTask(this, source).perform(_resultRecorder)
-              as DartEntry;
-        }
-        dartEntry = new ScanDartTask(
-                this, source, dartEntry.getValue(SourceEntry.CONTENT))
-            .perform(_resultRecorder) as DartEntry;
-      } on AnalysisException catch (exception) {
-        throw exception;
-      } catch (exception, stackTrace) {
-        throw new AnalysisException(
-            "Exception", new CaughtException(exception, stackTrace));
-      }
-      state = dartEntry.getState(descriptor);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return a
-   * cache entry in which the state of the data represented by the given
-   * descriptor is either [CacheState.VALID] or [CacheState.ERROR]. This method
-   * assumes that the data can be produced by verifying the source in the given
-   * library if the data is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  DartEntry _cacheDartVerificationData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      LibraryElement library = computeLibraryElement(librarySource);
-      CompilationUnit unit = resolveCompilationUnit(unitSource, library);
-      if (unit == null) {
-        throw new AnalysisException(
-            "Could not resolve compilation unit ${unitSource.fullName} in ${librarySource.fullName}");
-      }
-      dartEntry = new GenerateDartErrorsTask(this, unitSource, unit, library)
-          .perform(_resultRecorder) as DartEntry;
-      state = dartEntry.getStateInLibrary(descriptor, librarySource);
-    }
-    return dartEntry;
-  }
-
-  /**
-   * Given a source for an HTML file, return a cache entry in which all of the
-   * data represented by the state of the given descriptors is either
-   * [CacheState.VALID] or [CacheState.ERROR]. This method assumes that the data
-   * can be produced by parsing the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  HtmlEntry _cacheHtmlParseData(
-      Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
-    if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
-      ht.HtmlUnit unit = htmlEntry.anyParsedUnit;
-      if (unit != null) {
-        return htmlEntry;
-      }
-    }
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = htmlEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      try {
-        if (htmlEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-          htmlEntry = new GetContentTask(this, source).perform(_resultRecorder)
-              as HtmlEntry;
-        }
-        htmlEntry = new ParseHtmlTask(
-                this, source, htmlEntry.getValue(SourceEntry.CONTENT))
-            .perform(_resultRecorder) as HtmlEntry;
-      } on AnalysisException catch (exception) {
-        throw exception;
-      } catch (exception, stackTrace) {
-        throw new AnalysisException(
-            "Exception", new CaughtException(exception, stackTrace));
-      }
-      state = htmlEntry.getState(descriptor);
-    }
-    return htmlEntry;
-  }
-
-  /**
-   * Given a source for an HTML file, return a cache entry in which the state of
-   * the data represented by the given descriptor is either [CacheState.VALID]
-   * or [CacheState.ERROR]. This method assumes that the data can be produced by
-   * resolving the source if it is not already cached.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  HtmlEntry _cacheHtmlResolutionData(
-      Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
-    //
-    // Check to see whether we already have the information being requested.
-    //
-    CacheState state = htmlEntry.getState(descriptor);
-    while (state != CacheState.ERROR && state != CacheState.VALID) {
-      //
-      // If not, compute the information. Unless the modification date of the
-      // source continues to change, this loop will eventually terminate.
-      //
-      htmlEntry = _cacheHtmlParseData(source, htmlEntry, HtmlEntry.PARSED_UNIT);
-      htmlEntry = new ResolveHtmlTask(this, source, htmlEntry.modificationTime,
-              htmlEntry.getValue(HtmlEntry.PARSED_UNIT))
-          .perform(_resultRecorder) as HtmlEntry;
-      state = htmlEntry.getState(descriptor);
-    }
-    return htmlEntry;
-  }
-
-  /**
-   * Remove the given [pendingFuture] from [_pendingFutureSources], since the
-   * client has indicated its computation is not needed anymore.
-   */
-  void _cancelFuture(PendingFuture pendingFuture) {
-    List<PendingFuture> pendingFutures =
-        _pendingFutureSources[pendingFuture.source];
-    if (pendingFutures != null) {
-      pendingFutures.remove(pendingFuture);
-      if (pendingFutures.isEmpty) {
-        _pendingFutureSources.remove(pendingFuture.source);
-      }
-    }
-  }
-
-  /**
-   * Compute the transitive closure of all libraries that depend on the given
-   * [library] by adding such libraries to the given collection of
-   * [librariesToInvalidate].
-   */
-  void _computeAllLibrariesDependingOn(
-      Source library, HashSet<Source> librariesToInvalidate) {
-    if (librariesToInvalidate.add(library)) {
-      for (Source dependentLibrary in getLibrariesDependingOn(library)) {
-        _computeAllLibrariesDependingOn(
-            dependentLibrary, librariesToInvalidate);
-      }
-    }
-  }
-
-  /**
-   * Return the priority that should be used when the source associated with
-   * the given [dartEntry] is added to the work manager.
-   */
-  SourcePriority _computePriority(DartEntry dartEntry) {
-    SourceKind kind = dartEntry.kind;
-    if (kind == SourceKind.LIBRARY) {
-      return SourcePriority.LIBRARY;
-    } else if (kind == SourceKind.PART) {
-      return SourcePriority.NORMAL_PART;
-    }
-    return SourcePriority.UNKNOWN;
-  }
-
-  /**
-   * Given the encoded form of a source ([encoding]), use the source factory to
-   * reconstitute the original source.
-   */
-  Source _computeSourceFromEncoding(String encoding) =>
-      _sourceFactory.fromEncoding(encoding);
-
-  /**
-   * Return `true` if the given list of [sources] contains the given
-   * [targetSource].
-   */
-  bool _contains(List<Source> sources, Source targetSource) {
-    for (Source source in sources) {
-      if (source == targetSource) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Return `true` if the given list of [sources] contains any of the given
-   * [targetSources].
-   */
-  bool _containsAny(List<Source> sources, List<Source> targetSources) {
-    for (Source targetSource in targetSources) {
-      if (_contains(sources, targetSource)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Set the contents of the given [source] to the given [contents] and mark the
-   * source as having changed. The additional [offset], [oldLength] and
-   * [newLength] information is used by the context to determine what reanalysis
-   * is necessary. The method [setChangedContents] triggers a source changed
-   * event where as this method does not.
-   */
-  bool _contentRangeChanged(Source source, String contents, int offset,
-      int oldLength, int newLength) {
-    bool changed = false;
-    String originalContents = _contentCache.setContents(source, contents);
-    if (contents != null) {
-      if (contents != originalContents) {
-        if (_options.incremental) {
-          _incrementalAnalysisCache = IncrementalAnalysisCache.update(
-              _incrementalAnalysisCache,
-              source,
-              originalContents,
-              contents,
-              offset,
-              oldLength,
-              newLength,
-              _getReadableSourceEntry(source));
-        }
-        _sourceChanged(source);
-        changed = true;
-        SourceEntry sourceEntry = _cache.get(source);
-        if (sourceEntry != null) {
-          sourceEntry.modificationTime =
-              _contentCache.getModificationStamp(source);
-          sourceEntry.setValue(SourceEntry.CONTENT, contents);
-        }
-      }
-    } else if (originalContents != null) {
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.clear(_incrementalAnalysisCache, source);
-      _sourceChanged(source);
-      changed = true;
-    }
-    return changed;
-  }
-
-  /**
-   * Set the contents of the given [source] to the given [contents] and mark the
-   * source as having changed. This has the effect of overriding the default
-   * contents of the source. If the contents are `null` the override is removed
-   * so that the default contents will be returned. If [notify] is true, a
-   * source changed event is triggered.
-   */
-  void _contentsChanged(Source source, String contents, bool notify) {
-    String originalContents = _contentCache.setContents(source, contents);
-    handleContentsChanged(source, originalContents, contents, notify);
-  }
-
-  /**
-   * Create a [GenerateDartErrorsTask] for the given [unitSource], marking the
-   * verification errors as being in-process. The compilation unit and the
-   * library can be the same if the compilation unit is the defining compilation
-   * unit of the library.
-   */
-  AnalysisContextImpl_TaskData _createGenerateDartErrorsTask(Source unitSource,
-      DartEntry unitEntry, Source librarySource, DartEntry libraryEntry) {
-    if (unitEntry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource) !=
-            CacheState.VALID ||
-        libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    CompilationUnit unit =
-        unitEntry.getValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource);
-    if (unit == null) {
-      CaughtException exception = new CaughtException(
-          new AnalysisException(
-              "Entry has VALID state for RESOLVED_UNIT but null value for ${unitSource.fullName} in ${librarySource.fullName}"),
-          null);
-      AnalysisEngine.instance.logger
-          .logInformation(exception.toString(), exception);
-      unitEntry.recordResolutionError(exception);
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-    return new AnalysisContextImpl_TaskData(
-        new GenerateDartErrorsTask(this, unitSource, unit, libraryElement),
-        false);
-  }
-
-  /**
-   * Create a [GenerateDartHintsTask] for the given [source], marking the hints
-   * as being in-process.
-   */
-  AnalysisContextImpl_TaskData _createGenerateDartHintsTask(Source source,
-      DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
-    if (libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-    CompilationUnitElement definingUnit =
-        libraryElement.definingCompilationUnit;
-    List<CompilationUnitElement> parts = libraryElement.parts;
-    List<TimestampedData<CompilationUnit>> units =
-        new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-    units[0] = _getResolvedUnit(definingUnit, librarySource);
-    if (units[0] == null) {
-      // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-      // (unless there are multiple ASTs that need to be resolved).
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    for (int i = 0; i < parts.length; i++) {
-      units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-      if (units[i + 1] == null) {
-        // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-        // (unless there are multiple ASTs that need to be resolved).
-        return _createResolveDartLibraryTask(librarySource, libraryEntry);
-      }
-    }
-    return new AnalysisContextImpl_TaskData(
-        new GenerateDartHintsTask(this, units, libraryElement), false);
-  }
-
-  /**
-   * Create a [GenerateDartLintsTask] for the given [source], marking the lints
-   * as being in-process.
-   */
-  AnalysisContextImpl_TaskData _createGenerateDartLintsTask(Source source,
-      DartEntry dartEntry, Source librarySource, DartEntry libraryEntry) {
-    if (libraryEntry.getState(DartEntry.ELEMENT) != CacheState.VALID) {
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-    CompilationUnitElement definingUnit =
-        libraryElement.definingCompilationUnit;
-    List<CompilationUnitElement> parts = libraryElement.parts;
-    List<TimestampedData<CompilationUnit>> units =
-        new List<TimestampedData<CompilationUnit>>(parts.length + 1);
-    units[0] = _getResolvedUnit(definingUnit, librarySource);
-    if (units[0] == null) {
-      // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-      // (unless there are multiple ASTs that need to be resolved).
-      return _createResolveDartLibraryTask(librarySource, libraryEntry);
-    }
-    for (int i = 0; i < parts.length; i++) {
-      units[i + 1] = _getResolvedUnit(parts[i], librarySource);
-      if (units[i + 1] == null) {
-        // TODO(brianwilkerson) We should return a ResolveDartUnitTask
-        // (unless there are multiple ASTs that need to be resolved).
-        return _createResolveDartLibraryTask(librarySource, libraryEntry);
-      }
-    }
-    //TODO(pquitslund): revisit if we need all units or whether one will do
-    return new AnalysisContextImpl_TaskData(
-        new GenerateDartLintsTask(this, units, libraryElement), false);
-  }
-
-  /**
-   * Create a [GetContentTask] for the given [source], marking the content as
-   * being in-process.
-   */
-  AnalysisContextImpl_TaskData _createGetContentTask(
-      Source source, SourceEntry sourceEntry) {
-    return new AnalysisContextImpl_TaskData(
-        new GetContentTask(this, source), false);
-  }
-
-  /**
-   * Create a [ParseDartTask] for the given [source].
-   */
-  AnalysisContextImpl_TaskData _createParseDartTask(
-      Source source, DartEntry dartEntry) {
-    if (dartEntry.getState(DartEntry.TOKEN_STREAM) != CacheState.VALID ||
-        dartEntry.getState(SourceEntry.LINE_INFO) != CacheState.VALID) {
-      return _createScanDartTask(source, dartEntry);
-    }
-    Token tokenStream = dartEntry.getValue(DartEntry.TOKEN_STREAM);
-    dartEntry.setState(DartEntry.TOKEN_STREAM, CacheState.FLUSHED);
-    return new AnalysisContextImpl_TaskData(
-        new ParseDartTask(this, source, tokenStream,
-            dartEntry.getValue(SourceEntry.LINE_INFO)),
-        false);
-  }
-
-  /**
-   * Create a [ParseHtmlTask] for the given [source].
-   */
-  AnalysisContextImpl_TaskData _createParseHtmlTask(
-      Source source, HtmlEntry htmlEntry) {
-    if (htmlEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-      return _createGetContentTask(source, htmlEntry);
-    }
-    String content = htmlEntry.getValue(SourceEntry.CONTENT);
-    htmlEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-    return new AnalysisContextImpl_TaskData(
-        new ParseHtmlTask(this, source, content), false);
-  }
-
-  /**
-   * Create a [ResolveDartLibraryTask] for the given [source], marking ? as
-   * being in-process.
-   */
-  AnalysisContextImpl_TaskData _createResolveDartLibraryTask(
-      Source source, DartEntry dartEntry) {
-    try {
-      AnalysisContextImpl_CycleBuilder builder =
-          new AnalysisContextImpl_CycleBuilder(this);
-      PerformanceStatistics.cycles.makeCurrentWhile(() {
-        builder.computeCycleContaining(source);
-      });
-      AnalysisContextImpl_TaskData taskData = builder.taskData;
-      if (taskData != null) {
-        return taskData;
-      }
-      return new AnalysisContextImpl_TaskData(
-          new ResolveDartLibraryCycleTask(
-              this, source, source, builder.librariesInCycle),
-          false);
-    } on AnalysisException catch (exception, stackTrace) {
-      dartEntry
-          .recordResolutionError(new CaughtException(exception, stackTrace));
-      AnalysisEngine.instance.logger.logError(
-          "Internal error trying to create a ResolveDartLibraryTask",
-          new CaughtException(exception, stackTrace));
-    }
-    return new AnalysisContextImpl_TaskData(null, false);
-  }
-
-  /**
-   * Create a [ResolveHtmlTask] for the given [source], marking the resolved
-   * unit as being in-process.
-   */
-  AnalysisContextImpl_TaskData _createResolveHtmlTask(
-      Source source, HtmlEntry htmlEntry) {
-    if (htmlEntry.getState(HtmlEntry.PARSED_UNIT) != CacheState.VALID) {
-      return _createParseHtmlTask(source, htmlEntry);
-    }
-    return new AnalysisContextImpl_TaskData(
-        new ResolveHtmlTask(this, source, htmlEntry.modificationTime,
-            htmlEntry.getValue(HtmlEntry.PARSED_UNIT)),
-        false);
-  }
-
-  /**
-   * Create a [ScanDartTask] for the given [source], marking the scan errors as
-   * being in-process.
-   */
-  AnalysisContextImpl_TaskData _createScanDartTask(
-      Source source, DartEntry dartEntry) {
-    if (dartEntry.getState(SourceEntry.CONTENT) != CacheState.VALID) {
-      return _createGetContentTask(source, dartEntry);
-    }
-    String content = dartEntry.getValue(SourceEntry.CONTENT);
-    dartEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-    return new AnalysisContextImpl_TaskData(
-        new ScanDartTask(this, source, content), false);
-  }
-
-  /**
-   * Create a source entry for the given [source]. Return the source entry that
-   * was created, or `null` if the source should not be tracked by this context.
-   */
-  SourceEntry _createSourceEntry(Source source, bool explicitlyAdded) {
-    String name = source.shortName;
-    if (AnalysisEngine.isHtmlFileName(name)) {
-      HtmlEntry htmlEntry = new HtmlEntry();
-      htmlEntry.modificationTime = getModificationStamp(source);
-      htmlEntry.explicitlyAdded = explicitlyAdded;
-      _cache.put(source, htmlEntry);
-      if (!explicitlyAdded) {
-        _implicitAnalysisEventsController
-            .add(new ImplicitAnalysisEvent(source, true));
-      }
-      return htmlEntry;
-    } else {
-      DartEntry dartEntry = new DartEntry();
-      dartEntry.modificationTime = getModificationStamp(source);
-      dartEntry.explicitlyAdded = explicitlyAdded;
-      _cache.put(source, dartEntry);
-      if (!explicitlyAdded) {
-        _implicitAnalysisEventsController
-            .add(new ImplicitAnalysisEvent(source, true));
-      }
-      return dartEntry;
-    }
-  }
-
-  /**
-   * Return a list containing all of the change notices that are waiting to be
-   * returned. If there are no notices, then return either `null` or an empty
-   * list, depending on the value of [nullIfEmpty].
-   */
-  List<ChangeNotice> _getChangeNotices(bool nullIfEmpty) {
-    if (_pendingNotices.isEmpty) {
-      if (nullIfEmpty) {
-        return null;
-      }
-      return ChangeNoticeImpl.EMPTY_LIST;
-    }
-    List<ChangeNotice> notices = new List.from(_pendingNotices.values);
-    _pendingNotices.clear();
-    return notices;
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by generating
-   * hints for the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartHintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry =
-        _cacheDartHintData(unitSource, librarySource, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.ELEMENT)) {
-      return dartEntry.getValue(descriptor);
-    }
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by generating
-   * lints for the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartLintData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry =
-        _cacheDartLintData(unitSource, librarySource, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.ELEMENT)) {
-      return dartEntry.getValue(descriptor);
-    }
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source. This method assumes that
-   * the data can be produced by parsing the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartParseData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartParseData(source, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.PARSED_UNIT)) {
-      _accessedAst(source);
-      return dartEntry.anyParsedCompilationUnit;
-    }
-    return dartEntry.getValue(descriptor);
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not a Dart file. This method assumes that the data can be
-   * produced by parsing the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartParseData2(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getDartParseData(source, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by resolving the
-   * source in the context of the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartResolutionData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartResolutionData(
-        unitSource, librarySource, dartEntry, descriptor);
-    if (identical(descriptor, DartEntry.ELEMENT)) {
-      return dartEntry.getValue(descriptor);
-    } else if (identical(descriptor, DartEntry.RESOLVED_UNIT)) {
-      _accessedAst(unitSource);
-    }
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source, or the given default value if the source is not a Dart file. This
-   * method assumes that the data can be produced by resolving the source in the
-   * context of the library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartResolutionData2(Source unitSource, Source librarySource,
-      DataDescriptor descriptor, Object defaultValue) {
-    DartEntry dartEntry = _getReadableDartEntry(unitSource);
-    if (dartEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getDartResolutionData(
-          unitSource, librarySource, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source. This method assumes that
-   * the data can be produced by scanning the source if it is not already
-   * cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be scanned.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartScanData(
-      Source source, DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartScanData(source, dartEntry, descriptor);
-    return dartEntry.getValue(descriptor);
-  }
-
-  /**
-   * Given a source for a Dart file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not a Dart file. This method assumes that the data can be
-   * produced by scanning the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be scanned.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartScanData2(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    DartEntry dartEntry = _getReadableDartEntry(source);
-    if (dartEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getDartScanData(source, dartEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for a Dart file and the library that contains it, return the
-   * data represented by the given descriptor that is associated with that
-   * source. This method assumes that the data can be produced by verifying the
-   * source within the given library if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getDartVerificationData(Source unitSource, Source librarySource,
-      DartEntry dartEntry, DataDescriptor descriptor) {
-    dartEntry = _cacheDartVerificationData(
-        unitSource, librarySource, dartEntry, descriptor);
-    return dartEntry.getValueInLibrary(descriptor, librarySource);
-  }
-
-  /**
-   * Given a source for an HTML file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not an HTML file. This method assumes that the data can be
-   * produced by parsing the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be parsed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getHtmlParseData(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    HtmlEntry htmlEntry = _getReadableHtmlEntry(source);
-    if (htmlEntry == null) {
-      return defaultValue;
-    }
-    htmlEntry = _cacheHtmlParseData(source, htmlEntry, descriptor);
-    if (identical(descriptor, HtmlEntry.PARSED_UNIT)) {
-      _accessedAst(source);
-      return htmlEntry.anyParsedUnit;
-    }
-    return htmlEntry.getValue(descriptor);
-  }
-
-  /**
-   * Given a source for an HTML file, return the data represented by the given
-   * descriptor that is associated with that source, or the given default value
-   * if the source is not an HTML file. This method assumes that the data can be
-   * produced by resolving the source if it is not already cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getHtmlResolutionData(
-      Source source, DataDescriptor descriptor, Object defaultValue) {
-    HtmlEntry htmlEntry = _getReadableHtmlEntry(source);
-    if (htmlEntry == null) {
-      return defaultValue;
-    }
-    try {
-      return _getHtmlResolutionData2(source, htmlEntry, descriptor);
-    } on ObsoleteSourceAnalysisException catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not compute $descriptor",
-          new CaughtException(exception, stackTrace));
-      return defaultValue;
-    }
-  }
-
-  /**
-   * Given a source for an HTML file, return the data represented by the given
-   * descriptor that is associated with that source. This method assumes that
-   * the data can be produced by resolving the source if it is not already
-   * cached.
-   *
-   * Throws an [AnalysisException] if data could not be returned because the
-   * source could not be resolved.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment.
-   */
-  Object _getHtmlResolutionData2(
-      Source source, HtmlEntry htmlEntry, DataDescriptor descriptor) {
-    htmlEntry = _cacheHtmlResolutionData(source, htmlEntry, descriptor);
-    if (identical(descriptor, HtmlEntry.RESOLVED_UNIT)) {
-      _accessedAst(source);
-    }
-    return htmlEntry.getValue(descriptor);
-  }
-
-  /**
-   * Look at the given [source] to see whether a task needs to be performed
-   * related to it. Return the task that should be performed, or `null` if there
-   * is no more work to be done for the source.
-   */
-  AnalysisContextImpl_TaskData _getNextAnalysisTaskForSource(
-      Source source,
-      SourceEntry sourceEntry,
-      bool isPriority,
-      bool hintsEnabled,
-      bool lintsEnabled) {
-    // Refuse to generate tasks for html based files that are above 1500 KB
-    if (_isTooBigHtmlSourceEntry(source, sourceEntry)) {
-      // TODO (jwren) we still need to report an error of some kind back to the
-      // client.
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    if (sourceEntry == null) {
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    CacheState contentState = sourceEntry.getState(SourceEntry.CONTENT);
-    if (contentState == CacheState.INVALID) {
-      return _createGetContentTask(source, sourceEntry);
-    } else if (contentState == CacheState.IN_PROCESS) {
-      // We are already in the process of getting the content.
-      // There's nothing else we can do with this source until that's complete.
-      return new AnalysisContextImpl_TaskData(null, true);
-    } else if (contentState == CacheState.ERROR) {
-      // We have done all of the analysis we can for this source because we
-      // cannot get its content.
-      return new AnalysisContextImpl_TaskData(null, false);
-    }
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
-      if (scanErrorsState == CacheState.INVALID ||
-          (isPriority && scanErrorsState == CacheState.FLUSHED)) {
-        return _createScanDartTask(source, dartEntry);
-      }
-      CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
-      if (parseErrorsState == CacheState.INVALID ||
-          (isPriority && parseErrorsState == CacheState.FLUSHED)) {
-        return _createParseDartTask(source, dartEntry);
-      }
-      if (isPriority && parseErrorsState != CacheState.ERROR) {
-        if (!dartEntry.hasResolvableCompilationUnit) {
-          return _createParseDartTask(source, dartEntry);
-        }
-      }
-      SourceKind kind = dartEntry.getValue(DartEntry.SOURCE_KIND);
-      if (kind == SourceKind.UNKNOWN) {
-        return _createParseDartTask(source, dartEntry);
-      } else if (kind == SourceKind.LIBRARY) {
-        CacheState elementState = dartEntry.getState(DartEntry.ELEMENT);
-        if (elementState == CacheState.INVALID) {
-          return _createResolveDartLibraryTask(source, dartEntry);
-        }
-      }
-      List<Source> librariesContaining = dartEntry.containingLibraries;
-      for (Source librarySource in librariesContaining) {
-        SourceEntry librarySourceEntry = _cache.get(librarySource);
-        if (librarySourceEntry is DartEntry) {
-          DartEntry libraryEntry = librarySourceEntry;
-          CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
-          if (elementState == CacheState.INVALID ||
-              (isPriority && elementState == CacheState.FLUSHED)) {
-//            return createResolveDartLibraryTask(librarySource, (DartEntry) libraryEntry);
-            return new AnalysisContextImpl_TaskData(
-                new ResolveDartLibraryTask(this, source, librarySource), false);
-          }
-          CacheState resolvedUnitState = dartEntry.getStateInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource);
-          if (resolvedUnitState == CacheState.INVALID ||
-              (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-            //
-            // The commented out lines below are an optimization that doesn't
-            // quite work yet. The problem is that if the source was not
-            // resolved because it wasn't part of any library, then there won't
-            // be any elements in the element model that we can use to resolve
-            // it.
-            //
-//            LibraryElement libraryElement = libraryEntry.getValue(DartEntry.ELEMENT);
-//            if (libraryElement != null) {
-//              return new ResolveDartUnitTask(this, source, libraryElement);
-//            }
-            // Possibly replace with:
-//             return createResolveDartLibraryTask(librarySource, (DartEntry) libraryEntry);
-            return new AnalysisContextImpl_TaskData(
-                new ResolveDartLibraryTask(this, source, librarySource), false);
-          }
-          if (shouldErrorsBeAnalyzed(source, dartEntry)) {
-            CacheState verificationErrorsState = dartEntry.getStateInLibrary(
-                DartEntry.VERIFICATION_ERRORS, librarySource);
-            if (verificationErrorsState == CacheState.INVALID ||
-                (isPriority && verificationErrorsState == CacheState.FLUSHED)) {
-              return _createGenerateDartErrorsTask(
-                  source, dartEntry, librarySource, libraryEntry);
-            }
-            if (hintsEnabled) {
-              CacheState hintsState =
-                  dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource);
-              if (hintsState == CacheState.INVALID ||
-                  (isPriority && hintsState == CacheState.FLUSHED)) {
-                return _createGenerateDartHintsTask(
-                    source, dartEntry, librarySource, libraryEntry);
-              }
-            }
-            if (lintsEnabled) {
-              CacheState lintsState =
-                  dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource);
-              if (lintsState == CacheState.INVALID ||
-                  (isPriority && lintsState == CacheState.FLUSHED)) {
-                return _createGenerateDartLintsTask(
-                    source, dartEntry, librarySource, libraryEntry);
-              }
-            }
-          }
-        }
-      }
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      CacheState parseErrorsState = htmlEntry.getState(HtmlEntry.PARSE_ERRORS);
-      if (parseErrorsState == CacheState.INVALID ||
-          (isPriority && parseErrorsState == CacheState.FLUSHED)) {
-        return _createParseHtmlTask(source, htmlEntry);
-      }
-      if (isPriority && parseErrorsState != CacheState.ERROR) {
-        ht.HtmlUnit parsedUnit = htmlEntry.anyParsedUnit;
-        if (parsedUnit == null) {
-          return _createParseHtmlTask(source, htmlEntry);
-        }
-      }
-      CacheState resolvedUnitState =
-          htmlEntry.getState(HtmlEntry.RESOLVED_UNIT);
-      if (resolvedUnitState == CacheState.INVALID ||
-          (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-        return _createResolveHtmlTask(source, htmlEntry);
-      }
-    }
-    return new AnalysisContextImpl_TaskData(null, false);
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], or `null` if the
-   * source is not a Dart file.
-   *
-   * @param source the source for which a cache entry is being sought
-   * @return the source cache entry associated with the given source
-   */
-  DartEntry _getReadableDartEntry(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, false);
-    }
-    if (sourceEntry is DartEntry) {
-      return sourceEntry;
-    }
-    return null;
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], or `null` if the
-   * source is not an HTML file.
-   */
-  HtmlEntry _getReadableHtmlEntry(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, false);
-    }
-    if (sourceEntry is HtmlEntry) {
-      return sourceEntry;
-    }
-    return null;
-  }
-
-  /**
-   * Return the cache entry associated with the given [source], creating it if
-   * necessary.
-   */
-  SourceEntry _getReadableSourceEntry(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, false);
-    }
-    return sourceEntry;
-  }
-
-  /**
-   * Return a resolved compilation unit corresponding to the given [element] in
-   * the library defined by the given [librarySource], or `null` if the
-   * information is not cached.
-   */
-  TimestampedData<CompilationUnit> _getResolvedUnit(
-      CompilationUnitElement element, Source librarySource) {
-    SourceEntry sourceEntry = _cache.get(element.source);
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      if (dartEntry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource) ==
-          CacheState.VALID) {
-        return new TimestampedData<CompilationUnit>(
-            dartEntry.modificationTime,
-            dartEntry.getValueInLibrary(
-                DartEntry.RESOLVED_UNIT, librarySource));
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return a list containing all of the sources known to this context that have
-   * the given [kind].
-   */
-  List<Source> _getSources(SourceKind kind) {
-    List<Source> sources = new List<Source>();
-    MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.value.kind == kind) {
-        sources.add(iterator.key);
-      }
-    }
-    return sources;
-  }
-
-  /**
-   * Look at the given [source] to see whether a task needs to be performed
-   * related to it. If so, add the source to the set of sources that need to be
-   * processed. This method duplicates, and must therefore be kept in sync with,
-   * [_getNextAnalysisTaskForSource]. This method is intended to be used for
-   * testing purposes only.
-   */
-  void _getSourcesNeedingProcessing(
-      Source source,
-      SourceEntry sourceEntry,
-      bool isPriority,
-      bool hintsEnabled,
-      bool lintsEnabled,
-      HashSet<Source> sources) {
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      CacheState scanErrorsState = dartEntry.getState(DartEntry.SCAN_ERRORS);
-      if (scanErrorsState == CacheState.INVALID ||
-          (isPriority && scanErrorsState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-      CacheState parseErrorsState = dartEntry.getState(DartEntry.PARSE_ERRORS);
-      if (parseErrorsState == CacheState.INVALID ||
-          (isPriority && parseErrorsState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-      if (isPriority) {
-        if (!dartEntry.hasResolvableCompilationUnit) {
-          sources.add(source);
-          return;
-        }
-      }
-      for (Source librarySource in getLibrariesContaining(source)) {
-        SourceEntry libraryEntry = _cache.get(librarySource);
-        if (libraryEntry is DartEntry) {
-          CacheState elementState = libraryEntry.getState(DartEntry.ELEMENT);
-          if (elementState == CacheState.INVALID ||
-              (isPriority && elementState == CacheState.FLUSHED)) {
-            sources.add(source);
-            return;
-          }
-          CacheState resolvedUnitState = dartEntry.getStateInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource);
-          if (resolvedUnitState == CacheState.INVALID ||
-              (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-            LibraryElement libraryElement =
-                libraryEntry.getValue(DartEntry.ELEMENT);
-            if (libraryElement != null) {
-              sources.add(source);
-              return;
-            }
-          }
-          if (shouldErrorsBeAnalyzed(source, dartEntry)) {
-            CacheState verificationErrorsState = dartEntry.getStateInLibrary(
-                DartEntry.VERIFICATION_ERRORS, librarySource);
-            if (verificationErrorsState == CacheState.INVALID ||
-                (isPriority && verificationErrorsState == CacheState.FLUSHED)) {
-              LibraryElement libraryElement =
-                  libraryEntry.getValue(DartEntry.ELEMENT);
-              if (libraryElement != null) {
-                sources.add(source);
-                return;
-              }
-            }
-            if (hintsEnabled) {
-              CacheState hintsState =
-                  dartEntry.getStateInLibrary(DartEntry.HINTS, librarySource);
-              if (hintsState == CacheState.INVALID ||
-                  (isPriority && hintsState == CacheState.FLUSHED)) {
-                LibraryElement libraryElement =
-                    libraryEntry.getValue(DartEntry.ELEMENT);
-                if (libraryElement != null) {
-                  sources.add(source);
-                  return;
-                }
-              }
-            }
-            if (lintsEnabled) {
-              CacheState lintsState =
-                  dartEntry.getStateInLibrary(DartEntry.LINTS, librarySource);
-              if (lintsState == CacheState.INVALID ||
-                  (isPriority && lintsState == CacheState.FLUSHED)) {
-                LibraryElement libraryElement =
-                    libraryEntry.getValue(DartEntry.ELEMENT);
-                if (libraryElement != null) {
-                  sources.add(source);
-                  return;
-                }
-              }
-            }
-          }
-        }
-      }
-    } else if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      CacheState parsedUnitState = htmlEntry.getState(HtmlEntry.PARSED_UNIT);
-      if (parsedUnitState == CacheState.INVALID ||
-          (isPriority && parsedUnitState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-      CacheState resolvedUnitState =
-          htmlEntry.getState(HtmlEntry.RESOLVED_UNIT);
-      if (resolvedUnitState == CacheState.INVALID ||
-          (isPriority && resolvedUnitState == CacheState.FLUSHED)) {
-        sources.add(source);
-        return;
-      }
-    }
-  }
-
-  /**
-   * Invalidate all of the resolution results computed by this context. The flag
-   * [invalidateUris] should be `true` if the cached results of converting URIs
-   * to source files should also be invalidated.
-   */
-  void _invalidateAllLocalResolutionInformation(bool invalidateUris) {
-    HashMap<Source, List<Source>> oldPartMap =
-        new HashMap<Source, List<Source>>();
-    MapIterator<Source, SourceEntry> iterator = _privatePartition.iterator();
-    while (iterator.moveNext()) {
-      Source source = iterator.key;
-      SourceEntry sourceEntry = iterator.value;
-      if (sourceEntry is HtmlEntry) {
-        HtmlEntry htmlEntry = sourceEntry;
-        htmlEntry.invalidateAllResolutionInformation(invalidateUris);
-        iterator.value = htmlEntry;
-        _workManager.add(source, SourcePriority.HTML);
-      } else if (sourceEntry is DartEntry) {
-        DartEntry dartEntry = sourceEntry;
-        oldPartMap[source] = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
-        dartEntry.invalidateAllResolutionInformation(invalidateUris);
-        iterator.value = dartEntry;
-        _workManager.add(source, _computePriority(dartEntry));
-      }
-    }
-    _removeFromPartsUsingMap(oldPartMap);
-  }
-
-  /**
-   * In response to a change to at least one of the compilation units in the
-   * library defined by the given [librarySource], invalidate any results that
-   * are dependent on the result of resolving that library.
-   *
-   * <b>Note:</b> Any cache entries that were accessed before this method was
-   * invoked must be re-accessed after this method returns.
-   */
-  void _invalidateLibraryResolution(Source librarySource) {
-    // TODO(brianwilkerson) This could be optimized. There's no need to flush
-    // all of these entries if the public namespace hasn't changed, which will
-    // be a fairly common case. The question is whether we can afford the time
-    // to compute the namespace to look for differences.
-    DartEntry libraryEntry = _getReadableDartEntry(librarySource);
-    if (libraryEntry != null) {
-      List<Source> includedParts =
-          libraryEntry.getValue(DartEntry.INCLUDED_PARTS);
-      libraryEntry.invalidateAllResolutionInformation(false);
-      _workManager.add(librarySource, SourcePriority.LIBRARY);
-      for (Source partSource in includedParts) {
-        SourceEntry partEntry = _cache.get(partSource);
-        if (partEntry is DartEntry) {
-          partEntry.invalidateAllResolutionInformation(false);
-        }
-      }
-    }
-  }
-
-  /**
-   * Return `true` if the given [library] is, or depends on, 'dart:html'. The
-   * [visitedLibraries] is a collection of the libraries that have been visited,
-   * used to prevent infinite recursion.
-   */
-  bool _isClient(LibraryElement library, Source htmlSource,
-      HashSet<LibraryElement> visitedLibraries) {
-    if (visitedLibraries.contains(library)) {
-      return false;
-    }
-    if (library.source == htmlSource) {
-      return true;
-    }
-    visitedLibraries.add(library);
-    for (LibraryElement imported in library.importedLibraries) {
-      if (_isClient(imported, htmlSource, visitedLibraries)) {
-        return true;
-      }
-    }
-    for (LibraryElement exported in library.exportedLibraries) {
-      if (_isClient(exported, htmlSource, visitedLibraries)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  bool _isTooBigHtmlSourceEntry(Source source, SourceEntry sourceEntry) =>
-      false;
-
-//  /**
-//   * Notify all of the analysis listeners that the given source is no longer included in the set of
-//   * sources that are being analyzed.
-//   *
-//   * @param source the source that is no longer being analyzed
-//   */
-//  void _notifyExcludedSource(Source source) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].excludedSource(this, source);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given source is now included in the set of
-//   * sources that are being analyzed.
-//   *
-//   * @param source the source that is now being analyzed
-//   */
-//  void _notifyIncludedSource(Source source) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].includedSource(this, source);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given Dart source was parsed.
-//   *
-//   * @param source the source that was parsed
-//   * @param unit the result of parsing the source
-//   */
-//  void _notifyParsedDart(Source source, CompilationUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].parsedDart(this, source, unit);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given HTML source was parsed.
-//   *
-//   * @param source the source that was parsed
-//   * @param unit the result of parsing the source
-//   */
-//  void _notifyParsedHtml(Source source, ht.HtmlUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].parsedHtml(this, source, unit);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given Dart source was resolved.
-//   *
-//   * @param source the source that was resolved
-//   * @param unit the result of resolving the source
-//   */
-//  void _notifyResolvedDart(Source source, CompilationUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].resolvedDart(this, source, unit);
-//    }
-//  }
-
-//  /**
-//   * Notify all of the analysis listeners that the given HTML source was resolved.
-//   *
-//   * @param source the source that was resolved
-//   * @param unit the result of resolving the source
-//   */
-//  void _notifyResolvedHtml(Source source, ht.HtmlUnit unit) {
-//    int count = _listeners.length;
-//    for (int i = 0; i < count; i++) {
-//      _listeners[i].resolvedHtml(this, source, unit);
-//    }
-//  }
-
-  /**
-   * Log the given debugging [message].
-   */
-  void _logInformation(String message) {
-    AnalysisEngine.instance.logger.logInformation(message);
-  }
-
-  /**
-   * Notify all of the analysis listeners that a task is about to be performed.
-   */
-  void _notifyAboutToPerformTask(String taskDescription) {
-    int count = _listeners.length;
-    for (int i = 0; i < count; i++) {
-      _listeners[i].aboutToPerformTask(this, taskDescription);
-    }
-  }
-
-  /**
-   * Notify all of the analysis listeners that the errors associated with the
-   * given [source] has been updated to the given [errors].
-   */
-  void _notifyErrors(
-      Source source, List<AnalysisError> errors, LineInfo lineInfo) {
-    int count = _listeners.length;
-    for (int i = 0; i < count; i++) {
-      _listeners[i].computedErrors(this, source, errors, lineInfo);
-    }
-  }
-
-  /**
-   * Given that the given [source] (with the corresponding [sourceEntry]) has
-   * been invalidated, invalidate all of the libraries that depend on it.
-   */
-  void _propagateInvalidation(Source source, SourceEntry sourceEntry) {
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      htmlEntry.modificationTime = getModificationStamp(source);
-      htmlEntry.invalidateAllInformation();
-      _cache.removedAst(source);
-      _workManager.add(source, SourcePriority.HTML);
-    } else if (sourceEntry is DartEntry) {
-      List<Source> containingLibraries = getLibrariesContaining(source);
-      List<Source> dependentLibraries = getLibrariesDependingOn(source);
-      HashSet<Source> librariesToInvalidate = new HashSet<Source>();
-      for (Source containingLibrary in containingLibraries) {
-        _computeAllLibrariesDependingOn(
-            containingLibrary, librariesToInvalidate);
-      }
-      for (Source dependentLibrary in dependentLibraries) {
-        _computeAllLibrariesDependingOn(
-            dependentLibrary, librariesToInvalidate);
-      }
-      for (Source library in librariesToInvalidate) {
-        _invalidateLibraryResolution(library);
-      }
-      DartEntry dartEntry = _cache.get(source);
-      _removeFromParts(source, dartEntry);
-      dartEntry.modificationTime = getModificationStamp(source);
-      dartEntry.invalidateAllInformation();
-      _cache.removedAst(source);
-      _workManager.add(source, SourcePriority.UNKNOWN);
-    }
-    // reset unit in the notification, it is out of date now
-    ChangeNoticeImpl notice = _pendingNotices[source];
-    if (notice != null) {
-      notice.resolvedDartUnit = null;
-      notice.resolvedHtmlUnit = null;
-    }
-  }
-
-  /**
-   * Given a [dartEntry] and a [library] element, record the library element and
-   * other information gleaned from the element in the cache entry.
-   */
-  void _recordElementData(DartEntry dartEntry, LibraryElement library,
-      Source librarySource, Source htmlSource) {
-    dartEntry.setValue(DartEntry.ELEMENT, library);
-    dartEntry.setValue(DartEntry.IS_LAUNCHABLE, library.entryPoint != null);
-    dartEntry.setValue(DartEntry.IS_CLIENT,
-        _isClient(library, htmlSource, new HashSet<LibraryElement>()));
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    Source source = task.source;
-    DartEntry dartEntry = _cache.get(source);
-    Source librarySource = task.libraryElement.source;
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      dartEntry.recordVerificationErrorInLibrary(
-          librarySource, thrownException);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    dartEntry.setValueInLibrary(
-        DartEntry.VERIFICATION_ERRORS, librarySource, task.errors);
-    ChangeNoticeImpl notice = getNotice(source);
-    LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
-    notice.setErrors(dartEntry.allErrors, lineInfo);
-    return dartEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordGenerateDartHintsTask(GenerateDartHintsTask task) {
-    Source librarySource = task.libraryElement.source;
-    CaughtException thrownException = task.exception;
-    DartEntry libraryEntry = null;
-    HashMap<Source, List<AnalysisError>> hintMap = task.hintMap;
-    if (hintMap == null) {
-      // We don't have any information about which sources to mark as invalid
-      // other than the library source.
-      DartEntry libraryEntry = _cache.get(librarySource);
-      if (thrownException == null) {
-        String message = "GenerateDartHintsTask returned a null hint map "
-            "without throwing an exception: ${librarySource.fullName}";
-        thrownException =
-            new CaughtException(new AnalysisException(message), null);
-      }
-      libraryEntry.recordHintErrorInLibrary(librarySource, thrownException);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    hintMap.forEach((Source unitSource, List<AnalysisError> hints) {
-      DartEntry dartEntry = _cache.get(unitSource);
-      if (unitSource == librarySource) {
-        libraryEntry = dartEntry;
-      }
-      if (thrownException == null) {
-        dartEntry.setValueInLibrary(DartEntry.HINTS, librarySource, hints);
-        ChangeNoticeImpl notice = getNotice(unitSource);
-        LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
-        notice.setErrors(dartEntry.allErrors, lineInfo);
-      } else {
-        dartEntry.recordHintErrorInLibrary(librarySource, thrownException);
-      }
-    });
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return libraryEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordGenerateDartLintsTask(GenerateDartLintsTask task) {
-    Source librarySource = task.libraryElement.source;
-    CaughtException thrownException = task.exception;
-    DartEntry libraryEntry = null;
-    HashMap<Source, List<AnalysisError>> lintMap = task.lintMap;
-    if (lintMap == null) {
-      // We don't have any information about which sources to mark as invalid
-      // other than the library source.
-      DartEntry libraryEntry = _cache.get(librarySource);
-      if (thrownException == null) {
-        String message = "GenerateDartLintsTask returned a null lint map "
-            "without throwing an exception: ${librarySource.fullName}";
-        thrownException =
-            new CaughtException(new AnalysisException(message), null);
-      }
-      libraryEntry.recordLintErrorInLibrary(librarySource, thrownException);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    lintMap.forEach((Source unitSource, List<AnalysisError> lints) {
-      DartEntry dartEntry = _cache.get(unitSource);
-      if (unitSource == librarySource) {
-        libraryEntry = dartEntry;
-      }
-      if (thrownException == null) {
-        dartEntry.setValueInLibrary(DartEntry.LINTS, librarySource, lints);
-        ChangeNoticeImpl notice = getNotice(unitSource);
-        LineInfo lineInfo = dartEntry.getValue(SourceEntry.LINE_INFO);
-        notice.setErrors(dartEntry.allErrors, lineInfo);
-      } else {
-        dartEntry.recordLintErrorInLibrary(librarySource, thrownException);
-      }
-    });
-    if (thrownException != null) {
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    return libraryEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  SourceEntry _recordGetContentsTask(GetContentTask task) {
-    if (!task.isComplete) {
-      return null;
-    }
-    Source source = task.source;
-    SourceEntry sourceEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      sourceEntry.recordContentError(thrownException);
-      {
-        sourceEntry.setValue(SourceEntry.CONTENT_ERRORS, task.errors);
-        ChangeNoticeImpl notice = getNotice(source);
-        notice.setErrors(sourceEntry.allErrors, null);
-      }
-      _workManager.remove(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    sourceEntry.modificationTime = task.modificationTime;
-    sourceEntry.setValue(SourceEntry.CONTENT, task.content);
-    return sourceEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordIncrementalAnalysisTaskResults(
-      IncrementalAnalysisTask task) {
-    CompilationUnit unit = task.compilationUnit;
-    if (unit != null) {
-      ChangeNoticeImpl notice = getNotice(task.source);
-      notice.resolvedDartUnit = unit;
-      _incrementalAnalysisCache =
-          IncrementalAnalysisCache.cacheResult(task.cache, unit);
-    }
-    return null;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordParseDartTaskResults(ParseDartTask task) {
-    Source source = task.source;
-    DartEntry dartEntry = _cache.get(source);
-    _removeFromParts(source, dartEntry);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      _removeFromParts(source, dartEntry);
-      dartEntry.recordParseError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    if (task.hasNonPartOfDirective) {
-      dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-      dartEntry.containingLibrary = source;
-      _workManager.add(source, SourcePriority.LIBRARY);
-    } else if (task.hasPartOfDirective) {
-      dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
-      dartEntry.removeContainingLibrary(source);
-      _workManager.add(source, SourcePriority.NORMAL_PART);
-    } else {
-      // The file contains no directives.
-      List<Source> containingLibraries = dartEntry.containingLibraries;
-      if (containingLibraries.length > 1 ||
-          (containingLibraries.length == 1 &&
-              containingLibraries[0] != source)) {
-        dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.PART);
-        dartEntry.removeContainingLibrary(source);
-        _workManager.add(source, SourcePriority.NORMAL_PART);
-      } else {
-        dartEntry.setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-        dartEntry.containingLibrary = source;
-        _workManager.add(source, SourcePriority.LIBRARY);
-      }
-    }
-    List<Source> newParts = task.includedSources;
-    for (int i = 0; i < newParts.length; i++) {
-      Source partSource = newParts[i];
-      DartEntry partEntry = _getReadableDartEntry(partSource);
-      if (partEntry != null && !identical(partEntry, dartEntry)) {
-        // TODO(brianwilkerson) Change the kind of the "part" if it was marked
-        // as a library and it has no directives.
-        partEntry.addContainingLibrary(source);
-      }
-    }
-    dartEntry.setValue(DartEntry.PARSED_UNIT, task.compilationUnit);
-    dartEntry.setValue(DartEntry.PARSE_ERRORS, task.errors);
-    dartEntry.setValue(DartEntry.EXPORTED_LIBRARIES, task.exportedSources);
-    dartEntry.setValue(DartEntry.IMPORTED_LIBRARIES, task.importedSources);
-    dartEntry.setValue(DartEntry.INCLUDED_PARTS, newParts);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    if (notice.resolvedDartUnit == null) {
-      notice.parsedDartUnit = task.compilationUnit;
-    }
-    notice.setErrors(dartEntry.allErrors, task.lineInfo);
-    // Verify that the incrementally parsed and resolved unit in the incremental
-    // cache is structurally equivalent to the fully parsed unit
-    _incrementalAnalysisCache = IncrementalAnalysisCache.verifyStructure(
-        _incrementalAnalysisCache, source, task.compilationUnit);
-    return dartEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  HtmlEntry _recordParseHtmlTaskResults(ParseHtmlTask task) {
-    Source source = task.source;
-    HtmlEntry htmlEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      htmlEntry.recordParseError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    LineInfo lineInfo = task.lineInfo;
-    htmlEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
-    htmlEntry.setValue(HtmlEntry.PARSED_UNIT, task.htmlUnit);
-    htmlEntry.setValue(HtmlEntry.PARSE_ERRORS, task.errors);
-    htmlEntry.setValue(
-        HtmlEntry.REFERENCED_LIBRARIES, task.referencedLibraries);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    notice.setErrors(htmlEntry.allErrors, lineInfo);
-    return htmlEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordResolveDartUnitTaskResults(ResolveDartUnitTask task) {
-    Source unitSource = task.source;
-    DartEntry dartEntry = _cache.get(unitSource);
-    Source librarySource = task.librarySource;
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      dartEntry.recordResolutionErrorInLibrary(librarySource, thrownException);
-      _cache.removedAst(unitSource);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    dartEntry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, librarySource, task.resolvedUnit);
-    _cache.storedAst(unitSource);
-    return dartEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  HtmlEntry _recordResolveHtmlTaskResults(ResolveHtmlTask task) {
-    Source source = task.source;
-    HtmlEntry htmlEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      htmlEntry.recordResolutionError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    htmlEntry.setState(HtmlEntry.PARSED_UNIT, CacheState.FLUSHED);
-    htmlEntry.setValue(HtmlEntry.RESOLVED_UNIT, task.resolvedUnit);
-    htmlEntry.setValue(HtmlEntry.ELEMENT, task.element);
-    htmlEntry.setValue(HtmlEntry.RESOLUTION_ERRORS, task.resolutionErrors);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    notice.resolvedHtmlUnit = task.resolvedUnit;
-    LineInfo lineInfo = htmlEntry.getValue(SourceEntry.LINE_INFO);
-    notice.setErrors(htmlEntry.allErrors, lineInfo);
-    return htmlEntry;
-  }
-
-  /**
-   * Record the results produced by performing a [task] and return the cache
-   * entry associated with the results.
-   */
-  DartEntry _recordScanDartTaskResults(ScanDartTask task) {
-    Source source = task.source;
-    DartEntry dartEntry = _cache.get(source);
-    CaughtException thrownException = task.exception;
-    if (thrownException != null) {
-      _removeFromParts(source, dartEntry);
-      dartEntry.recordScanError(thrownException);
-      _cache.removedAst(source);
-      throw new AnalysisException('<rethrow>', thrownException);
-    }
-    LineInfo lineInfo = task.lineInfo;
-    dartEntry.setValue(SourceEntry.LINE_INFO, lineInfo);
-    dartEntry.setValue(DartEntry.TOKEN_STREAM, task.tokenStream);
-    dartEntry.setValue(DartEntry.SCAN_ERRORS, task.errors);
-    _cache.storedAst(source);
-    ChangeNoticeImpl notice = getNotice(source);
-    notice.setErrors(dartEntry.allErrors, lineInfo);
-    return dartEntry;
-  }
-
-  void _removeFromCache(Source source) {
-    SourceEntry entry = _cache.remove(source);
-    if (entry != null && !entry.explicitlyAdded) {
-      _implicitAnalysisEventsController
-          .add(new ImplicitAnalysisEvent(source, false));
-    }
-  }
-
-  /**
-   * Remove the given [librarySource] from the list of containing libraries for
-   * all of the parts referenced by the given [dartEntry].
-   */
-  void _removeFromParts(Source librarySource, DartEntry dartEntry) {
-    List<Source> oldParts = dartEntry.getValue(DartEntry.INCLUDED_PARTS);
-    for (int i = 0; i < oldParts.length; i++) {
-      Source partSource = oldParts[i];
-      DartEntry partEntry = _getReadableDartEntry(partSource);
-      if (partEntry != null && !identical(partEntry, dartEntry)) {
-        partEntry.removeContainingLibrary(librarySource);
-        if (partEntry.containingLibraries.length == 0 && !exists(partSource)) {
-          _removeFromCache(partSource);
-        }
-      }
-    }
-  }
-
-  /**
-   * Remove the given libraries that are keys in the given map from the list of
-   * containing libraries for each of the parts in the corresponding value.
-   */
-  void _removeFromPartsUsingMap(HashMap<Source, List<Source>> oldPartMap) {
-    oldPartMap.forEach((Source librarySource, List<Source> oldParts) {
-      for (int i = 0; i < oldParts.length; i++) {
-        Source partSource = oldParts[i];
-        if (partSource != librarySource) {
-          DartEntry partEntry = _getReadableDartEntry(partSource);
-          if (partEntry != null) {
-            partEntry.removeContainingLibrary(librarySource);
-            if (partEntry.containingLibraries.length == 0 &&
-                !exists(partSource)) {
-              _removeFromCache(partSource);
-            }
-          }
-        }
-      }
-    });
-  }
-
-  /**
-   * Remove the given [source] from the priority order if it is in the list.
-   */
-  void _removeFromPriorityOrder(Source source) {
-    int count = _priorityOrder.length;
-    List<Source> newOrder = new List<Source>();
-    for (int i = 0; i < count; i++) {
-      if (_priorityOrder[i] != source) {
-        newOrder.add(_priorityOrder[i]);
-      }
-    }
-    if (newOrder.length < count) {
-      analysisPriorityOrder = newOrder;
-    }
-  }
-
-  /**
-   * Create an entry for the newly added [source] and invalidate any sources
-   * that referenced the source before it existed.
-   */
-  void _sourceAvailable(Source source) {
-    // TODO(brianwilkerson) This method needs to check whether the source was
-    // previously being implicitly analyzed. If so, the cache entry needs to be
-    // update to reflect the new status and an event needs to be generated to
-    // inform clients that it is no longer being implicitly analyzed.
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry == null) {
-      sourceEntry = _createSourceEntry(source, true);
-    } else {
-      _propagateInvalidation(source, sourceEntry);
-      sourceEntry = _cache.get(source);
-    }
-    if (sourceEntry is HtmlEntry) {
-      _workManager.add(source, SourcePriority.HTML);
-    } else if (sourceEntry is DartEntry) {
-      _workManager.add(source, _computePriority(sourceEntry));
-    }
-  }
-
-  /**
-   * Invalidate the [source] that was changed and any sources that referenced
-   * the source before it existed.
-   */
-  void _sourceChanged(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    // If the source is removed, we don't care about it.
-    if (sourceEntry == null) {
-      return;
-    }
-    // Check if the content of the source is the same as it was the last time.
-    String sourceContent = sourceEntry.getValue(SourceEntry.CONTENT);
-    if (sourceContent != null) {
-      sourceEntry.setState(SourceEntry.CONTENT, CacheState.FLUSHED);
-      try {
-        TimestampedData<String> fileContents = getContents(source);
-        if (fileContents.data == sourceContent) {
-          return;
-        }
-      } catch (e) {}
-    }
-    // We have to invalidate the cache.
-    _propagateInvalidation(source, sourceEntry);
-  }
-
-  /**
-   * Record that the give [source] has been deleted.
-   */
-  void _sourceDeleted(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      htmlEntry.recordContentError(new CaughtException(
-          new AnalysisException("This source was marked as being deleted"),
-          null));
-    } else if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      HashSet<Source> libraries = new HashSet<Source>();
-      for (Source librarySource in getLibrariesContaining(source)) {
-        libraries.add(librarySource);
-        for (Source dependentLibrary
-            in getLibrariesDependingOn(librarySource)) {
-          libraries.add(dependentLibrary);
-        }
-      }
-      for (Source librarySource in libraries) {
-        _invalidateLibraryResolution(librarySource);
-      }
-      dartEntry.recordContentError(new CaughtException(
-          new AnalysisException("This source was marked as being deleted"),
-          null));
-    }
-    _workManager.remove(source);
-    _removeFromPriorityOrder(source);
-  }
-
-  /**
-   * Record that the given [source] has been removed.
-   */
-  void _sourceRemoved(Source source) {
-    SourceEntry sourceEntry = _cache.get(source);
-    if (sourceEntry is HtmlEntry) {} else if (sourceEntry is DartEntry) {
-      HashSet<Source> libraries = new HashSet<Source>();
-      for (Source librarySource in getLibrariesContaining(source)) {
-        libraries.add(librarySource);
-        for (Source dependentLibrary
-            in getLibrariesDependingOn(librarySource)) {
-          libraries.add(dependentLibrary);
-        }
-      }
-      for (Source librarySource in libraries) {
-        _invalidateLibraryResolution(librarySource);
-      }
-    }
-    _removeFromCache(source);
-    _workManager.remove(source);
-    _removeFromPriorityOrder(source);
-  }
-
-  /**
-   * TODO(scheglov) A hackish, limited incremental resolution implementation.
-   */
-  bool _tryPoorMansIncrementalResolution(Source unitSource, String newCode) {
-    return PerformanceStatistics.incrementalAnalysis.makeCurrentWhile(() {
-      incrementalResolutionValidation_lastUnitSource = null;
-      incrementalResolutionValidation_lastLibrarySource = null;
-      incrementalResolutionValidation_lastUnit = null;
-      // prepare the entry
-      DartEntry dartEntry = _cache.get(unitSource);
-      if (dartEntry == null) {
-        return false;
-      }
-      // prepare the (only) library source
-      List<Source> librarySources = getLibrariesContaining(unitSource);
-      if (librarySources.length != 1) {
-        return false;
-      }
-      Source librarySource = librarySources[0];
-      // prepare the library element
-      LibraryElement libraryElement = getLibraryElement(librarySource);
-      if (libraryElement == null) {
-        return false;
-      }
-      // prepare the existing unit
-      CompilationUnit oldUnit =
-          getResolvedCompilationUnit2(unitSource, librarySource);
-      if (oldUnit == null) {
-        return false;
-      }
-      // do resolution
-      Stopwatch perfCounter = new Stopwatch()..start();
-      PoorMansIncrementalResolver resolver = new PoorMansIncrementalResolver(
-          typeProvider,
-          unitSource,
-          getReadableSourceEntryOrNull(unitSource),
-          null,
-          null,
-          oldUnit,
-          analysisOptions.incrementalApi);
-      bool success = resolver.resolve(newCode);
-      AnalysisEngine.instance.instrumentationService.logPerformance(
-          AnalysisPerformanceKind.INCREMENTAL,
-          perfCounter,
-          'success=$success,context_id=$_id,code_length=${newCode.length}');
-      if (!success) {
-        return false;
-      }
-      // if validation, remember the result, but throw it away
-      if (analysisOptions.incrementalValidation) {
-        incrementalResolutionValidation_lastUnitSource = oldUnit.element.source;
-        incrementalResolutionValidation_lastLibrarySource =
-            oldUnit.element.library.source;
-        incrementalResolutionValidation_lastUnit = oldUnit;
-        return false;
-      }
-      // prepare notice
-      {
-        LineInfo lineInfo = getLineInfo(unitSource);
-        ChangeNoticeImpl notice = getNotice(unitSource);
-        notice.resolvedDartUnit = oldUnit;
-        notice.setErrors(dartEntry.allErrors, lineInfo);
-      }
-      // OK
-      return true;
-    });
-  }
-
-  void _validateLastIncrementalResolutionResult() {
-    if (incrementalResolutionValidation_lastUnitSource == null ||
-        incrementalResolutionValidation_lastLibrarySource == null ||
-        incrementalResolutionValidation_lastUnit == null) {
-      return;
-    }
-    CompilationUnit fullUnit = getResolvedCompilationUnit2(
-        incrementalResolutionValidation_lastUnitSource,
-        incrementalResolutionValidation_lastLibrarySource);
-    if (fullUnit != null) {
-      try {
-        assertSameResolution(
-            incrementalResolutionValidation_lastUnit, fullUnit);
-      } on IncrementalResolutionMismatch catch (mismatch, stack) {
-        String failure = mismatch.message;
-        String message =
-            'Incremental resolution mismatch:\n$failure\nat\n$stack';
-        AnalysisEngine.instance.logger.logError(message);
-      }
-    }
-    incrementalResolutionValidation_lastUnitSource = null;
-    incrementalResolutionValidation_lastLibrarySource = null;
-    incrementalResolutionValidation_lastUnit = null;
-  }
-}
-
-/**
- * An object used by an analysis context to record the results of a task.
- */
-class AnalysisContextImpl_AnalysisTaskResultRecorder
-    implements AnalysisTaskVisitor<SourceEntry> {
-  final AnalysisContextImpl AnalysisContextImpl_this;
-
-  AnalysisContextImpl_AnalysisTaskResultRecorder(this.AnalysisContextImpl_this);
-
-  @override
-  DartEntry visitGenerateDartErrorsTask(GenerateDartErrorsTask task) =>
-      AnalysisContextImpl_this._recordGenerateDartErrorsTask(task);
-
-  @override
-  DartEntry visitGenerateDartHintsTask(GenerateDartHintsTask task) =>
-      AnalysisContextImpl_this._recordGenerateDartHintsTask(task);
-
-  @override
-  DartEntry visitGenerateDartLintsTask(GenerateDartLintsTask task) =>
-      AnalysisContextImpl_this._recordGenerateDartLintsTask(task);
-
-  @override
-  SourceEntry visitGetContentTask(GetContentTask task) =>
-      AnalysisContextImpl_this._recordGetContentsTask(task);
-
-  @override
-  DartEntry visitIncrementalAnalysisTask(IncrementalAnalysisTask task) =>
-      AnalysisContextImpl_this._recordIncrementalAnalysisTaskResults(task);
-
-  @override
-  DartEntry visitParseDartTask(ParseDartTask task) =>
-      AnalysisContextImpl_this._recordParseDartTaskResults(task);
-
-  @override
-  HtmlEntry visitParseHtmlTask(ParseHtmlTask task) =>
-      AnalysisContextImpl_this._recordParseHtmlTaskResults(task);
-
-  @override
-  DartEntry visitResolveDartLibraryCycleTask(
-          ResolveDartLibraryCycleTask task) =>
-      AnalysisContextImpl_this.recordResolveDartLibraryCycleTaskResults(task);
-
-  @override
-  DartEntry visitResolveDartLibraryTask(ResolveDartLibraryTask task) =>
-      AnalysisContextImpl_this.recordResolveDartLibraryTaskResults(task);
-
-  @override
-  DartEntry visitResolveDartUnitTask(ResolveDartUnitTask task) =>
-      AnalysisContextImpl_this._recordResolveDartUnitTaskResults(task);
-
-  @override
-  HtmlEntry visitResolveHtmlTask(ResolveHtmlTask task) =>
-      AnalysisContextImpl_this._recordResolveHtmlTaskResults(task);
-
-  @override
-  DartEntry visitScanDartTask(ScanDartTask task) =>
-      AnalysisContextImpl_this._recordScanDartTaskResults(task);
-}
-
-class AnalysisContextImpl_ContextRetentionPolicy
-    implements CacheRetentionPolicy {
-  final AnalysisContextImpl AnalysisContextImpl_this;
-
-  AnalysisContextImpl_ContextRetentionPolicy(this.AnalysisContextImpl_this);
-
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
-    int priorityCount = AnalysisContextImpl_this._priorityOrder.length;
-    for (int i = 0; i < priorityCount; i++) {
-      if (source == AnalysisContextImpl_this._priorityOrder[i]) {
-        return RetentionPriority.HIGH;
-      }
-    }
-    if (AnalysisContextImpl_this._neededForResolution != null &&
-        AnalysisContextImpl_this._neededForResolution.contains(source)) {
-      return RetentionPriority.HIGH;
-    }
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      if (_astIsNeeded(dartEntry)) {
-        return RetentionPriority.MEDIUM;
-      }
-    }
-    return RetentionPriority.LOW;
-  }
-
-  bool _astIsNeeded(DartEntry dartEntry) =>
-      dartEntry.hasInvalidData(DartEntry.HINTS) ||
-          dartEntry.hasInvalidData(DartEntry.LINTS) ||
-          dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) ||
-          dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS);
-}
-
-/**
- * An object used to construct a list of the libraries that must be resolved
- * together in order to resolve any one of the libraries.
- */
-class AnalysisContextImpl_CycleBuilder {
-  final AnalysisContextImpl AnalysisContextImpl_this;
-
-  /**
-   * A table mapping the sources of the defining compilation units of libraries
-   * to the representation of the library that has the information needed to
-   * resolve the library.
-   */
-  HashMap<Source, ResolvableLibrary> _libraryMap =
-      new HashMap<Source, ResolvableLibrary>();
-
-  /**
-   * The dependency graph used to compute the libraries in the cycle.
-   */
-  DirectedGraph<ResolvableLibrary> _dependencyGraph;
-
-  /**
-   * A list containing the libraries that are ready to be resolved.
-   */
-  List<ResolvableLibrary> _librariesInCycle;
-
-  /**
-   * The analysis task that needs to be performed before the cycle of libraries
-   * can be resolved, or `null` if the libraries are ready to be resolved.
-   */
-  AnalysisContextImpl_TaskData _taskData;
-
-  /**
-   * Initialize a newly created cycle builder.
-   */
-  AnalysisContextImpl_CycleBuilder(this.AnalysisContextImpl_this) : super();
-
-  /**
-   * Return a list containing the libraries that are ready to be resolved
-   * (assuming that [getTaskData] returns `null`).
-   */
-  List<ResolvableLibrary> get librariesInCycle => _librariesInCycle;
-
-  /**
-   * Return a representation of an analysis task that needs to be performed
-   * before the cycle of libraries can be resolved, or `null` if the libraries
-   * are ready to be resolved.
-   */
-  AnalysisContextImpl_TaskData get taskData => _taskData;
-
-  /**
-   * Compute a list of the libraries that need to be resolved together in orde
-   *  to resolve the given [librarySource].
-   */
-  void computeCycleContaining(Source librarySource) {
-    //
-    // Create the object representing the library being resolved.
-    //
-    ResolvableLibrary targetLibrary = _createLibrary(librarySource);
-    //
-    // Compute the set of libraries that need to be resolved together.
-    //
-    _dependencyGraph = new DirectedGraph<ResolvableLibrary>();
-    _computeLibraryDependencies(targetLibrary);
-    if (_taskData != null) {
-      return;
-    }
-    _librariesInCycle = _dependencyGraph.findCycleContaining(targetLibrary);
-    //
-    // Ensure that all of the data needed to resolve them has been computed.
-    //
-    _ensureImportsAndExports();
-    if (_taskData != null) {
-      // At least one imported library needs to be resolved before the target
-      // library.
-      AnalysisTask task = _taskData.task;
-      if (task is ResolveDartLibraryTask) {
-        AnalysisContextImpl_this._workManager
-            .addFirst(task.librarySource, SourcePriority.LIBRARY);
-      }
-      return;
-    }
-    _computePartsInCycle(librarySource);
-    if (_taskData != null) {
-      // At least one part needs to be parsed.
-      return;
-    }
-    // All of the AST's necessary to perform a resolution of the library cycle
-    // have been gathered, so it is no longer necessary to retain them in the
-    // cache.
-    AnalysisContextImpl_this._neededForResolution = null;
-  }
-
-  bool _addDependency(ResolvableLibrary dependant, Source dependency,
-      List<ResolvableLibrary> dependencyList) {
-    if (dependant.librarySource == dependency) {
-      // Don't add a dependency of a library on itself; there's no point.
-      return true;
-    }
-    ResolvableLibrary importedLibrary = _libraryMap[dependency];
-    if (importedLibrary == null) {
-      importedLibrary = _createLibraryOrNull(dependency);
-      if (importedLibrary != null) {
-        _computeLibraryDependencies(importedLibrary);
-        if (_taskData != null) {
-          return false;
-        }
-      }
-    }
-    if (importedLibrary != null) {
-      if (dependencyList != null) {
-        dependencyList.add(importedLibrary);
-      }
-      _dependencyGraph.addEdge(dependant, importedLibrary);
-    }
-    return true;
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given [library],
-   * creating instances of the class [Library] to represent them, and record the
-   * references in the library objects.
-   *
-   * Throws an [AnalysisException] if some portion of the library graph could
-   * not be traversed.
-   */
-  void _computeLibraryDependencies(ResolvableLibrary library) {
-    Source librarySource = library.librarySource;
-    DartEntry dartEntry =
-        AnalysisContextImpl_this._getReadableDartEntry(librarySource);
-    List<Source> importedSources =
-        _getSources(librarySource, dartEntry, DartEntry.IMPORTED_LIBRARIES);
-    if (_taskData != null) {
-      return;
-    }
-    List<Source> exportedSources =
-        _getSources(librarySource, dartEntry, DartEntry.EXPORTED_LIBRARIES);
-    if (_taskData != null) {
-      return;
-    }
-    _computeLibraryDependenciesFromDirectives(
-        library, importedSources, exportedSources);
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given [library],
-   * creating instances of the class [Library] to represent them, and record the
-   * references in the library objects. The [importedSources] is a list
-   * containing the sources that are imported into the given library. The
-   * [exportedSources] is a list containing the sources that are exported from
-   * the given library.
-   */
-  void _computeLibraryDependenciesFromDirectives(ResolvableLibrary library,
-      List<Source> importedSources, List<Source> exportedSources) {
-    int importCount = importedSources.length;
-    List<ResolvableLibrary> importedLibraries = new List<ResolvableLibrary>();
-    bool explicitlyImportsCore = false;
-    bool importsAsync = false;
-    for (int i = 0; i < importCount; i++) {
-      Source importedSource = importedSources[i];
-      if (importedSource == AnalysisContextImpl_this._coreLibrarySource) {
-        explicitlyImportsCore = true;
-      } else if (importedSource ==
-          AnalysisContextImpl_this._asyncLibrarySource) {
-        importsAsync = true;
-      }
-      if (!_addDependency(library, importedSource, importedLibraries)) {
-        return;
-      }
-    }
-    library.explicitlyImportsCore = explicitlyImportsCore;
-    if (!explicitlyImportsCore) {
-      if (!_addDependency(library, AnalysisContextImpl_this._coreLibrarySource,
-          importedLibraries)) {
-        return;
-      }
-    }
-    if (!importsAsync) {
-      // Add a dependency on async to ensure that the Future element will be
-      // built before we generate errors and warnings for async methods.  Also
-      // include it in importedLibraries, so that it will be picked up by
-      // LibraryResolver2._buildLibraryMap().
-      // TODO(paulberry): this is a bit of a hack, since the async library
-      // isn't actually being imported.  Also, it's not clear whether it should
-      // be necessary: in theory, dart:core already (indirectly) imports
-      // dart:async, so if core has been built, async should have been built
-      // too.  However, removing this code causes unit test failures.
-      if (!_addDependency(library, AnalysisContextImpl_this._asyncLibrarySource,
-          importedLibraries)) {
-        return;
-      }
-    }
-    library.importedLibraries = importedLibraries;
-    int exportCount = exportedSources.length;
-    if (exportCount > 0) {
-      List<ResolvableLibrary> exportedLibraries = new List<ResolvableLibrary>();
-      for (int i = 0; i < exportCount; i++) {
-        Source exportedSource = exportedSources[i];
-        if (!_addDependency(library, exportedSource, exportedLibraries)) {
-          return;
-        }
-      }
-      library.exportedLibraries = exportedLibraries;
-    }
-  }
-
-  /**
-   * Gather the resolvable AST structures for each of the compilation units in
-   * each of the libraries in the cycle. This is done in two phases: first we
-   * ensure that we have cached an AST structure for each compilation unit, then
-   * we gather them. We split the work this way because getting the AST
-   * structures can change the state of the cache in such a way that we would
-   * have more work to do if any compilation unit didn't have a resolvable AST
-   * structure.
-   */
-  void _computePartsInCycle(Source librarySource) {
-    int count = _librariesInCycle.length;
-    List<CycleBuilder_LibraryPair> libraryData =
-        new List<CycleBuilder_LibraryPair>();
-    for (int i = 0; i < count; i++) {
-      ResolvableLibrary library = _librariesInCycle[i];
-      libraryData.add(new CycleBuilder_LibraryPair(
-          library, _ensurePartsInLibrary(library)));
-    }
-    AnalysisContextImpl_this._neededForResolution = _gatherSources(libraryData);
-    if (AnalysisContextImpl._TRACE_PERFORM_TASK) {
-      print(
-          "  preserve resolution data for ${AnalysisContextImpl_this._neededForResolution.length} sources while resolving ${librarySource.fullName}");
-    }
-    if (_taskData != null) {
-      return;
-    }
-    for (int i = 0; i < count; i++) {
-      _computePartsInLibrary(libraryData[i]);
-    }
-  }
-
-  /**
-   * Gather the resolvable compilation units for each of the compilation units
-   * in the library represented by the [libraryPair].
-   */
-  void _computePartsInLibrary(CycleBuilder_LibraryPair libraryPair) {
-    ResolvableLibrary library = libraryPair.library;
-    List<CycleBuilder_SourceEntryPair> entryPairs = libraryPair.entryPairs;
-    int count = entryPairs.length;
-    List<ResolvableCompilationUnit> units =
-        new List<ResolvableCompilationUnit>(count);
-    for (int i = 0; i < count; i++) {
-      CycleBuilder_SourceEntryPair entryPair = entryPairs[i];
-      Source source = entryPair.source;
-      DartEntry dartEntry = entryPair.entry;
-      units[i] = new ResolvableCompilationUnit(
-          source, dartEntry.resolvableCompilationUnit);
-    }
-    library.resolvableCompilationUnits = units;
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by
-   * the compilation unit with the given [librarySource].
-   */
-  ResolvableLibrary _createLibrary(Source librarySource) {
-    ResolvableLibrary library = new ResolvableLibrary(librarySource);
-    SourceEntry sourceEntry =
-        AnalysisContextImpl_this._cache.get(librarySource);
-    if (sourceEntry is DartEntry) {
-      LibraryElementImpl libraryElement =
-          sourceEntry.getValue(DartEntry.ELEMENT) as LibraryElementImpl;
-      if (libraryElement != null) {
-        library.libraryElement = libraryElement;
-      }
-    }
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by
-   * the compilation unit with the given [librarySource].
-   */
-  ResolvableLibrary _createLibraryOrNull(Source librarySource) {
-    ResolvableLibrary library = new ResolvableLibrary(librarySource);
-    SourceEntry sourceEntry =
-        AnalysisContextImpl_this._cache.get(librarySource);
-    if (sourceEntry is DartEntry) {
-      LibraryElementImpl libraryElement =
-          sourceEntry.getValue(DartEntry.ELEMENT) as LibraryElementImpl;
-      if (libraryElement != null) {
-        library.libraryElement = libraryElement;
-      }
-    }
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Ensure that the given [library] has an element model built for it. If
-   * another task needs to be executed first in order to build the element
-   * model, that task is placed in [taskData].
-   */
-  void _ensureElementModel(ResolvableLibrary library) {
-    Source librarySource = library.librarySource;
-    DartEntry libraryEntry =
-        AnalysisContextImpl_this._getReadableDartEntry(librarySource);
-    if (libraryEntry != null &&
-        libraryEntry.getState(DartEntry.PARSED_UNIT) != CacheState.ERROR) {
-      AnalysisContextImpl_this._workManager
-          .addFirst(librarySource, SourcePriority.LIBRARY);
-      if (_taskData == null) {
-        _taskData = AnalysisContextImpl_this._createResolveDartLibraryTask(
-            librarySource, libraryEntry);
-      }
-    }
-  }
-
-  /**
-   * Ensure that all of the libraries that are exported by the given [library]
-   * (but are not themselves in the cycle) have element models built for them.
-   * If another task needs to be executed first in order to build the element
-   * model, that task is placed in [taskData].
-   */
-  void _ensureExports(
-      ResolvableLibrary library, HashSet<Source> visitedLibraries) {
-    List<ResolvableLibrary> dependencies = library.exports;
-    int dependencyCount = dependencies.length;
-    for (int i = 0; i < dependencyCount; i++) {
-      ResolvableLibrary dependency = dependencies[i];
-      if (!_librariesInCycle.contains(dependency) &&
-          visitedLibraries.add(dependency.librarySource)) {
-        if (dependency.libraryElement == null) {
-          _ensureElementModel(dependency);
-        } else {
-          _ensureExports(dependency, visitedLibraries);
-        }
-        if (_taskData != null) {
-          return;
-        }
-      }
-    }
-  }
-
-  /**
-   * Ensure that all of the libraries that are exported by the given [library]
-   * (but are not themselves in the cycle) have element models built for them.
-   * If another task needs to be executed first in order to build the element
-   * model, that task is placed in [taskData].
-   */
-  void _ensureImports(ResolvableLibrary library) {
-    List<ResolvableLibrary> dependencies = library.imports;
-    int dependencyCount = dependencies.length;
-    for (int i = 0; i < dependencyCount; i++) {
-      ResolvableLibrary dependency = dependencies[i];
-      if (!_librariesInCycle.contains(dependency) &&
-          dependency.libraryElement == null) {
-        _ensureElementModel(dependency);
-        if (_taskData != null) {
-          return;
-        }
-      }
-    }
-  }
-
-  /**
-   * Ensure that all of the libraries that are either imported or exported by
-   * libraries in the cycle (but are not themselves in the cycle) have element
-   * models built for them.
-   */
-  void _ensureImportsAndExports() {
-    HashSet<Source> visitedLibraries = new HashSet<Source>();
-    int libraryCount = _librariesInCycle.length;
-    for (int i = 0; i < libraryCount; i++) {
-      ResolvableLibrary library = _librariesInCycle[i];
-      _ensureImports(library);
-      if (_taskData != null) {
-        return;
-      }
-      _ensureExports(library, visitedLibraries);
-      if (_taskData != null) {
-        return;
-      }
-    }
-  }
-
-  /**
-   * Ensure that there is a resolvable compilation unit available for all of the
-   * compilation units in the given [library].
-   */
-  List<CycleBuilder_SourceEntryPair> _ensurePartsInLibrary(
-      ResolvableLibrary library) {
-    List<CycleBuilder_SourceEntryPair> pairs =
-        new List<CycleBuilder_SourceEntryPair>();
-    Source librarySource = library.librarySource;
-    DartEntry libraryEntry =
-        AnalysisContextImpl_this._getReadableDartEntry(librarySource);
-    if (libraryEntry == null) {
-      throw new AnalysisException(
-          "Cannot find entry for ${librarySource.fullName}");
-    } else if (libraryEntry.getState(DartEntry.PARSED_UNIT) ==
-        CacheState.ERROR) {
-      String message =
-          "Cannot compute parsed unit for ${librarySource.fullName}";
-      CaughtException exception = libraryEntry.exception;
-      if (exception == null) {
-        throw new AnalysisException(message);
-      }
-      throw new AnalysisException(
-          message, new CaughtException(exception, null));
-    }
-    _ensureResolvableCompilationUnit(librarySource, libraryEntry);
-    pairs.add(new CycleBuilder_SourceEntryPair(librarySource, libraryEntry));
-    List<Source> partSources =
-        _getSources(librarySource, libraryEntry, DartEntry.INCLUDED_PARTS);
-    int count = partSources.length;
-    for (int i = 0; i < count; i++) {
-      Source partSource = partSources[i];
-      DartEntry partEntry =
-          AnalysisContextImpl_this._getReadableDartEntry(partSource);
-      if (partEntry != null &&
-          partEntry.getState(DartEntry.PARSED_UNIT) != CacheState.ERROR) {
-        _ensureResolvableCompilationUnit(partSource, partEntry);
-        pairs.add(new CycleBuilder_SourceEntryPair(partSource, partEntry));
-      }
-    }
-    return pairs;
-  }
-
-  /**
-   * Ensure that there is a resolvable compilation unit available for the given
-   * [source].
-   */
-  void _ensureResolvableCompilationUnit(Source source, DartEntry dartEntry) {
-    // The entry will be null if the source represents a non-Dart file.
-    if (dartEntry != null && !dartEntry.hasResolvableCompilationUnit) {
-      if (_taskData == null) {
-        _taskData =
-            AnalysisContextImpl_this._createParseDartTask(source, dartEntry);
-      }
-    }
-  }
-
-  HashSet<Source> _gatherSources(List<CycleBuilder_LibraryPair> libraryData) {
-    int libraryCount = libraryData.length;
-    HashSet<Source> sources = new HashSet<Source>();
-    for (int i = 0; i < libraryCount; i++) {
-      List<CycleBuilder_SourceEntryPair> entryPairs = libraryData[i].entryPairs;
-      int entryCount = entryPairs.length;
-      for (int j = 0; j < entryCount; j++) {
-        sources.add(entryPairs[j].source);
-      }
-    }
-    return sources;
-  }
-
-  /**
-   * Return the sources described by the given [descriptor].
-   */
-  List<Source> _getSources(Source source, DartEntry dartEntry,
-      DataDescriptor<List<Source>> descriptor) {
-    if (dartEntry == null) {
-      return Source.EMPTY_LIST;
-    }
-    CacheState exportState = dartEntry.getState(descriptor);
-    if (exportState == CacheState.ERROR) {
-      return Source.EMPTY_LIST;
-    } else if (exportState != CacheState.VALID) {
-      if (_taskData == null) {
-        _taskData =
-            AnalysisContextImpl_this._createParseDartTask(source, dartEntry);
-      }
-      return Source.EMPTY_LIST;
-    }
-    return dartEntry.getValue(descriptor);
-  }
-}
-
-/**
- * Information about the next task to be performed. Each data has an implicit
- * associated source: the source that might need to be analyzed. There are
- * essentially three states that can be represented:
- *
- * * If [getTask] returns a non-`null` value, then that is the task that should
- *   be executed to further analyze the associated source.
- * * Otherwise, if [isBlocked] returns `true`, then there is no work that can be
- *   done, but analysis for the associated source is not complete.
- * * Otherwise, [getDependentSource] should return a source that needs to be
- *   analyzed before the analysis of the associated source can be completed.
- */
-class AnalysisContextImpl_TaskData {
-  /**
-   * The task that is to be performed.
-   */
-  final AnalysisTask task;
-
-  /**
-   * A flag indicating whether the associated source is blocked waiting for its
-   * contents to be loaded.
-   */
-  final bool _blocked;
-
-  /**
-   * Initialize a newly created data holder.
-   */
-  AnalysisContextImpl_TaskData(this.task, this._blocked);
-
-  /**
-   * Return `true` if the associated source is blocked waiting for its contents
-   * to be loaded.
-   */
-  bool get isBlocked => _blocked;
-
-  @override
-  String toString() {
-    if (task == null) {
-      return "blocked: $_blocked";
-    }
-    return task.toString();
-  }
-}
-
-/**
- * Statistics and information about a single [AnalysisContext].
- */
-abstract class AnalysisContextStatistics {
-  /**
-   * Return the statistics for each kind of cached data.
-   */
-  List<AnalysisContextStatistics_CacheRow> get cacheRows;
-
-  /**
-   * Return the exceptions that caused some entries to have a state of
-   * [CacheState.ERROR].
-   */
-  List<CaughtException> get exceptions;
-
-  /**
-   * Return information about each of the partitions in the cache.
-   */
-  List<AnalysisContextStatistics_PartitionData> get partitionData;
-
-  /**
-   * Return a list containing all of the sources in the cache.
-   */
-  List<Source> get sources;
-}
-
-/**
- * Information about single piece of data in the cache.
- */
-abstract class AnalysisContextStatistics_CacheRow {
-  /**
-   * List of possible states which can be queried.
-   */
-  static const List<CacheState> STATES = const <CacheState>[
-    CacheState.ERROR,
-    CacheState.FLUSHED,
-    CacheState.IN_PROCESS,
-    CacheState.INVALID,
-    CacheState.VALID
-  ];
-
-  /**
-   * Return the number of entries whose state is [CacheState.ERROR].
-   */
-  int get errorCount;
-
-  /**
-   * Return the number of entries whose state is [CacheState.FLUSHED].
-   */
-  int get flushedCount;
-
-  /**
-   * Return the number of entries whose state is [CacheState.IN_PROCESS].
-   */
-  int get inProcessCount;
-
-  /**
-   * Return the number of entries whose state is [CacheState.INVALID].
-   */
-  int get invalidCount;
-
-  /**
-   * Return the name of the data represented by this object.
-   */
-  String get name;
-
-  /**
-   * Return the number of entries whose state is [CacheState.VALID].
-   */
-  int get validCount;
-
-  /**
-   * Return the number of entries whose state is [state].
-   */
-  int getCount(CacheState state);
-}
-
-/**
- * Information about a single partition in the cache.
- */
-abstract class AnalysisContextStatistics_PartitionData {
-  /**
-   * Return the number of entries in the partition that have an AST structure in
-   * one state or another.
-   */
-  int get astCount;
-
-  /**
-   * Return the total number of entries in the partition.
-   */
-  int get totalCount;
-}
-
-/**
- * Implementation of the [AnalysisContextStatistics].
- */
-class AnalysisContextStatisticsImpl implements AnalysisContextStatistics {
-  Map<String, AnalysisContextStatistics_CacheRow> _dataMap =
-      new HashMap<String, AnalysisContextStatistics_CacheRow>();
-
-  List<Source> _sources = new List<Source>();
-
-  HashSet<CaughtException> _exceptions = new HashSet<CaughtException>();
-
-  List<AnalysisContextStatistics_PartitionData> _partitionData;
-
-  @override
-  List<AnalysisContextStatistics_CacheRow> get cacheRows =>
-      _dataMap.values.toList();
-
-  @override
-  List<CaughtException> get exceptions => new List.from(_exceptions);
-
-  @override
-  List<AnalysisContextStatistics_PartitionData> get partitionData =>
-      _partitionData;
-
-  /**
-   * Set the partition data returned by this object to the given data.
-   */
-  void set partitionData(List<AnalysisContextStatistics_PartitionData> data) {
-    _partitionData = data;
-  }
-
-  @override
-  List<Source> get sources => _sources;
-
-  void addSource(Source source) {
-    _sources.add(source);
-  }
-
-  void _internalPutCacheItem(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state) {
-    String rowName = rowDesc.toString();
-    AnalysisContextStatisticsImpl_CacheRowImpl row =
-        _dataMap[rowName] as AnalysisContextStatisticsImpl_CacheRowImpl;
-    if (row == null) {
-      row = new AnalysisContextStatisticsImpl_CacheRowImpl(rowName);
-      _dataMap[rowName] = row;
-    }
-    row._incState(state);
-    if (state == CacheState.ERROR) {
-      CaughtException exception = dartEntry.exception;
-      if (exception != null) {
-        _exceptions.add(exception);
-      }
-    }
-  }
-}
-
-class AnalysisContextStatisticsImpl_CacheRowImpl
-    implements AnalysisContextStatistics_CacheRow {
-  final String name;
-
-  Map<CacheState, int> _counts = <CacheState, int>{};
-
-  AnalysisContextStatisticsImpl_CacheRowImpl(this.name);
-
-  @override
-  int get errorCount => getCount(CacheState.ERROR);
-
-  @override
-  int get flushedCount => getCount(CacheState.FLUSHED);
-
-  @override
-  int get hashCode => name.hashCode;
-
-  @override
-  int get inProcessCount => getCount(CacheState.IN_PROCESS);
-
-  @override
-  int get invalidCount => getCount(CacheState.INVALID);
-
-  @override
-  int get validCount => getCount(CacheState.VALID);
-
-  @override
-  bool operator ==(Object obj) =>
-      obj is AnalysisContextStatisticsImpl_CacheRowImpl && obj.name == name;
-
-  @override
-  int getCount(CacheState state) {
-    int count = _counts[state];
-    if (count != null) {
-      return count;
-    } else {
-      return 0;
-    }
-  }
-
-  void _incState(CacheState state) {
-    if (_counts[state] == null) {
-      _counts[state] = 1;
-    } else {
-      _counts[state]++;
-    }
-  }
-}
-
-class AnalysisContextStatisticsImpl_PartitionDataImpl
-    implements AnalysisContextStatistics_PartitionData {
-  final int astCount;
-
-  final int totalCount;
-
-  AnalysisContextStatisticsImpl_PartitionDataImpl(
-      this.astCount, this.totalCount);
-}
-
-/**
  * A representation of changes to the types of analysis that should be
  * performed.
  */
@@ -5931,39 +762,17 @@
       InstrumentationService.NULL_SERVICE;
 
   /**
-   * The list of supported plugins for processing by clients.
-   */
-  List<Plugin> _supportedPlugins;
-
-  /**
    * The partition manager being used to manage the shared partitions.
    */
   final PartitionManager partitionManager = new PartitionManager();
 
   /**
-   * The partition manager being used to manage the shared partitions.
-   */
-  final newContext.PartitionManager partitionManager_new =
-      new newContext.PartitionManager();
-
-  /**
-   * A flag indicating whether the (new) task model should be used to perform
-   * analysis.
-   */
-  bool useTaskModel = true;
-
-  /**
    * A flag indicating whether the task model should attempt to limit
    * invalidation after a change.
    */
   bool limitInvalidationInTaskModel = false;
 
   /**
-   * The plugins that are defined outside the `analyzer` package.
-   */
-  List<Plugin> _userDefinedPlugins = <Plugin>[];
-
-  /**
    * The task manager used to manage the tasks used to analyze code.
    */
   TaskManager _taskManager;
@@ -6003,26 +812,21 @@
   }
 
   /**
-   * Return the list of supported plugins for processing by clients.
+   * Return the list of plugins that clients are required to process, either by
+   * creating an [ExtensionManager] or by using the method
+   * [processRequiredPlugins].
    */
-  List<Plugin> get supportedPlugins {
-    if (_supportedPlugins == null) {
-      _supportedPlugins = <Plugin>[
-        enginePlugin,
-        commandLinePlugin,
-        optionsPlugin
-      ];
-      _supportedPlugins.addAll(_userDefinedPlugins);
-    }
-    return _supportedPlugins;
-  }
+  List<Plugin> get requiredPlugins => <Plugin>[enginePlugin];
 
   /**
    * Return the task manager used to manage the tasks used to analyze code.
    */
   TaskManager get taskManager {
     if (_taskManager == null) {
-      new ExtensionManager().processPlugins(supportedPlugins);
+      if (enginePlugin.taskExtensionPoint == null) {
+        throw new IllegalStateException(
+            'The analysis engine plugin has not been registered');
+      }
       _taskManager = new TaskManager();
       _taskManager.addTaskDescriptors(enginePlugin.taskDescriptors);
       // TODO(brianwilkerson) Create a way to associate different results with
@@ -6033,18 +837,6 @@
   }
 
   /**
-   * Set plugins that are defined outside the `analyzer` package.
-   */
-  void set userDefinedPlugins(List<Plugin> plugins) {
-    if (plugins == null) {
-      plugins = <Plugin>[];
-    }
-    _userDefinedPlugins = plugins;
-    _supportedPlugins = null;
-    _taskManager = null;
-  }
-
-  /**
    * Clear any caches holding on to analysis results so that a full re-analysis
    * will be performed the next time an analysis context is created.
    */
@@ -6056,13 +848,20 @@
    * Create and return a new context in which analysis can be performed.
    */
   AnalysisContext createAnalysisContext() {
-    if (useTaskModel) {
-      return new newContext.AnalysisContextImpl();
-    }
     return new AnalysisContextImpl();
   }
 
   /**
+   * A utility method that clients can use to process all of the required
+   * plugins. This method can only be used by clients that do not need to
+   * process any other plugins.
+   */
+  void processRequiredPlugins() {
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
+  }
+
+  /**
    * Return `true` if the given [fileName] is an analysis options file.
    */
   static bool isAnalysisOptionsFileName(String fileName,
@@ -6206,22 +1005,10 @@
   void parsedDart(AnalysisContext context, Source source, CompilationUnit unit);
 
   /**
-   * Reports that the given HTML [source] was parsed in the given [context].
-   */
-  @deprecated
-  void parsedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
-
-  /**
    * Reports that the given Dart [source] was resolved in the given [context].
    */
   void resolvedDart(
       AnalysisContext context, Source source, CompilationUnit unit);
-
-  /**
-   * Reports that the given HTML [source] was resolved in the given [context].
-   */
-  @deprecated
-  void resolvedHtml(AnalysisContext context, Source source, ht.HtmlUnit unit);
 }
 
 /**
@@ -6239,18 +1026,6 @@
  */
 abstract class AnalysisOptions {
   /**
-   * If analysis is to parse and analyze all function bodies, return `true`.
-   * If analysis is to skip all function bodies, return `false`.  If analysis
-   * is to parse and analyze function bodies in some sources and not in others,
-   * throw an exception.
-   *
-   * This getter is deprecated; consider using [analyzeFunctionBodiesPredicate]
-   * instead.
-   */
-  @deprecated // Use this.analyzeFunctionBodiesPredicate
-  bool get analyzeFunctionBodies;
-
-  /**
    * Function that returns `true` if analysis is to parse and analyze function
    * bodies for a given source.
    */
@@ -6268,22 +1043,14 @@
   bool get dart2jsHint;
 
   /**
-   * Return `true` if analysis is to include the new async support.
+   * Return `true` to enable custom assert messages (DEP 37).
    */
-  @deprecated // Always true
-  bool get enableAsync;
+  bool get enableAssertMessage;
 
   /**
-   * Return `true` if analysis is to include the new deferred loading support.
+   * Return `true` to enable interface libraries (DEP 40).
    */
-  @deprecated // Always true
-  bool get enableDeferredLoading;
-
-  /**
-   * Return `true` if analysis is to include the new enum support.
-   */
-  @deprecated // Always true
-  bool get enableEnum;
+  bool get enableConditionalDirectives;
 
   /**
    * Return `true` to enable generic methods (DEP 22).
@@ -6291,12 +1058,6 @@
   bool get enableGenericMethods => null;
 
   /**
-   * Return `true` to enable null-aware operators (DEP 9).
-   */
-  @deprecated // Always true
-  bool get enableNullAwareOperators;
-
-  /**
    * Return `true` to strictly follow the specification when generating
    * warnings on "call" methods (fixes dartbug.com/21938).
    */
@@ -6370,18 +1131,6 @@
   static const int DEFAULT_CACHE_SIZE = 64;
 
   /**
-   * The default value for enabling deferred loading.
-   */
-  @deprecated
-  static bool DEFAULT_ENABLE_DEFERRED_LOADING = true;
-
-  /**
-   * The default value for enabling enum support.
-   */
-  @deprecated
-  static bool DEFAULT_ENABLE_ENUM = true;
-
-  /**
    * A predicate indicating whether analysis is to parse and analyze function
    * bodies.
    */
@@ -6401,6 +1150,17 @@
   bool dart2jsHint = false;
 
   /**
+   * A flag indicating whether custom assert messages are to be supported (DEP
+   * 37).
+   */
+  bool enableAssertMessage = false;
+
+  /**
+   * A flag indicating whether interface libraries are to be supported (DEP 40).
+   */
+  bool enableConditionalDirectives = false;
+
+  /**
    * A flag indicating whether generic methods are to be supported (DEP 22).
    */
   bool enableGenericMethods = false;
@@ -6485,36 +1245,11 @@
    * Initialize a newly created set of analysis options to have the same values
    * as those in the given set of analysis [options].
    */
-  @deprecated // Use new AnalysisOptionsImpl.from(options)
-  AnalysisOptionsImpl.con1(AnalysisOptions options) {
-    analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
-    cacheSize = options.cacheSize;
-    dart2jsHint = options.dart2jsHint;
-    enableStrictCallChecks = options.enableStrictCallChecks;
-    enableGenericMethods = options.enableGenericMethods;
-    enableSuperMixins = options.enableSuperMixins;
-    generateImplicitErrors = options.generateImplicitErrors;
-    generateSdkErrors = options.generateSdkErrors;
-    hint = options.hint;
-    incremental = options.incremental;
-    incrementalApi = options.incrementalApi;
-    incrementalValidation = options.incrementalValidation;
-    lint = options.lint;
-    preserveComments = options.preserveComments;
-    strongMode = options.strongMode;
-    if (options is AnalysisOptionsImpl) {
-      strongModeHints = options.strongModeHints;
-    }
-  }
-
-  /**
-   * Initialize a newly created set of analysis options to have the same values
-   * as those in the given set of analysis [options].
-   */
   AnalysisOptionsImpl.from(AnalysisOptions options) {
     analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
+    enableAssertMessage = options.enableAssertMessage;
     enableStrictCallChecks = options.enableStrictCallChecks;
     enableGenericMethods = options.enableGenericMethods;
     enableSuperMixins = options.enableSuperMixins;
@@ -6562,42 +1297,6 @@
     _analyzeFunctionBodiesPredicate = value;
   }
 
-  @deprecated
-  @override
-  bool get enableAsync => true;
-
-  @deprecated
-  void set enableAsync(bool enable) {
-    // Async support cannot be disabled
-  }
-
-  @deprecated
-  @override
-  bool get enableDeferredLoading => true;
-
-  @deprecated
-  void set enableDeferredLoading(bool enable) {
-    // Deferred loading support cannot be disabled
-  }
-
-  @deprecated
-  @override
-  bool get enableEnum => true;
-
-  @deprecated
-  void set enableEnum(bool enable) {
-    // Enum support cannot be disabled
-  }
-
-  @deprecated
-  @override
-  bool get enableNullAwareOperators => true;
-
-  @deprecated
-  void set enableNullAwareOperators(bool enable) {
-    // Null-aware operator support cannot be disabled
-  }
-
   /**
    * Predicate used for [analyzeFunctionBodiesPredicate] when
    * [analyzeFunctionBodies] is set to `true`.
@@ -6662,174 +1361,6 @@
 }
 
 /**
- * An analysis task.
- */
-abstract class AnalysisTask {
-  /**
-   * The context in which the task is to be performed.
-   */
-  final InternalAnalysisContext context;
-
-  /**
-   * The exception that was thrown while performing this task, or `null` if the
-   * task completed successfully.
-   */
-  CaughtException _thrownException;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given
-   * [context].
-   */
-  AnalysisTask(this.context);
-
-  /**
-   * Return the exception that was thrown while performing this task, or `null`
-   * if the task completed successfully.
-   */
-  CaughtException get exception => _thrownException;
-
-  /**
-   * Return a textual description of this task.
-   */
-  String get taskDescription;
-
-  /**
-   * Use the given [visitor] to visit this task. Throws an [AnalysisException]
-   * if the visitor throws the exception.
-   */
-  accept(AnalysisTaskVisitor visitor);
-
-  /**
-   * Perform this analysis task, protected by an exception handler. Throws an
-   * [AnalysisException] if an exception occurs while performing the task.
-   */
-  void internalPerform();
-
-  /**
-   * Perform this analysis task and use the given [visitor] to visit this task
-   * after it has completed. Throws an [AnalysisException] if the visitor throws
-   * the exception.
-   */
-  Object perform(AnalysisTaskVisitor visitor) {
-    try {
-      _safelyPerform();
-    } on AnalysisException catch (exception, stackTrace) {
-      _thrownException = new CaughtException(exception, stackTrace);
-      AnalysisEngine.instance.logger.logInformation(
-          "Task failed: $taskDescription",
-          new CaughtException(exception, stackTrace));
-    }
-    return PerformanceStatistics.analysisTaskVisitor
-        .makeCurrentWhile(() => accept(visitor));
-  }
-
-  @override
-  String toString() => taskDescription;
-
-  /**
-   * Perform this analysis task, ensuring that all exceptions are wrapped in an
-   * [AnalysisException]. Throws an [AnalysisException] if any exception occurs
-   * while performing the task
-   */
-  void _safelyPerform() {
-    try {
-      String contextName = context.name;
-      if (contextName == null) {
-        contextName = 'unnamed';
-      }
-      AnalysisEngine.instance.instrumentationService
-          .logAnalysisTask(contextName, taskDescription);
-      internalPerform();
-    } on AnalysisException {
-      rethrow;
-    } catch (exception, stackTrace) {
-      throw new AnalysisException(
-          exception.toString(), new CaughtException(exception, stackTrace));
-    }
-  }
-}
-
-/**
- * An object used to visit tasks. While tasks are not structured in any
- * interesting way, this class provides the ability to dispatch to an
- * appropriate method.
- */
-abstract class AnalysisTaskVisitor<E> {
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGenerateDartErrorsTask(GenerateDartErrorsTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGenerateDartHintsTask(GenerateDartHintsTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGenerateDartLintsTask(GenerateDartLintsTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitGetContentTask(GetContentTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitIncrementalAnalysisTask(
-      IncrementalAnalysisTask incrementalAnalysisTask);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitParseDartTask(ParseDartTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitParseHtmlTask(ParseHtmlTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveDartLibraryCycleTask(ResolveDartLibraryCycleTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveDartLibraryTask(ResolveDartLibraryTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveDartUnitTask(ResolveDartUnitTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitResolveHtmlTask(ResolveHtmlTask task);
-
-  /**
-   * Visit the given [task], returning the result of the visit. This method will
-   * throw an AnalysisException if the visitor throws an exception.
-   */
-  E visitScanDartTask(ScanDartTask task);
-}
-
-/**
  * The result of applying a [ChangeSet] to a [AnalysisContext].
  */
 class ApplyChangesStatus {
@@ -6842,262 +1373,6 @@
 }
 
 /**
- * A `CachedResult` is a single analysis result that is stored in a
- * [SourceEntry].
- */
-class CachedResult<E> {
-  /**
-   * The state of the cached value.
-   */
-  CacheState state;
-
-  /**
-   * The value being cached, or `null` if there is no value (for example, when
-   * the [state] is [CacheState.INVALID].
-   */
-  E value;
-
-  /**
-   * Initialize a newly created result holder to represent the value of data
-   * described by the given [descriptor].
-   */
-  CachedResult(DataDescriptor descriptor) {
-    state = CacheState.INVALID;
-    value = descriptor.defaultValue;
-  }
-}
-
-/**
- * A single partition in an LRU cache of information related to analysis.
- */
-abstract class CachePartition {
-  /**
-   * The context that owns this partition. Multiple contexts can reference a
-   * partition, but only one context can own it.
-   */
-  final InternalAnalysisContext context;
-
-  /**
-   * The maximum number of sources for which AST structures should be kept in
-   * the cache.
-   */
-  int _maxCacheSize = 0;
-
-  /**
-   * The policy used to determine which pieces of data to remove from the cache.
-   */
-  final CacheRetentionPolicy _retentionPolicy;
-
-  /**
-   * A table mapping the sources belonging to this partition to the information
-   * known about those sources.
-   */
-  HashMap<Source, SourceEntry> _sourceMap = new HashMap<Source, SourceEntry>();
-
-  /**
-   * A list containing the most recently accessed sources with the most recently
-   * used at the end of the list. When more sources are added than the maximum
-   * allowed then the least recently used source will be removed and will have
-   * it's cached AST structure flushed.
-   */
-  List<Source> _recentlyUsed;
-
-  /**
-   * Initialize a newly created cache to maintain at most [maxCacheSize] AST
-   * structures in the cache. The cache is owned by the give [context], and the
-   * [retentionPolicy] will be used to determine which pieces of data to remove
-   * from the cache.
-   */
-  CachePartition(this.context, this._maxCacheSize, this._retentionPolicy) {
-    _recentlyUsed = new List<Source>();
-  }
-
-  /**
-   * Return the number of entries in this partition that have an AST associated
-   * with them.
-   */
-  int get astSize {
-    int astSize = 0;
-    int count = _recentlyUsed.length;
-    for (int i = 0; i < count; i++) {
-      Source source = _recentlyUsed[i];
-      SourceEntry sourceEntry = _sourceMap[source];
-      if (sourceEntry is DartEntry) {
-        if (sourceEntry.anyParsedCompilationUnit != null) {
-          astSize++;
-        }
-      } else if (sourceEntry is HtmlEntry) {
-        if (sourceEntry.anyParsedUnit != null) {
-          astSize++;
-        }
-      }
-    }
-    return astSize;
-  }
-
-  /**
-   * Return a table mapping the sources known to the context to the information
-   * known about the source.
-   *
-   * <b>Note:</b> This method is only visible for use by [AnalysisCache] and
-   * should not be used for any other purpose.
-   */
-  Map<Source, SourceEntry> get map => _sourceMap;
-
-  /**
-   * Set the maximum size of the cache to the given [size].
-   */
-  void set maxCacheSize(int size) {
-    _maxCacheSize = size;
-    while (_recentlyUsed.length > _maxCacheSize) {
-      if (!_flushAstFromCache()) {
-        break;
-      }
-    }
-  }
-
-  /**
-   * Record that the AST associated with the given source was just read from the
-   * cache.
-   */
-  void accessedAst(Source source) {
-    if (_recentlyUsed.remove(source)) {
-      _recentlyUsed.add(source);
-      return;
-    }
-    while (_recentlyUsed.length >= _maxCacheSize) {
-      if (!_flushAstFromCache()) {
-        break;
-      }
-    }
-    _recentlyUsed.add(source);
-  }
-
-  /**
-   * Return `true` if the given [source] is contained in this partition.
-   */
-  bool contains(Source source);
-
-  /**
-   * Return the entry associated with the given [source].
-   */
-  SourceEntry get(Source source) => _sourceMap[source];
-
-  /**
-   * Return an iterator returning all of the map entries mapping sources to
-   * cache entries.
-   */
-  MapIterator<Source, SourceEntry> iterator() =>
-      new SingleMapIterator<Source, SourceEntry>(_sourceMap);
-
-  /**
-   * Associate the given [entry] with the given [source].
-   */
-  void put(Source source, SourceEntry entry) {
-    entry.fixExceptionState();
-    _sourceMap[source] = entry;
-  }
-
-  /**
-   * Remove all information related to the given [source] from this partition.
-   * Return the entry associated with the source, or `null` if there was cache
-   * entry for the source.
-   */
-  SourceEntry remove(Source source) {
-    _recentlyUsed.remove(source);
-    return _sourceMap.remove(source);
-  }
-
-  /**
-   * Record that the AST associated with the given [source] was just removed
-   * from the cache.
-   */
-  void removedAst(Source source) {
-    _recentlyUsed.remove(source);
-  }
-
-  /**
-   * Return the number of sources that are mapped to cache entries.
-   */
-  int size() => _sourceMap.length;
-
-  /**
-   * Record that the AST associated with the given [source] was just stored to
-   * the cache.
-   */
-  void storedAst(Source source) {
-    if (_recentlyUsed.contains(source)) {
-      return;
-    }
-    while (_recentlyUsed.length >= _maxCacheSize) {
-      if (!_flushAstFromCache()) {
-        break;
-      }
-    }
-    _recentlyUsed.add(source);
-  }
-
-  /**
-   * Attempt to flush one AST structure from the cache. Return `true` if a
-   * structure was flushed.
-   */
-  bool _flushAstFromCache() {
-    Source removedSource = _removeAstToFlush();
-    if (removedSource == null) {
-      return false;
-    }
-    SourceEntry sourceEntry = _sourceMap[removedSource];
-    if (sourceEntry is HtmlEntry) {
-      HtmlEntry htmlEntry = sourceEntry;
-      htmlEntry.flushAstStructures();
-    } else if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      dartEntry.flushAstStructures();
-    }
-    return true;
-  }
-
-  /**
-   * Remove and return one source from the list of recently used sources whose
-   * AST structure can be flushed from the cache. The source that will be
-   * returned will be the source that has been unreferenced for the longest
-   * period of time but that is not a priority for analysis.
-   */
-  Source _removeAstToFlush() {
-    int sourceToRemove = -1;
-    for (int i = 0; i < _recentlyUsed.length; i++) {
-      Source source = _recentlyUsed[i];
-      RetentionPriority priority =
-          _retentionPolicy.getAstPriority(source, _sourceMap[source]);
-      if (priority == RetentionPriority.LOW) {
-        return _recentlyUsed.removeAt(i);
-      } else if (priority == RetentionPriority.MEDIUM && sourceToRemove < 0) {
-        sourceToRemove = i;
-      }
-    }
-    if (sourceToRemove < 0) {
-      // This happens if the retention policy returns a priority of HIGH for all
-      // of the sources that have been recently used. This is the case, for
-      // example, when the list of priority sources is bigger than the current
-      // cache size.
-      return null;
-    }
-    return _recentlyUsed.removeAt(sourceToRemove);
-  }
-}
-
-/**
- * An object used to determine how important it is for data to be retained in
- * the analysis cache.
- */
-abstract class CacheRetentionPolicy {
-  /**
-   * Return the priority of retaining the AST structure for the given [source].
-   */
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry);
-}
-
-/**
  * The possible states of cached data.
  */
 class CacheState extends Enum<CacheState> {
@@ -7182,13 +1457,6 @@
   CompilationUnit get resolvedDartUnit;
 
   /**
-   * The fully resolved HTML AST that changed as a result of the analysis, or
-   * `null` if the AST was not changed.
-   */
-  @deprecated
-  ht.HtmlUnit get resolvedHtmlUnit;
-
-  /**
    * Return the source for which the result is being reported.
    */
   Source get source;
@@ -7221,13 +1489,6 @@
   CompilationUnit resolvedDartUnit;
 
   /**
-   * The fully resolved HTML AST that changed as a result of the analysis, or
-   * `null` if the AST was not changed.
-   */
-  @deprecated
-  ht.HtmlUnit resolvedHtmlUnit;
-
-  /**
    * The errors that changed as a result of the analysis, or `null` if errors
    * were not changed.
    */
@@ -7329,7 +1590,8 @@
   /**
    * Return `true` if this change set does not contain any changes.
    */
-  bool get isEmpty => addedSources.isEmpty &&
+  bool get isEmpty =>
+      addedSources.isEmpty &&
       changedSources.isEmpty &&
       _changedContent.isEmpty &&
       changedRanges.isEmpty &&
@@ -7547,1564 +1809,6 @@
 }
 
 /**
- * A pair containing a library and a list of the (source, entry) pairs for
- * compilation units in the library.
- */
-class CycleBuilder_LibraryPair {
-  /**
-   * The library containing the compilation units.
-   */
-  ResolvableLibrary library;
-
-  /**
-   * The (source, entry) pairs representing the compilation units in the
-   * library.
-   */
-  List<CycleBuilder_SourceEntryPair> entryPairs;
-
-  /**
-   * Initialize a newly created pair from the given [library] and [entryPairs].
-   */
-  CycleBuilder_LibraryPair(this.library, this.entryPairs);
-}
-
-/**
- * A pair containing a source and the cache entry associated with that source.
- * They are used to reduce the number of times an entry must be looked up in the
- * cache.
- */
-class CycleBuilder_SourceEntryPair {
-  /**
-   * The source associated with the entry.
-   */
-  Source source;
-
-  /**
-   * The entry associated with the source.
-   */
-  DartEntry entry;
-
-  /**
-   * Initialize a newly created pair from the given [source] and [entry].
-   */
-  CycleBuilder_SourceEntryPair(this.source, this.entry);
-}
-
-/**
- * The information cached by an analysis context about an individual Dart file.
- */
-class DartEntry extends SourceEntry {
-  /**
-   * The data descriptor representing the element model representing a single
-   * compilation unit. This model is incomplete and should not be used except as
-   * input to another task.
-   */
-  static final DataDescriptor<List<AnalysisError>> BUILT_ELEMENT =
-      new DataDescriptor<List<AnalysisError>>("DartEntry.BUILT_ELEMENT");
-
-  /**
-   * The data descriptor representing the AST structure after the element model
-   * has been built (and declarations are resolved) but before other resolution
-   * has been performed.
-   */
-  static final DataDescriptor<CompilationUnit> BUILT_UNIT =
-      new DataDescriptor<CompilationUnit>("DartEntry.BUILT_UNIT");
-
-  /**
-   * The data descriptor representing the list of libraries that contain this
-   * compilation unit.
-   */
-  static final DataDescriptor<List<Source>> CONTAINING_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.CONTAINING_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the library element for the library. This
-   * data is only available for Dart files that are the defining compilation
-   * unit of a library.
-   */
-  static final DataDescriptor<LibraryElement> ELEMENT =
-      new DataDescriptor<LibraryElement>("DartEntry.ELEMENT");
-
-  /**
-   * The data descriptor representing the list of exported libraries. This data
-   * is only available for Dart files that are the defining compilation unit of
-   * a library.
-   */
-  static final DataDescriptor<List<Source>> EXPORTED_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.EXPORTED_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the hints resulting from auditing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> HINTS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.HINTS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the list of imported libraries. This data
-   * is only available for Dart files that are the defining compilation unit of
-   * a library.
-   */
-  static final DataDescriptor<List<Source>> IMPORTED_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.IMPORTED_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the list of included parts. This data is
-   * only available for Dart files that are the defining compilation unit of a
-   * library.
-   */
-  static final DataDescriptor<List<Source>> INCLUDED_PARTS =
-      new DataDescriptor<List<Source>>(
-          "DartEntry.INCLUDED_PARTS", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the client flag. This data is only
-   * available for Dart files that are the defining compilation unit of a
-   * library.
-   */
-  static final DataDescriptor<bool> IS_CLIENT =
-      new DataDescriptor<bool>("DartEntry.IS_CLIENT", false);
-
-  /**
-   * The data descriptor representing the launchable flag. This data is only
-   * available for Dart files that are the defining compilation unit of a
-   * library.
-   */
-  static final DataDescriptor<bool> IS_LAUNCHABLE =
-      new DataDescriptor<bool>("DartEntry.IS_LAUNCHABLE", false);
-
-  /**
-   * The data descriptor representing lint warnings resulting from auditing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> LINTS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.LINTS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the errors resulting from parsing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> PARSE_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.PARSE_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the parsed AST structure.
-   */
-  static final DataDescriptor<CompilationUnit> PARSED_UNIT =
-      new DataDescriptor<CompilationUnit>("DartEntry.PARSED_UNIT");
-
-  /**
-   * The data descriptor representing the public namespace of the library. This
-   * data is only available for Dart files that are the defining compilation
-   * unit of a library.
-   */
-  static final DataDescriptor<Namespace> PUBLIC_NAMESPACE =
-      new DataDescriptor<Namespace>("DartEntry.PUBLIC_NAMESPACE");
-
-  /**
-   * The data descriptor representing the errors resulting from resolving the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.RESOLUTION_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the resolved AST structure.
-   */
-  static final DataDescriptor<CompilationUnit> RESOLVED_UNIT =
-      new DataDescriptor<CompilationUnit>("DartEntry.RESOLVED_UNIT");
-
-  /**
-   * The data descriptor representing the errors resulting from scanning the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> SCAN_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.SCAN_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the source kind.
-   */
-  static final DataDescriptor<SourceKind> SOURCE_KIND =
-      new DataDescriptor<SourceKind>(
-          "DartEntry.SOURCE_KIND", SourceKind.UNKNOWN);
-
-  /**
-   * The data descriptor representing the token stream.
-   */
-  static final DataDescriptor<Token> TOKEN_STREAM =
-      new DataDescriptor<Token>("DartEntry.TOKEN_STREAM");
-
-  /**
-   * The data descriptor representing the errors resulting from verifying the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> VERIFICATION_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "DartEntry.VERIFICATION_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The list of libraries that contain this compilation unit. The list will be
-   * empty if there are no known libraries that contain this compilation unit.
-   */
-  List<Source> _containingLibraries = new List<Source>();
-
-  /**
-   * The information known as a result of resolving this compilation unit as
-   * part of the library that contains this unit. This field will never be
-   * `null`.
-   */
-  ResolutionState _resolutionState = new ResolutionState();
-
-  /**
-   * Return all of the errors associated with the compilation unit that are
-   * currently cached.
-   */
-  List<AnalysisError> get allErrors {
-    List<AnalysisError> errors = new List<AnalysisError>();
-    errors.addAll(super.allErrors);
-    errors.addAll(getValue(SCAN_ERRORS));
-    errors.addAll(getValue(PARSE_ERRORS));
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      errors.addAll(state.getValue(RESOLUTION_ERRORS));
-      errors.addAll(state.getValue(VERIFICATION_ERRORS));
-      errors.addAll(state.getValue(HINTS));
-      errors.addAll(state.getValue(LINTS));
-      state = state._nextState;
-    }
-    if (errors.length == 0) {
-      return AnalysisError.NO_ERRORS;
-    }
-    return errors;
-  }
-
-  /**
-   * Return a valid parsed compilation unit, either an unresolved AST structure
-   * or the result of resolving the AST structure in the context of some
-   * library, or `null` if there is no parsed compilation unit available.
-   */
-  CompilationUnit get anyParsedCompilationUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      return getValue(PARSED_UNIT);
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(BUILT_UNIT) == CacheState.VALID) {
-        return state.getValue(BUILT_UNIT);
-      }
-      state = state._nextState;
-    }
-
-    return anyResolvedCompilationUnit;
-  }
-
-  /**
-   * Return the result of resolving the compilation unit as part of any library,
-   * or `null` if there is no cached resolved compilation unit.
-   */
-  CompilationUnit get anyResolvedCompilationUnit {
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-        return state.getValue(RESOLVED_UNIT);
-      }
-      state = state._nextState;
-    }
-    return null;
-  }
-
-  /**
-   * The libraries that are known to contain this part.
-   */
-  List<Source> get containingLibraries => _containingLibraries;
-
-  /**
-   * Set the list of libraries that contain this compilation unit to contain
-   * only the given [librarySource]. This method should only be invoked on
-   * entries that represent a library.
-   */
-  void set containingLibrary(Source librarySource) {
-    _containingLibraries.clear();
-    _containingLibraries.add(librarySource);
-  }
-
-  @override
-  List<DataDescriptor> get descriptors {
-    List<DataDescriptor> result = super.descriptors;
-    result.addAll(<DataDescriptor>[
-      DartEntry.SOURCE_KIND,
-      DartEntry.CONTAINING_LIBRARIES,
-      DartEntry.PARSE_ERRORS,
-      DartEntry.PARSED_UNIT,
-      DartEntry.SCAN_ERRORS,
-      DartEntry.SOURCE_KIND,
-      DartEntry.TOKEN_STREAM
-    ]);
-    SourceKind kind = getValue(DartEntry.SOURCE_KIND);
-    if (kind == SourceKind.LIBRARY) {
-      result.addAll(<DataDescriptor>[
-        DartEntry.ELEMENT,
-        DartEntry.EXPORTED_LIBRARIES,
-        DartEntry.IMPORTED_LIBRARIES,
-        DartEntry.INCLUDED_PARTS,
-        DartEntry.IS_CLIENT,
-        DartEntry.IS_LAUNCHABLE,
-        DartEntry.PUBLIC_NAMESPACE
-      ]);
-    }
-    return result;
-  }
-
-  /**
-   * Return `true` if this entry has an AST structure that can be resolved, even
-   * if it needs to be copied. Returning `true` implies that the method
-   * [resolvableCompilationUnit] will return a non-`null` result.
-   */
-  bool get hasResolvableCompilationUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      return true;
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(BUILT_UNIT) == CacheState.VALID ||
-          state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-        return true;
-      }
-      state = state._nextState;
-    }
-
-    return false;
-  }
-
-  @override
-  SourceKind get kind => getValue(SOURCE_KIND);
-
-  /**
-   * The library sources containing the receiver's source.
-   */
-  List<Source> get librariesContaining {
-    ResolutionState state = _resolutionState;
-    List<Source> result = new List<Source>();
-    while (state != null) {
-      if (state._librarySource != null) {
-        result.add(state._librarySource);
-      }
-      state = state._nextState;
-    }
-    return result;
-  }
-
-  /**
-   * Get a list of all the library-dependent descriptors for which values may
-   * be stored in this SourceEntry.
-   */
-  List<DataDescriptor> get libraryDescriptors {
-    return <DataDescriptor>[
-      DartEntry.BUILT_ELEMENT,
-      DartEntry.BUILT_UNIT,
-      DartEntry.RESOLUTION_ERRORS,
-      DartEntry.RESOLVED_UNIT,
-      DartEntry.VERIFICATION_ERRORS,
-      DartEntry.HINTS,
-      DartEntry.LINTS
-    ];
-  }
-
-  /**
-   * A compilation unit that has not been accessed by any other client and can
-   * therefore safely be modified by the reconciler, or `null` if the source has
-   * not been parsed.
-   */
-  CompilationUnit get resolvableCompilationUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      CompilationUnit unit = getValue(PARSED_UNIT);
-      setState(PARSED_UNIT, CacheState.FLUSHED);
-      return unit;
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (state.getState(BUILT_UNIT) == CacheState.VALID) {
-        // TODO(brianwilkerson) We're cloning the structure to remove any
-        // previous resolution data, but I'm not sure that's necessary.
-        return state.getValue(BUILT_UNIT).accept(new AstCloner());
-      }
-      if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-        return state.getValue(RESOLVED_UNIT).accept(new AstCloner());
-      }
-      state = state._nextState;
-    }
-    return null;
-  }
-
-  /**
-   * Add the given [librarySource] to the list of libraries that contain this
-   * part. This method should only be invoked on entries that represent a part.
-   */
-  void addContainingLibrary(Source librarySource) {
-    _containingLibraries.add(librarySource);
-  }
-
-  /**
-   * Flush any AST structures being maintained by this entry.
-   */
-  void flushAstStructures() {
-    _flush(TOKEN_STREAM);
-    _flush(PARSED_UNIT);
-    _resolutionState.flushAstStructures();
-  }
-
-  /**
-   * Return the state of the data represented by the given [descriptor] in the
-   * context of the given [librarySource].
-   */
-  CacheState getStateInLibrary(
-      DataDescriptor descriptor, Source librarySource) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (librarySource == state._librarySource) {
-        return state.getState(descriptor);
-      }
-      state = state._nextState;
-    }
-    return CacheState.INVALID;
-  }
-
-  /**
-   * Return the value of the data represented by the given [descriptor] in the
-   * context of the given [librarySource], or `null` if the data represented by
-   * the descriptor is not in the cache.
-   */
-  Object getValueInLibrary(DataDescriptor descriptor, Source librarySource) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState state = _resolutionState;
-    while (state != null) {
-      if (librarySource == state._librarySource) {
-        return state.getValue(descriptor);
-      }
-      state = state._nextState;
-    }
-    return descriptor.defaultValue;
-  }
-
-  /**
-   * Return `true` if the data represented by the given [descriptor] is marked
-   * as being invalid. If the descriptor represents library-specific data then
-   * this method will return `true` if the data associated with any library it
-   * marked as invalid.
-   */
-  bool hasInvalidData(DataDescriptor descriptor) {
-    if (_isValidDescriptor(descriptor)) {
-      return getState(descriptor) == CacheState.INVALID;
-    } else if (_isValidLibraryDescriptor(descriptor)) {
-      ResolutionState state = _resolutionState;
-      while (state != null) {
-        if (state.getState(descriptor) == CacheState.INVALID) {
-          return true;
-        }
-        state = state._nextState;
-      }
-    }
-    return false;
-  }
-
-  @override
-  void invalidateAllInformation() {
-    super.invalidateAllInformation();
-    setState(SCAN_ERRORS, CacheState.INVALID);
-    setState(TOKEN_STREAM, CacheState.INVALID);
-    setState(SOURCE_KIND, CacheState.INVALID);
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    _discardCachedResolutionInformation(true);
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the
-   * compilation unit. The flag [invalidateUris] should be `true` if the cached
-   * results of converting URIs to source files should also be invalidated.
-   */
-  void invalidateAllResolutionInformation(bool invalidateUris) {
-    if (getState(PARSED_UNIT) == CacheState.FLUSHED) {
-      ResolutionState state = _resolutionState;
-      while (state != null) {
-        if (state.getState(BUILT_UNIT) == CacheState.VALID) {
-          CompilationUnit unit = state.getValue(BUILT_UNIT);
-          setValue(PARSED_UNIT, unit.accept(new AstCloner()));
-          break;
-        } else if (state.getState(RESOLVED_UNIT) == CacheState.VALID) {
-          CompilationUnit unit = state.getValue(RESOLVED_UNIT);
-          setValue(PARSED_UNIT, unit.accept(new AstCloner()));
-          break;
-        }
-        state = state._nextState;
-      }
-    }
-    _discardCachedResolutionInformation(invalidateUris);
-  }
-
-  /**
-   * Invalidate all of the parse and resolution information associated with
-   * this source.
-   */
-  void invalidateParseInformation() {
-    setState(SOURCE_KIND, CacheState.INVALID);
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    _containingLibraries.clear();
-    _discardCachedResolutionInformation(true);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to build the element
-   * model for the source represented by this entry in the context of the given
-   * [library]. This will set the state of all resolution-based information as
-   * being in error, but will not change the state of any parse results.
-   */
-  void recordBuildElementErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    setStateInLibrary(BUILT_ELEMENT, librarySource, CacheState.ERROR);
-    setStateInLibrary(BUILT_UNIT, librarySource, CacheState.ERROR);
-    recordResolutionErrorInLibrary(librarySource, exception);
-  }
-
-  @override
-  void recordContentError(CaughtException exception) {
-    super.recordContentError(exception);
-    recordScanError(exception);
-  }
-
-  /**
-   * Record that an error occurred while attempting to generate hints for the
-   * source represented by this entry. This will set the state of all
-   * verification information as being in error. The [librarySource] is the
-   * source of the library in which hints were being generated. The [exception]
-   * is the exception that shows where the error occurred.
-   */
-  void recordHintErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordHintError();
-  }
-
-  /**
-   * Record that an error occurred while attempting to generate lints for the
-   * source represented by this entry. This will set the state of all
-   * verification information as being in error. The [librarySource] is the
-   * source of the library in which lints were being generated. The [exception]
-   * is the exception that shows where the error occurred.
-   */
-  void recordLintErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordLintError();
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to scan or parse the
-   * entry represented by this entry. This will set the state of all information,
-   * including any resolution-based information, as being in error.
-   */
-  void recordParseError(CaughtException exception) {
-    setState(SOURCE_KIND, CacheState.ERROR);
-    setState(PARSE_ERRORS, CacheState.ERROR);
-    setState(PARSED_UNIT, CacheState.ERROR);
-    setState(EXPORTED_LIBRARIES, CacheState.ERROR);
-    setState(IMPORTED_LIBRARIES, CacheState.ERROR);
-    setState(INCLUDED_PARTS, CacheState.ERROR);
-    recordResolutionError(exception);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to resolve the source
-   * represented by this entry. This will set the state of all resolution-based
-   * information as being in error, but will not change the state of any parse
-   * results.
-   */
-  void recordResolutionError(CaughtException exception) {
-    this.exception = exception;
-    setState(ELEMENT, CacheState.ERROR);
-    setState(IS_CLIENT, CacheState.ERROR);
-    setState(IS_LAUNCHABLE, CacheState.ERROR);
-    setState(PUBLIC_NAMESPACE, CacheState.ERROR);
-    _resolutionState.recordResolutionErrorsInAllLibraries();
-  }
-
-  /**
-   * Record that an error occurred while attempting to resolve the source
-   * represented by this entry. This will set the state of all resolution-based
-   * information as being in error, but will not change the state of any parse
-   * results. The [librarySource] is the source of the library in which
-   * resolution was being performed. The [exception] is the exception that shows
-   * where the error occurred.
-   */
-  void recordResolutionErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    setState(ELEMENT, CacheState.ERROR);
-    setState(IS_CLIENT, CacheState.ERROR);
-    setState(IS_LAUNCHABLE, CacheState.ERROR);
-    setState(PUBLIC_NAMESPACE, CacheState.ERROR);
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordResolutionError();
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to scan or parse the
-   * entry represented by this entry. This will set the state of all
-   * information, including any resolution-based information, as being in error.
-   */
-  @override
-  void recordScanError(CaughtException exception) {
-    super.recordScanError(exception);
-    setState(SCAN_ERRORS, CacheState.ERROR);
-    setState(TOKEN_STREAM, CacheState.ERROR);
-    recordParseError(exception);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to generate errors and
-   * warnings for the source represented by this entry. This will set the state
-   * of all verification information as being in error. The [librarySource] is
-   * the source of the library in which verification was being performed. The
-   * [exception] is the exception that shows where the error occurred.
-   */
-  void recordVerificationErrorInLibrary(
-      Source librarySource, CaughtException exception) {
-    this.exception = exception;
-    ResolutionState state = _getOrCreateResolutionState(librarySource);
-    state.recordVerificationError();
-  }
-
-  /**
-   * Remove the given [library] from the list of libraries that contain this
-   * part. This method should only be invoked on entries that represent a part.
-   */
-  void removeContainingLibrary(Source library) {
-    _containingLibraries.remove(library);
-  }
-
-  /**
-   * Remove any resolution information associated with this compilation unit
-   * being part of the given [library], presumably because it is no longer part
-   * of the library.
-   */
-  void removeResolution(Source library) {
-    if (library != null) {
-      if (library == _resolutionState._librarySource) {
-        if (_resolutionState._nextState == null) {
-          _resolutionState.invalidateAllResolutionInformation();
-        } else {
-          _resolutionState = _resolutionState._nextState;
-        }
-      } else {
-        ResolutionState priorState = _resolutionState;
-        ResolutionState state = _resolutionState._nextState;
-        while (state != null) {
-          if (library == state._librarySource) {
-            priorState._nextState = state._nextState;
-            break;
-          }
-          priorState = state;
-          state = state._nextState;
-        }
-      }
-    }
-  }
-
-  /**
-   * Set the state of the data represented by the given [descriptor] in the
-   * context of the given [library] to the given [state].
-   */
-  void setStateInLibrary(
-      DataDescriptor descriptor, Source library, CacheState state) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState resolutionState = _getOrCreateResolutionState(library);
-    resolutionState.setState(descriptor, state);
-  }
-
-  /**
-   * Set the value of the data represented by the given [descriptor] in the
-   * context of the given [library] to the given [value], and set the state of
-   * that data to [CacheState.VALID].
-   */
-  void setValueInLibrary(
-      DataDescriptor descriptor, Source library, Object value) {
-    if (!_isValidLibraryDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    ResolutionState state = _getOrCreateResolutionState(library);
-    state.setValue(descriptor, value);
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the
-   * compilation unit. The flag [invalidateUris] should be `true` if the cached
-   * results of converting URIs to source files should also be invalidated.
-   */
-  void _discardCachedResolutionInformation(bool invalidateUris) {
-    setState(ELEMENT, CacheState.INVALID);
-    setState(IS_CLIENT, CacheState.INVALID);
-    setState(IS_LAUNCHABLE, CacheState.INVALID);
-    setState(PUBLIC_NAMESPACE, CacheState.INVALID);
-    _resolutionState.invalidateAllResolutionInformation();
-    if (invalidateUris) {
-      setState(EXPORTED_LIBRARIES, CacheState.INVALID);
-      setState(IMPORTED_LIBRARIES, CacheState.INVALID);
-      setState(INCLUDED_PARTS, CacheState.INVALID);
-    }
-  }
-
-  /**
-   * Return a resolution state for the specified [library], creating one as
-   * necessary.
-   */
-  ResolutionState _getOrCreateResolutionState(Source library) {
-    ResolutionState state = _resolutionState;
-    if (state._librarySource == null) {
-      state._librarySource = library;
-      return state;
-    }
-    while (state._librarySource != library) {
-      if (state._nextState == null) {
-        ResolutionState newState = new ResolutionState();
-        newState._librarySource = library;
-        state._nextState = newState;
-        return newState;
-      }
-      state = state._nextState;
-    }
-    return state;
-  }
-
-  @override
-  bool _isValidDescriptor(DataDescriptor descriptor) {
-    return descriptor == CONTAINING_LIBRARIES ||
-        descriptor == ELEMENT ||
-        descriptor == EXPORTED_LIBRARIES ||
-        descriptor == IMPORTED_LIBRARIES ||
-        descriptor == INCLUDED_PARTS ||
-        descriptor == IS_CLIENT ||
-        descriptor == IS_LAUNCHABLE ||
-        descriptor == PARSED_UNIT ||
-        descriptor == PARSE_ERRORS ||
-        descriptor == PUBLIC_NAMESPACE ||
-        descriptor == SCAN_ERRORS ||
-        descriptor == SOURCE_KIND ||
-        descriptor == TOKEN_STREAM ||
-        super._isValidDescriptor(descriptor);
-  }
-
-  /**
-   * Return `true` if the [descriptor] is valid for this entry when the data is
-   * relative to a library.
-   */
-  bool _isValidLibraryDescriptor(DataDescriptor descriptor) {
-    return descriptor == BUILT_ELEMENT ||
-        descriptor == BUILT_UNIT ||
-        descriptor == HINTS ||
-        descriptor == LINTS ||
-        descriptor == RESOLUTION_ERRORS ||
-        descriptor == RESOLVED_UNIT ||
-        descriptor == VERIFICATION_ERRORS;
-  }
-
-  @override
-  bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
-    bool needsSeparator = super._writeDiffOn(buffer, oldEntry);
-    if (oldEntry is! DartEntry) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("entry type changed; was ");
-      buffer.write(oldEntry.runtimeType.toString());
-      return true;
-    }
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "tokenStream",
-        DartEntry.TOKEN_STREAM, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "scanErrors", DartEntry.SCAN_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "sourceKind", DartEntry.SOURCE_KIND, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "parsedUnit", DartEntry.PARSED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "parseErrors",
-        DartEntry.PARSE_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "importedLibraries", DartEntry.IMPORTED_LIBRARIES, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "exportedLibraries", DartEntry.EXPORTED_LIBRARIES, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "includedParts",
-        DartEntry.INCLUDED_PARTS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "element", DartEntry.ELEMENT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "publicNamespace", DartEntry.PUBLIC_NAMESPACE, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "clientServer", DartEntry.IS_CLIENT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "launchable",
-        DartEntry.IS_LAUNCHABLE, oldEntry);
-    // TODO(brianwilkerson) Add better support for containingLibraries.
-    // It would be nice to be able to report on size-preserving changes.
-    int oldLibraryCount = (oldEntry as DartEntry)._containingLibraries.length;
-    int libraryCount = _containingLibraries.length;
-    if (oldLibraryCount != libraryCount) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("containingLibraryCount = ");
-      buffer.write(oldLibraryCount);
-      buffer.write(" -> ");
-      buffer.write(libraryCount);
-      needsSeparator = true;
-    }
-    //
-    // Report change to the per-library state.
-    //
-    HashMap<Source, ResolutionState> oldStateMap =
-        new HashMap<Source, ResolutionState>();
-    ResolutionState state = (oldEntry as DartEntry)._resolutionState;
-    while (state != null) {
-      Source librarySource = state._librarySource;
-      if (librarySource != null) {
-        oldStateMap[librarySource] = state;
-      }
-      state = state._nextState;
-    }
-    state = _resolutionState;
-    while (state != null) {
-      Source librarySource = state._librarySource;
-      if (librarySource != null) {
-        ResolutionState oldState = oldStateMap.remove(librarySource);
-        if (oldState == null) {
-          if (needsSeparator) {
-            buffer.write("; ");
-          }
-          buffer.write("added resolution for ");
-          buffer.write(librarySource.fullName);
-          needsSeparator = true;
-        } else {
-          needsSeparator = oldState._writeDiffOn(
-              buffer, needsSeparator, oldEntry as DartEntry);
-        }
-      }
-      state = state._nextState;
-    }
-    for (Source librarySource in oldStateMap.keys.toSet()) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("removed resolution for ");
-      buffer.write(librarySource.fullName);
-      needsSeparator = true;
-    }
-    return needsSeparator;
-  }
-
-  @override
-  void _writeOn(StringBuffer buffer) {
-    buffer.write("Dart: ");
-    super._writeOn(buffer);
-    _writeStateOn(buffer, "tokenStream", TOKEN_STREAM);
-    _writeStateOn(buffer, "scanErrors", SCAN_ERRORS);
-    _writeStateOn(buffer, "sourceKind", SOURCE_KIND);
-    _writeStateOn(buffer, "parsedUnit", PARSED_UNIT);
-    _writeStateOn(buffer, "parseErrors", PARSE_ERRORS);
-    _writeStateOn(buffer, "exportedLibraries", EXPORTED_LIBRARIES);
-    _writeStateOn(buffer, "importedLibraries", IMPORTED_LIBRARIES);
-    _writeStateOn(buffer, "includedParts", INCLUDED_PARTS);
-    _writeStateOn(buffer, "element", ELEMENT);
-    _writeStateOn(buffer, "publicNamespace", PUBLIC_NAMESPACE);
-    _writeStateOn(buffer, "clientServer", IS_CLIENT);
-    _writeStateOn(buffer, "launchable", IS_LAUNCHABLE);
-    _resolutionState._writeOn(buffer);
-  }
-}
-
-/**
- * An immutable constant representing data that can be stored in the cache.
- */
-class DataDescriptor<E> {
-  /**
-   * The next artificial hash code.
-   */
-  static int _NEXT_HASH_CODE = 0;
-
-  /**
-   * The artifitial hash code for this object.
-   */
-  final int _hashCode = _NEXT_HASH_CODE++;
-
-  /**
-   * The name of the descriptor, used for debugging purposes.
-   */
-  final String _name;
-
-  /**
-   * The default value used when the data does not exist.
-   */
-  final E defaultValue;
-
-  /**
-   * Initialize a newly created descriptor to have the given [name] and
-   * [defaultValue].
-   */
-  DataDescriptor(this._name, [this.defaultValue = null]);
-
-  @override
-  int get hashCode => _hashCode;
-
-  @override
-  String toString() => _name;
-}
-
-/**
- * A retention policy that will keep AST's in the cache if there is analysis
- * information that needs to be computed for a source, where the computation is
- * dependent on having the AST.
- */
-class DefaultRetentionPolicy implements CacheRetentionPolicy {
-  /**
-   * An instance of this class that can be shared.
-   */
-  static DefaultRetentionPolicy POLICY = new DefaultRetentionPolicy();
-
-  /**
-   * Return `true` if there is analysis information in the given [dartEntry]
-   * that needs to be computed, where the computation is dependent on having the
-   * AST.
-   */
-  bool astIsNeeded(DartEntry dartEntry) =>
-      dartEntry.hasInvalidData(DartEntry.HINTS) ||
-          dartEntry.hasInvalidData(DartEntry.LINTS) ||
-          dartEntry.hasInvalidData(DartEntry.VERIFICATION_ERRORS) ||
-          dartEntry.hasInvalidData(DartEntry.RESOLUTION_ERRORS);
-
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) {
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      if (astIsNeeded(dartEntry)) {
-        return RetentionPriority.MEDIUM;
-      }
-    }
-    return RetentionPriority.LOW;
-  }
-}
-
-/**
- * Instances of the class `GenerateDartErrorsTask` generate errors and warnings for a single
- * Dart source.
- */
-class GenerateDartErrorsTask extends AnalysisTask {
-  /**
-   * The source for which errors and warnings are to be produced.
-   */
-  final Source source;
-
-  /**
-   * The compilation unit used to resolve the dependencies.
-   */
-  final CompilationUnit _unit;
-
-  /**
-   * The element model for the library containing the source.
-   */
-  final LibraryElement libraryElement;
-
-  /**
-   * The errors that were generated for the source.
-   */
-  List<AnalysisError> _errors;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source for which errors and warnings are to be produced
-   * @param unit the compilation unit used to resolve the dependencies
-   * @param libraryElement the element model for the library containing the source
-   */
-  GenerateDartErrorsTask(InternalAnalysisContext context, this.source,
-      this._unit, this.libraryElement)
-      : super(context);
-
-  /**
-   * Return the errors that were generated for the source.
-   *
-   * @return the errors that were generated for the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  @override
-  String get taskDescription =>
-      "generate errors and warnings for ${source.fullName}";
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitGenerateDartErrorsTask(this);
-
-  @override
-  void internalPerform() {
-    PerformanceStatistics.errors.makeCurrentWhile(() {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
-      TypeProvider typeProvider = context.typeProvider;
-      //
-      // Validate the directives
-      //
-      validateDirectives(context, source, _unit, errorListener);
-      //
-      // Use the ConstantVerifier to verify the use of constants.
-      // This needs to happen before using the ErrorVerifier because some error
-      // codes need the computed constant values.
-      //
-      // TODO(paulberry): as a temporary workaround for issue 21572,
-      // ConstantVerifier is being run right after ConstantValueComputer, so we
-      // don't need to run it here.  Once issue 21572 is fixed, re-enable the
-      // call to ConstantVerifier.
-//      ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, libraryElement, typeProvider);
-//      _unit.accept(constantVerifier);
-      //
-      // Use the ErrorVerifier to compute the rest of the errors.
-      //
-      ErrorVerifier errorVerifier = new ErrorVerifier(
-          errorReporter,
-          libraryElement,
-          typeProvider,
-          new InheritanceManager(libraryElement),
-          context.analysisOptions.enableSuperMixins);
-      _unit.accept(errorVerifier);
-      _errors = errorListener.getErrorsForSource(source);
-    });
-  }
-
-  /**
-   * Check each directive in the given compilation unit to see if the referenced source exists and
-   * report an error if it does not.
-   *
-   * @param context the context in which the library exists
-   * @param librarySource the source representing the library containing the directives
-   * @param unit the compilation unit containing the directives to be validated
-   * @param errorListener the error listener to which errors should be reported
-   */
-  static void validateDirectives(AnalysisContext context, Source librarySource,
-      CompilationUnit unit, AnalysisErrorListener errorListener) {
-    for (Directive directive in unit.directives) {
-      if (directive is UriBasedDirective) {
-        validateReferencedSource(
-            context, librarySource, directive, errorListener);
-      }
-    }
-  }
-
-  /**
-   * Check the given directive to see if the referenced source exists and report an error if it does
-   * not.
-   *
-   * @param context the context in which the library exists
-   * @param librarySource the source representing the library containing the directive
-   * @param directive the directive to be verified
-   * @param errorListener the error listener to which errors should be reported
-   */
-  static void validateReferencedSource(
-      AnalysisContext context,
-      Source librarySource,
-      UriBasedDirective directive,
-      AnalysisErrorListener errorListener) {
-    Source source = directive.source;
-    if (source != null) {
-      if (context.exists(source)) {
-        return;
-      }
-    } else {
-      // Don't report errors already reported by ParseDartTask.resolveDirective
-      if (directive.validate() != null) {
-        return;
-      }
-    }
-    StringLiteral uriLiteral = directive.uri;
-    errorListener.onError(new AnalysisError(
-        librarySource,
-        uriLiteral.offset,
-        uriLiteral.length,
-        CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-        [directive.uriContent]));
-  }
-}
-
-/**
- * Instances of the class `GenerateDartHintsTask` generate hints for a single Dart library.
- */
-class GenerateDartHintsTask extends AnalysisTask {
-  /**
-   * The compilation units that comprise the library, with the defining compilation unit appearing
-   * first in the list.
-   */
-  final List<TimestampedData<CompilationUnit>> _units;
-
-  /**
-   * The element model for the library being analyzed.
-   */
-  final LibraryElement libraryElement;
-
-  /**
-   * A table mapping the sources that were analyzed to the hints that were
-   * generated for the sources.
-   */
-  HashMap<Source, List<AnalysisError>> _hintMap;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param units the compilation units that comprise the library, with the defining compilation
-   *          unit appearing first in the list
-   * @param libraryElement the element model for the library being analyzed
-   */
-  GenerateDartHintsTask(
-      InternalAnalysisContext context, this._units, this.libraryElement)
-      : super(context);
-
-  /**
-   * Return a table mapping the sources that were analyzed to the hints that were generated for the
-   * sources, or `null` if the task has not been performed or if the analysis did not complete
-   * normally.
-   *
-   * @return a table mapping the sources that were analyzed to the hints that were generated for the
-   *         sources
-   */
-  HashMap<Source, List<AnalysisError>> get hintMap => _hintMap;
-
-  @override
-  String get taskDescription {
-    Source librarySource = libraryElement.source;
-    if (librarySource == null) {
-      return "generate Dart hints for library without source";
-    }
-    return "generate Dart hints for ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitGenerateDartHintsTask(this);
-
-  @override
-  void internalPerform() {
-    //
-    // Gather the compilation units.
-    //
-    int unitCount = _units.length;
-    List<CompilationUnit> compilationUnits =
-        new List<CompilationUnit>(unitCount);
-    for (int i = 0; i < unitCount; i++) {
-      compilationUnits[i] = _units[i].data;
-    }
-    //
-    // Analyze all of the units.
-    //
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-    HintGenerator hintGenerator =
-        new HintGenerator(compilationUnits, context, errorListener);
-    hintGenerator.generateForLibrary();
-    //
-    // Store the results.
-    //
-    _hintMap = new HashMap<Source, List<AnalysisError>>();
-    for (int i = 0; i < unitCount; i++) {
-      Source source = _units[i].data.element.source;
-      _hintMap[source] = errorListener.getErrorsForSource(source);
-    }
-  }
-}
-
-/// Generates lint feedback for a single Dart library.
-class GenerateDartLintsTask extends AnalysisTask {
-  ///The compilation units that comprise the library, with the defining
-  ///compilation unit appearing first in the list.
-  final List<TimestampedData<CompilationUnit>> _units;
-
-  /// The element model for the library being analyzed.
-  final LibraryElement libraryElement;
-
-  /// A mapping of analyzed sources to their associated lint warnings.
-  /// May be [null] if the task has not been performed or if analysis did not
-  /// complete normally.
-  HashMap<Source, List<AnalysisError>> lintMap;
-
-  /// Initialize a newly created task to perform lint checking over these
-  /// [_units] belonging to this [libraryElement] within the given [context].
-  GenerateDartLintsTask(context, this._units, this.libraryElement)
-      : super(context);
-
-  @override
-  String get taskDescription {
-    Source librarySource = libraryElement.source;
-    return (librarySource == null)
-        ? "generate Dart lints for library without source"
-        : "generate Dart lints for ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitGenerateDartLintsTask(this);
-
-  @override
-  void internalPerform() {
-    Iterable<CompilationUnit> compilationUnits =
-        _units.map((TimestampedData<CompilationUnit> unit) => unit.data);
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-    LintGenerator lintGenerator =
-        new LintGenerator(compilationUnits, errorListener);
-    lintGenerator.generate();
-
-    lintMap = new HashMap<Source, List<AnalysisError>>();
-    compilationUnits.forEach((CompilationUnit unit) {
-      Source source = unit.element.source;
-      lintMap[source] = errorListener.getErrorsForSource(source);
-    });
-  }
-}
-
-/**
- * Instances of the class `GetContentTask` get the contents of a source.
- */
-class GetContentTask extends AnalysisTask {
-  /**
-   * The source to be read.
-   */
-  final Source source;
-
-  /**
-   * A flag indicating whether this task is complete.
-   */
-  bool _complete = false;
-
-  /**
-   * The contents of the source.
-   */
-  String _content;
-
-  /**
-   * The errors that were produced by getting the source content.
-   */
-  final List<AnalysisError> errors = <AnalysisError>[];
-
-  /**
-   * The time at which the contents of the source were last modified.
-   */
-  int _modificationTime = -1;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param contentData the time-stamped contents of the source
-   */
-  GetContentTask(InternalAnalysisContext context, this.source)
-      : super(context) {
-    if (source == null) {
-      throw new IllegalArgumentException("Cannot get contents of null source");
-    }
-  }
-
-  /**
-   * Return the contents of the source, or `null` if the task has not completed or if there
-   * was an exception while getting the contents.
-   *
-   * @return the contents of the source
-   */
-  String get content => _content;
-
-  /**
-   * Return `true` if this task is complete. Unlike most tasks, this task is allowed to be
-   * visited more than once in order to support asynchronous IO. If the task is not complete when it
-   * is visited synchronously as part of the [AnalysisTask.perform]
-   * method, it will be visited again, using the same visitor, when the IO operation has been
-   * performed.
-   *
-   * @return `true` if this task is complete
-   */
-  bool get isComplete => _complete;
-
-  /**
-   * Return the time at which the contents of the source that was parsed were last modified, or a
-   * negative value if the task has not yet been performed or if an exception occurred.
-   *
-   * @return the time at which the contents of the source that was parsed were last modified
-   */
-  int get modificationTime => _modificationTime;
-
-  @override
-  String get taskDescription => "get contents of ${source.fullName}";
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitGetContentTask(this);
-
-  @override
-  void internalPerform() {
-    _complete = true;
-    try {
-      TimestampedData<String> data = context.getContents(source);
-      _content = data.data;
-      _modificationTime = data.modificationTime;
-      AnalysisEngine.instance.instrumentationService
-          .logFileRead(source.fullName, _modificationTime, _content);
-    } catch (exception, stackTrace) {
-      if (source.exists()) {
-        errors.add(new AnalysisError(
-            source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT, [exception]));
-      }
-      throw new AnalysisException("Could not get contents of $source",
-          new CaughtException(exception, stackTrace));
-    }
-  }
-}
-
-/**
- * The information cached by an analysis context about an individual HTML file.
- */
-class HtmlEntry extends SourceEntry {
-  /**
-   * The data descriptor representing the HTML element.
-   */
-  static final DataDescriptor<HtmlElement> ELEMENT =
-      new DataDescriptor<HtmlElement>("HtmlEntry.ELEMENT");
-
-  /**
-   * The data descriptor representing the hints resulting from auditing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> HINTS =
-      new DataDescriptor<List<AnalysisError>>(
-          "HtmlEntry.HINTS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the errors resulting from parsing the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> PARSE_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "HtmlEntry.PARSE_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the parsed AST structure.
-   */
-  static final DataDescriptor<ht.HtmlUnit> PARSED_UNIT =
-      new DataDescriptor<ht.HtmlUnit>("HtmlEntry.PARSED_UNIT");
-
-  /**
-   * The data descriptor representing the resolved AST structure.
-   */
-  static final DataDescriptor<ht.HtmlUnit> RESOLVED_UNIT =
-      new DataDescriptor<ht.HtmlUnit>("HtmlEntry.RESOLVED_UNIT");
-
-  /**
-   * The data descriptor representing the list of referenced libraries.
-   */
-  static final DataDescriptor<List<Source>> REFERENCED_LIBRARIES =
-      new DataDescriptor<List<Source>>(
-          "HtmlEntry.REFERENCED_LIBRARIES", Source.EMPTY_LIST);
-
-  /**
-   * The data descriptor representing the errors resulting from resolving the
-   * source.
-   */
-  static final DataDescriptor<List<AnalysisError>> RESOLUTION_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "HtmlEntry.RESOLUTION_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * Return all of the errors associated with the HTML file that are currently
-   * cached.
-   */
-  List<AnalysisError> get allErrors {
-    List<AnalysisError> errors = new List<AnalysisError>();
-    errors.addAll(super.allErrors);
-    errors.addAll(getValue(PARSE_ERRORS));
-    errors.addAll(getValue(RESOLUTION_ERRORS));
-    errors.addAll(getValue(HINTS));
-    if (errors.length == 0) {
-      return AnalysisError.NO_ERRORS;
-    }
-    return errors;
-  }
-
-  /**
-   * Return a valid parsed unit, either an unresolved AST structure or the
-   * result of resolving the AST structure, or `null` if there is no parsed unit
-   * available.
-   */
-  ht.HtmlUnit get anyParsedUnit {
-    if (getState(PARSED_UNIT) == CacheState.VALID) {
-      return getValue(PARSED_UNIT);
-    }
-    if (getState(RESOLVED_UNIT) == CacheState.VALID) {
-      return getValue(RESOLVED_UNIT);
-    }
-    return null;
-  }
-
-  @override
-  List<DataDescriptor> get descriptors {
-    List<DataDescriptor> result = super.descriptors;
-    result.addAll([
-      HtmlEntry.ELEMENT,
-      HtmlEntry.PARSE_ERRORS,
-      HtmlEntry.PARSED_UNIT,
-      HtmlEntry.RESOLUTION_ERRORS,
-      HtmlEntry.RESOLVED_UNIT,
-      HtmlEntry.HINTS
-    ]);
-    return result;
-  }
-
-  @override
-  SourceKind get kind => SourceKind.HTML;
-
-  /**
-   * Flush any AST structures being maintained by this entry.
-   */
-  void flushAstStructures() {
-    _flush(PARSED_UNIT);
-    _flush(RESOLVED_UNIT);
-  }
-
-  @override
-  void invalidateAllInformation() {
-    super.invalidateAllInformation();
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    setState(RESOLVED_UNIT, CacheState.INVALID);
-    invalidateAllResolutionInformation(true);
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the HTML file.
-   * If [invalidateUris] is `true`, the cached results of converting URIs to
-   * source files should also be invalidated.
-   */
-  void invalidateAllResolutionInformation(bool invalidateUris) {
-    setState(RESOLVED_UNIT, CacheState.INVALID);
-    setState(ELEMENT, CacheState.INVALID);
-    setState(RESOLUTION_ERRORS, CacheState.INVALID);
-    setState(HINTS, CacheState.INVALID);
-    if (invalidateUris) {
-      setState(REFERENCED_LIBRARIES, CacheState.INVALID);
-    }
-  }
-
-  /**
-   * Invalidate all of the parse and resolution information associated with
-   * this source.
-   */
-  void invalidateParseInformation() {
-    setState(PARSE_ERRORS, CacheState.INVALID);
-    setState(PARSED_UNIT, CacheState.INVALID);
-    invalidateAllResolutionInformation(true);
-  }
-
-  @override
-  void recordContentError(CaughtException exception) {
-    super.recordContentError(exception);
-    recordParseError(exception);
-  }
-
-  /**
-   * Record that an [exception] was encountered while attempting to parse the
-   * source associated with this entry.
-   */
-  void recordParseError(CaughtException exception) {
-    // If the scanning and parsing of HTML are separated,
-    // the following line can be removed.
-    recordScanError(exception);
-    setState(PARSE_ERRORS, CacheState.ERROR);
-    setState(PARSED_UNIT, CacheState.ERROR);
-    setState(REFERENCED_LIBRARIES, CacheState.ERROR);
-    recordResolutionError(exception);
-  }
-
-  /**
-   * Record that an [exception] was encountered while attempting to resolve the
-   * source associated with this entry.
-   */
-  void recordResolutionError(CaughtException exception) {
-    this.exception = exception;
-    setState(RESOLVED_UNIT, CacheState.ERROR);
-    setState(ELEMENT, CacheState.ERROR);
-    setState(RESOLUTION_ERRORS, CacheState.ERROR);
-    setState(HINTS, CacheState.ERROR);
-  }
-
-  @override
-  bool _isValidDescriptor(DataDescriptor descriptor) {
-    return descriptor == ELEMENT ||
-        descriptor == HINTS ||
-        descriptor == PARSED_UNIT ||
-        descriptor == PARSE_ERRORS ||
-        descriptor == REFERENCED_LIBRARIES ||
-        descriptor == RESOLUTION_ERRORS ||
-        descriptor == RESOLVED_UNIT ||
-        super._isValidDescriptor(descriptor);
-  }
-
-  @override
-  bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
-    bool needsSeparator = super._writeDiffOn(buffer, oldEntry);
-    if (oldEntry is! HtmlEntry) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("entry type changed; was ");
-      buffer.write(oldEntry.runtimeType);
-      return true;
-    }
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "parseErrors",
-        HtmlEntry.PARSE_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "parsedUnit", HtmlEntry.PARSED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "resolvedUnit",
-        HtmlEntry.RESOLVED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "resolutionErrors", HtmlEntry.RESOLUTION_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "referencedLibraries", HtmlEntry.REFERENCED_LIBRARIES, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "element", HtmlEntry.ELEMENT, oldEntry);
-    return needsSeparator;
-  }
-
-  @override
-  void _writeOn(StringBuffer buffer) {
-    buffer.write("Html: ");
-    super._writeOn(buffer);
-    _writeStateOn(buffer, "parseErrors", PARSE_ERRORS);
-    _writeStateOn(buffer, "parsedUnit", PARSED_UNIT);
-    _writeStateOn(buffer, "resolvedUnit", RESOLVED_UNIT);
-    _writeStateOn(buffer, "resolutionErrors", RESOLUTION_ERRORS);
-    _writeStateOn(buffer, "referencedLibraries", REFERENCED_LIBRARIES);
-    _writeStateOn(buffer, "element", ELEMENT);
-  }
-}
-
-/**
  * An event indicating when a source either starts or stops being implicitly
  * analyzed.
  */
@@ -9131,296 +1835,6 @@
 }
 
 /**
- * Instances of the class `IncrementalAnalysisCache` hold information used to perform
- * incremental analysis.
- *
- * See [AnalysisContextImpl.setChangedContents].
- */
-class IncrementalAnalysisCache {
-  final Source librarySource;
-
-  final Source source;
-
-  final String oldContents;
-
-  final CompilationUnit resolvedUnit;
-
-  String _newContents;
-
-  int _offset = 0;
-
-  int _oldLength = 0;
-
-  int _newLength = 0;
-
-  IncrementalAnalysisCache(
-      this.librarySource,
-      this.source,
-      this.resolvedUnit,
-      this.oldContents,
-      this._newContents,
-      this._offset,
-      this._oldLength,
-      this._newLength);
-
-  /**
-   * Determine if the cache contains source changes that need to be analyzed
-   *
-   * @return `true` if the cache contains changes to be analyzed, else `false`
-   */
-  bool get hasWork => _oldLength > 0 || _newLength > 0;
-
-  /**
-   * Return the current contents for the receiver's source.
-   *
-   * @return the contents (not `null`)
-   */
-  String get newContents => _newContents;
-
-  /**
-   * Return the number of characters in the replacement text.
-   *
-   * @return the replacement length (zero or greater)
-   */
-  int get newLength => _newLength;
-
-  /**
-   * Return the character position of the first changed character.
-   *
-   * @return the offset (zero or greater)
-   */
-  int get offset => _offset;
-
-  /**
-   * Return the number of characters that were replaced.
-   *
-   * @return the replaced length (zero or greater)
-   */
-  int get oldLength => _oldLength;
-
-  /**
-   * Determine if the incremental analysis result can be cached for the next incremental analysis.
-   *
-   * @param cache the prior incremental analysis cache
-   * @param unit the incrementally updated compilation unit
-   * @return the cache used for incremental analysis or `null` if incremental analysis results
-   *         cannot be cached for the next incremental analysis
-   */
-  static IncrementalAnalysisCache cacheResult(
-      IncrementalAnalysisCache cache, CompilationUnit unit) {
-    if (cache != null && unit != null) {
-      return new IncrementalAnalysisCache(cache.librarySource, cache.source,
-          unit, cache._newContents, cache._newContents, 0, 0, 0);
-    }
-    return null;
-  }
-
-  /**
-   * Determine if the cache should be cleared.
-   *
-   * @param cache the prior cache or `null` if none
-   * @param source the source being updated (not `null`)
-   * @return the cache used for incremental analysis or `null` if incremental analysis cannot
-   *         be performed
-   */
-  static IncrementalAnalysisCache clear(
-      IncrementalAnalysisCache cache, Source source) {
-    if (cache == null || cache.source == source) {
-      return null;
-    }
-    return cache;
-  }
-
-  /**
-   * Determine if incremental analysis can be performed from the given information.
-   *
-   * @param cache the prior cache or `null` if none
-   * @param source the source being updated (not `null`)
-   * @param oldContents the original source contents prior to this update (may be `null`)
-   * @param newContents the new contents after this incremental change (not `null`)
-   * @param offset the offset at which the change occurred
-   * @param oldLength the length of the text being replaced
-   * @param newLength the length of the replacement text
-   * @param sourceEntry the cached entry for the given source or `null` if none
-   * @return the cache used for incremental analysis or `null` if incremental analysis cannot
-   *         be performed
-   */
-  static IncrementalAnalysisCache update(
-      IncrementalAnalysisCache cache,
-      Source source,
-      String oldContents,
-      String newContents,
-      int offset,
-      int oldLength,
-      int newLength,
-      SourceEntry sourceEntry) {
-    // Determine the cache resolved unit
-    Source librarySource = null;
-    CompilationUnit unit = null;
-    if (sourceEntry is DartEntry) {
-      DartEntry dartEntry = sourceEntry;
-      List<Source> librarySources = dartEntry.librariesContaining;
-      if (librarySources.length == 1) {
-        librarySource = librarySources[0];
-        if (librarySource != null) {
-          unit = dartEntry.getValueInLibrary(
-              DartEntry.RESOLVED_UNIT, librarySource);
-        }
-      }
-    }
-    // Create a new cache if there is not an existing cache or the source is
-    // different or a new resolved compilation unit is available.
-    if (cache == null || cache.source != source || unit != null) {
-      if (unit == null) {
-        return null;
-      }
-      if (oldContents == null) {
-        if (oldLength != 0) {
-          return null;
-        }
-        oldContents =
-            "${newContents.substring(0, offset)}${newContents.substring(offset + newLength)}";
-      }
-      return new IncrementalAnalysisCache(librarySource, source, unit,
-          oldContents, newContents, offset, oldLength, newLength);
-    }
-    // Update the existing cache if the change is contiguous
-    if (cache._oldLength == 0 && cache._newLength == 0) {
-      cache._offset = offset;
-      cache._oldLength = oldLength;
-      cache._newLength = newLength;
-    } else {
-      if (cache._offset > offset || offset > cache._offset + cache._newLength) {
-        return null;
-      }
-      cache._newLength += newLength - oldLength;
-    }
-    cache._newContents = newContents;
-    return cache;
-  }
-
-  /**
-   * Verify that the incrementally parsed and resolved unit in the incremental cache is structurally
-   * equivalent to the fully parsed unit.
-   *
-   * @param cache the prior cache or `null` if none
-   * @param source the source of the compilation unit that was parsed (not `null`)
-   * @param unit the compilation unit that was just parsed
-   * @return the cache used for incremental analysis or `null` if incremental analysis results
-   *         cannot be cached for the next incremental analysis
-   */
-  static IncrementalAnalysisCache verifyStructure(
-      IncrementalAnalysisCache cache, Source source, CompilationUnit unit) {
-    if (cache != null && unit != null && cache.source == source) {
-      if (!AstComparator.equalNodes(cache.resolvedUnit, unit)) {
-        return null;
-      }
-    }
-    return cache;
-  }
-}
-
-/**
- * Instances of the class `IncrementalAnalysisTask` incrementally update existing analysis.
- */
-class IncrementalAnalysisTask extends AnalysisTask {
-  /**
-   * The information used to perform incremental analysis.
-   */
-  final IncrementalAnalysisCache cache;
-
-  /**
-   * The compilation unit that was produced by incrementally updating the existing unit.
-   */
-  CompilationUnit _updatedUnit;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param cache the incremental analysis cache used to perform the analysis
-   */
-  IncrementalAnalysisTask(InternalAnalysisContext context, this.cache)
-      : super(context);
-
-  /**
-   * Return the compilation unit that was produced by incrementally updating the existing
-   * compilation unit, or `null` if the task has not yet been performed, could not be
-   * performed, or if an exception occurred.
-   *
-   * @return the compilation unit
-   */
-  CompilationUnit get compilationUnit => _updatedUnit;
-
-  /**
-   * Return the source that is to be incrementally analyzed.
-   *
-   * @return the source
-   */
-  Source get source => cache != null ? cache.source : null;
-
-  @override
-  String get taskDescription =>
-      "incremental analysis ${cache != null ? cache.source : "null"}";
-
-  /**
-   * Return the type provider used for incremental resolution.
-   *
-   * @return the type provider (or `null` if an exception occurs)
-   */
-  TypeProvider get typeProvider {
-    try {
-      return context.typeProvider;
-    } on AnalysisException {
-      return null;
-    }
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitIncrementalAnalysisTask(this);
-
-  @override
-  void internalPerform() {
-    if (cache == null) {
-      return;
-    }
-    // Only handle small changes
-    if (cache.oldLength > 0 || cache.newLength > 30) {
-      return;
-    }
-    // Produce an updated token stream
-    CharacterReader reader = new CharSequenceReader(cache.newContents);
-    BooleanErrorListener errorListener = new BooleanErrorListener();
-    IncrementalScanner scanner = new IncrementalScanner(
-        cache.source, reader, errorListener, context.analysisOptions);
-    scanner.rescan(cache.resolvedUnit.beginToken, cache.offset, cache.oldLength,
-        cache.newLength);
-    if (errorListener.errorReported) {
-      return;
-    }
-    // Produce an updated AST
-    IncrementalParser parser = new IncrementalParser(
-        cache.source, scanner.tokenMap, AnalysisErrorListener.NULL_LISTENER);
-    _updatedUnit = parser.reparse(cache.resolvedUnit, scanner.leftToken,
-        scanner.rightToken, cache.offset, cache.offset + cache.oldLength);
-    // Update the resolution
-    TypeProvider typeProvider = this.typeProvider;
-    if (_updatedUnit != null && typeProvider != null) {
-      CompilationUnitElement element = _updatedUnit.element;
-      if (element != null) {
-        LibraryElement library = element.library;
-        if (library != null) {
-          IncrementalResolver resolver = new IncrementalResolver(null, null,
-              null, element, cache.offset, cache.oldLength, cache.newLength);
-          resolver.resolve(parser.updatedNode);
-        }
-      }
-    }
-  }
-}
-
-/**
  * Additional behavior for an analysis context that is required by internal
  * users of the context.
  */
@@ -9428,10 +1842,8 @@
   /**
    * A table mapping the sources known to the context to the information known
    * about the source.
-   *
-   * TODO(scheglov) add the type, once we have only one cache.
    */
-  dynamic get analysisCache;
+  AnalysisCache get analysisCache;
 
   /**
    * Allow the client to supply its own content cache.  This will take the
@@ -9449,11 +1861,6 @@
   List<AnalysisTarget> get explicitTargets;
 
   /**
-   * A factory to override how [LibraryResolver] is created.
-   */
-  LibraryResolverFactory get libraryResolverFactory;
-
-  /**
    * Return a list containing all of the sources that have been marked as
    * priority sources. Clients must not modify the returned list.
    */
@@ -9467,20 +1874,8 @@
   /**
    * The partition that contains analysis results that are not shared with other
    * contexts.
-   *
-   * TODO(scheglov) add the type, once we have only one cache.
    */
-  dynamic get privateAnalysisCachePartition;
-
-  /**
-   * A factory to override how [ResolverVisitor] is created.
-   */
-  ResolverVisitorFactory get resolverVisitorFactory;
-
-  /**
-   * Returns a statistics about this context.
-   */
-  AnalysisContextStatistics get statistics;
+  CachePartition get privateAnalysisCachePartition;
 
   /**
    * Sets the [TypeProvider] for this context.
@@ -9488,14 +1883,9 @@
   void set typeProvider(TypeProvider typeProvider);
 
   /**
-   * A factory to override how [TypeResolverVisitor] is created.
-   */
-  TypeResolverVisitorFactory get typeResolverVisitorFactory;
-
-  /**
    * A list of all [WorkManager]s used by this context.
    */
-  List<newContext.WorkManager> get workManagers;
+  List<WorkManager> get workManagers;
 
   /**
    * Return a list containing the sources of the libraries that are exported by
@@ -9520,17 +1910,6 @@
   List<Source> computeImportedLibraries(Source source);
 
   /**
-   * Return an AST structure corresponding to the given [source], but ensure
-   * that the structure has not already been resolved and will not be resolved
-   * by any other threads or in any other library.
-   *
-   * Throws an [AnalysisException] if the analysis could not be performed.
-   *
-   * <b>Note:</b> This method cannot be used in an async environment
-   */
-  CompilationUnit computeResolvableCompilationUnit(Source source);
-
-  /**
    * Return all the resolved [CompilationUnit]s for the given [source] if not
    * flushed, otherwise return `null` and ensures that the [CompilationUnit]s
    * will be eventually returned to the client from [performAnalysisTask].
@@ -9540,7 +1919,7 @@
   /**
    * Return the cache entry associated with the given [target].
    */
-  cache.CacheEntry getCacheEntry(AnalysisTarget target);
+  CacheEntry getCacheEntry(AnalysisTarget target);
 
   /**
    * Return context that owns the given [source].
@@ -9587,12 +1966,8 @@
 
   /**
    * Return `true` if errors should be produced for the given [source].
-   * The [entry] associated with the source is passed in for efficiency.
-   *
-   * TODO(scheglov) remove [entry] after migration to the new task model.
-   * It is not used there anyway.
    */
-  bool shouldErrorsBeAnalyzed(Source source, Object entry);
+  bool shouldErrorsBeAnalyzed(Source source);
 
   /**
    * For testing only: flush all representations of the AST (both resolved and
@@ -9601,13 +1976,6 @@
   void test_flushAstStructures(Source source);
 
   /**
-   * Call the given callback function for eache cache item in the context.
-   */
-  @deprecated
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state));
-
-  /**
    * Visit all entries of the content cache.
    */
   void visitContentCache(ContentCacheVisitor visitor);
@@ -9634,25 +2002,11 @@
   void logError(String message, [CaughtException exception]);
 
   /**
-   * Log the given [exception] as one representing an error. The [message] is an
-   * explanation of why the error occurred or what it means.
-   */
-  @deprecated // Use logError(message, exception)
-  void logError2(String message, Object exception);
-
-  /**
    * Log the given informational message. The [message] is expected to be an
    * explanation of why the error occurred or what it means. The [exception] is
    * expected to be the reason for the error.
    */
   void logInformation(String message, [CaughtException exception]);
-
-  /**
-   * Log the given [exception] as one representing an informational message. The
-   * [message] is an explanation of why the error occurred or what it means.
-   */
-  @deprecated // Use logInformation(message, exception)
-  void logInformation2(String message, Object exception);
 }
 
 /**
@@ -9663,13 +2017,7 @@
   void logError(String message, [CaughtException exception]) {}
 
   @override
-  void logError2(String message, Object exception) {}
-
-  @override
   void logInformation(String message, [CaughtException exception]) {}
-
-  @override
-  void logInformation2(String message, Object exception) {}
 }
 
 /**
@@ -9700,547 +2048,6 @@
 }
 
 /**
- * Instances of the class `ParseDartTask` parse a specific source as a Dart file.
- */
-class ParseDartTask extends AnalysisTask {
-  /**
-   * The source to be parsed.
-   */
-  final Source source;
-
-  /**
-   * The head of the token stream used for parsing.
-   */
-  final Token _tokenStream;
-
-  /**
-   * The line information associated with the source.
-   */
-  final LineInfo lineInfo;
-
-  /**
-   * The compilation unit that was produced by parsing the source.
-   */
-  CompilationUnit _unit;
-
-  /**
-   * A flag indicating whether the source contains a 'part of' directive.
-   */
-  bool _containsPartOfDirective = false;
-
-  /**
-   * A flag indicating whether the source contains any directive other than a 'part of' directive.
-   */
-  bool _containsNonPartOfDirective = false;
-
-  /**
-   * A set containing the sources referenced by 'export' directives.
-   */
-  HashSet<Source> _exportedSources = new HashSet<Source>();
-
-  /**
-   * A set containing the sources referenced by 'import' directives.
-   */
-  HashSet<Source> _importedSources = new HashSet<Source>();
-
-  /**
-   * A set containing the sources referenced by 'part' directives.
-   */
-  HashSet<Source> _includedSources = new HashSet<Source>();
-
-  /**
-   * The errors that were produced by scanning and parsing the source.
-   */
-  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param tokenStream the head of the token stream used for parsing
-   * @param lineInfo the line information associated with the source
-   */
-  ParseDartTask(InternalAnalysisContext context, this.source, this._tokenStream,
-      this.lineInfo)
-      : super(context);
-
-  /**
-   * Return the compilation unit that was produced by parsing the source, or `null` if the
-   * task has not yet been performed or if an exception occurred.
-   *
-   * @return the compilation unit that was produced by parsing the source
-   */
-  CompilationUnit get compilationUnit => _unit;
-
-  /**
-   * Return the errors that were produced by scanning and parsing the source, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return the errors that were produced by scanning and parsing the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  /**
-   * Return a list containing the sources referenced by 'export' directives, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return an list containing the sources referenced by 'export' directives
-   */
-  List<Source> get exportedSources => _toArray(_exportedSources);
-
-  /**
-   * Return `true` if the source contains any directive other than a 'part of' directive, or
-   * `false` if the task has not yet been performed or if an exception occurred.
-   *
-   * @return `true` if the source contains any directive other than a 'part of' directive
-   */
-  bool get hasNonPartOfDirective => _containsNonPartOfDirective;
-
-  /**
-   * Return `true` if the source contains a 'part of' directive, or `false` if the task
-   * has not yet been performed or if an exception occurred.
-   *
-   * @return `true` if the source contains a 'part of' directive
-   */
-  bool get hasPartOfDirective => _containsPartOfDirective;
-
-  /**
-   * Return a list containing the sources referenced by 'import' directives, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return a list containing the sources referenced by 'import' directives
-   */
-  List<Source> get importedSources => _toArray(_importedSources);
-
-  /**
-   * Return a list containing the sources referenced by 'part' directives, or an empty list if
-   * the task has not yet been performed or if an exception occurred.
-   *
-   * @return a list containing the sources referenced by 'part' directives
-   */
-  List<Source> get includedSources => _toArray(_includedSources);
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "parse as dart null source";
-    }
-    return "parse as dart ${source.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitParseDartTask(this);
-
-  @override
-  void internalPerform() {
-    //
-    // Then parse the token stream.
-    //
-    PerformanceStatistics.parse.makeCurrentWhile(() {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      Parser parser = new Parser(source, errorListener);
-      AnalysisOptions options = context.analysisOptions;
-      parser.parseFunctionBodies =
-          options.analyzeFunctionBodiesPredicate(source);
-      parser.parseGenericMethods = options.enableGenericMethods;
-      _unit = parser.parseCompilationUnit(_tokenStream);
-      _unit.lineInfo = lineInfo;
-      AnalysisContext analysisContext = context;
-      for (Directive directive in _unit.directives) {
-        if (directive is PartOfDirective) {
-          _containsPartOfDirective = true;
-        } else {
-          _containsNonPartOfDirective = true;
-          if (directive is UriBasedDirective) {
-            Source referencedSource = resolveDirective(
-                analysisContext, source, directive, errorListener);
-            if (referencedSource != null) {
-              if (directive is ExportDirective) {
-                _exportedSources.add(referencedSource);
-              } else if (directive is ImportDirective) {
-                _importedSources.add(referencedSource);
-              } else if (directive is PartDirective) {
-                if (referencedSource != source) {
-                  _includedSources.add(referencedSource);
-                }
-              } else {
-                throw new AnalysisException(
-                    "$runtimeType failed to handle a ${directive.runtimeType}");
-              }
-            }
-          }
-        }
-      }
-      _errors = errorListener.getErrorsForSource(source);
-    });
-  }
-
-  /**
-   * Efficiently convert the given set of [sources] to a list.
-   */
-  List<Source> _toArray(HashSet<Source> sources) {
-    int size = sources.length;
-    if (size == 0) {
-      return Source.EMPTY_LIST;
-    }
-    return new List.from(sources);
-  }
-
-  /**
-   * Return the result of resolving the URI of the given URI-based directive against the URI of the
-   * given library, or `null` if the URI is not valid.
-   *
-   * @param context the context in which the resolution is to be performed
-   * @param librarySource the source representing the library containing the directive
-   * @param directive the directive which URI should be resolved
-   * @param errorListener the error listener to which errors should be reported
-   * @return the result of resolving the URI against the URI of the library
-   */
-  static Source resolveDirective(AnalysisContext context, Source librarySource,
-      UriBasedDirective directive, AnalysisErrorListener errorListener) {
-    StringLiteral uriLiteral = directive.uri;
-    String uriContent = uriLiteral.stringValue;
-    if (uriContent != null) {
-      uriContent = uriContent.trim();
-      directive.uriContent = uriContent;
-    }
-    UriValidationCode code = directive.validate();
-    if (code == null) {
-      String encodedUriContent = Uri.encodeFull(uriContent);
-      try {
-        Source source =
-            context.sourceFactory.resolveUri(librarySource, encodedUriContent);
-        directive.source = source;
-        return source;
-      } on JavaIOException {
-        code = UriValidationCode.INVALID_URI;
-      }
-    }
-    if (code == UriValidationCode.URI_WITH_DART_EXT_SCHEME) {
-      return null;
-    }
-    if (code == UriValidationCode.URI_WITH_INTERPOLATION) {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
-      return null;
-    }
-    if (code == UriValidationCode.INVALID_URI) {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
-      return null;
-    }
-    throw new RuntimeException(
-        message: "Failed to handle validation code: $code");
-  }
-}
-
-/**
- * Instances of the class `ParseHtmlTask` parse a specific source as an HTML file.
- */
-class ParseHtmlTask extends AnalysisTask {
-  /**
-   * The name of the 'src' attribute in a HTML tag.
-   */
-  static String _ATTRIBUTE_SRC = "src";
-
-  /**
-   * The name of the 'script' tag in an HTML file.
-   */
-  static String _TAG_SCRIPT = "script";
-
-  /**
-   * The source to be parsed.
-   */
-  final Source source;
-
-  /**
-   * The contents of the source.
-   */
-  final String _content;
-
-  /**
-   * The line information that was produced.
-   */
-  LineInfo _lineInfo;
-
-  /**
-   * The HTML unit that was produced by parsing the source.
-   */
-  ht.HtmlUnit _unit;
-
-  /**
-   * The errors that were produced by scanning and parsing the source.
-   */
-  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
-  /**
-   * A list containing the sources of the libraries that are referenced within the HTML.
-   */
-  List<Source> _referencedLibraries = Source.EMPTY_LIST;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param content the contents of the source
-   */
-  ParseHtmlTask(InternalAnalysisContext context, this.source, this._content)
-      : super(context);
-
-  /**
-   * Return the errors that were produced by scanning and parsing the source, or `null` if the
-   * task has not yet been performed or if an exception occurred.
-   *
-   * @return the errors that were produced by scanning and parsing the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  /**
-   * Return the HTML unit that was produced by parsing the source.
-   *
-   * @return the HTML unit that was produced by parsing the source
-   */
-  ht.HtmlUnit get htmlUnit => _unit;
-
-  /**
-   * Return the sources of libraries that are referenced in the specified HTML file.
-   *
-   * @return the sources of libraries that are referenced in the HTML file
-   */
-  List<Source> get librarySources {
-    List<Source> libraries = new List<Source>();
-    _unit.accept(new ParseHtmlTask_getLibrarySources(this, libraries));
-    if (libraries.isEmpty) {
-      return Source.EMPTY_LIST;
-    }
-    return libraries;
-  }
-
-  /**
-   * Return the line information that was produced, or `null` if the task has not yet been
-   * performed or if an exception occurred.
-   *
-   * @return the line information that was produced
-   */
-  LineInfo get lineInfo => _lineInfo;
-
-  /**
-   * Return a list containing the sources of the libraries that are referenced within the HTML.
-   *
-   * @return the sources of the libraries that are referenced within the HTML
-   */
-  List<Source> get referencedLibraries => _referencedLibraries;
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "parse as html null source";
-    }
-    return "parse as html ${source.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitParseHtmlTask(this);
-
-  @override
-  void internalPerform() {
-    try {
-      ht.AbstractScanner scanner = new ht.StringScanner(source, _content);
-      scanner.passThroughElements = <String>[_TAG_SCRIPT];
-      ht.Token token = scanner.tokenize();
-      _lineInfo = new LineInfo(scanner.lineStarts);
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      _unit = new ht.HtmlParser(source, errorListener, context.analysisOptions)
-          .parse(token, _lineInfo);
-      _unit.accept(new RecursiveXmlVisitor_ParseHtmlTask_internalPerform(
-          this, errorListener));
-      _errors = errorListener.getErrorsForSource(source);
-      _referencedLibraries = librarySources;
-    } catch (exception, stackTrace) {
-      throw new AnalysisException(
-          "Exception", new CaughtException(exception, stackTrace));
-    }
-  }
-
-  /**
-   * Resolves directives in the given [CompilationUnit].
-   */
-  void _resolveScriptDirectives(
-      CompilationUnit script, AnalysisErrorListener errorListener) {
-    if (script == null) {
-      return;
-    }
-    AnalysisContext analysisContext = context;
-    for (Directive directive in script.directives) {
-      if (directive is UriBasedDirective) {
-        ParseDartTask.resolveDirective(
-            analysisContext, source, directive, errorListener);
-      }
-    }
-  }
-}
-
-class ParseHtmlTask_getLibrarySources extends ht.RecursiveXmlVisitor<Object> {
-  final ParseHtmlTask _task;
-
-  List<Source> libraries;
-
-  ParseHtmlTask_getLibrarySources(this._task, this.libraries) : super();
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    ht.XmlAttributeNode scriptAttribute = null;
-    for (ht.XmlAttributeNode attribute in node.attributes) {
-      if (javaStringEqualsIgnoreCase(
-          attribute.name, ParseHtmlTask._ATTRIBUTE_SRC)) {
-        scriptAttribute = attribute;
-      }
-    }
-    if (scriptAttribute != null) {
-      try {
-        Uri uri = Uri.parse(scriptAttribute.text);
-        String fileName = uri.path;
-        Source librarySource =
-            _task.context.sourceFactory.resolveUri(_task.source, fileName);
-        if (_task.context.exists(librarySource)) {
-          libraries.add(librarySource);
-        }
-      } on FormatException {
-        // ignored - invalid URI reported during resolution phase
-      }
-    }
-    return super.visitHtmlScriptTagNode(node);
-  }
-}
-
-/**
- * An object that manages the partitions that can be shared between analysis
- * contexts.
- */
-class PartitionManager {
-  /**
-   * The default cache size for a Dart SDK partition.
-   */
-  static int _DEFAULT_SDK_CACHE_SIZE = 256;
-
-  /**
-   * A table mapping SDK's to the partitions used for those SDK's.
-   */
-  HashMap<DartSdk, SdkCachePartition> _sdkPartitions =
-      new HashMap<DartSdk, SdkCachePartition>();
-
-  /**
-   * Clear any cached data being maintained by this manager.
-   */
-  void clearCache() {
-    _sdkPartitions.clear();
-  }
-
-  /**
-   * Return the partition being used for the given [sdk], creating the partition
-   * if necessary.
-   */
-  SdkCachePartition forSdk(DartSdk sdk) {
-    // Call sdk.context now, because when it creates a new
-    // InternalAnalysisContext instance, it calls forSdk() again, so creates an
-    // SdkCachePartition instance.
-    // So, if we initialize context after "partition == null", we end up
-    // with two SdkCachePartition instances.
-    InternalAnalysisContext sdkContext = sdk.context;
-    // Check cache for an existing partition.
-    SdkCachePartition partition = _sdkPartitions[sdk];
-    if (partition == null) {
-      partition = new SdkCachePartition(sdkContext, _DEFAULT_SDK_CACHE_SIZE);
-      _sdkPartitions[sdk] = partition;
-    }
-    return partition;
-  }
-}
-
-/**
- * Representation of a pending computation which is based on the results of
- * analysis that may or may not have been completed.
- */
-class PendingFuture<T> {
-  /**
-   * The context in which this computation runs.
-   */
-  final AnalysisContextImpl _context;
-
-  /**
-   * The source used by this computation to compute its value.
-   */
-  final Source source;
-
-  /**
-   * The function which implements the computation.
-   */
-  final PendingFutureComputer<T> _computeValue;
-
-  /**
-   * The completer that should be completed once the computation has succeeded.
-   */
-  CancelableCompleter<T> _completer;
-
-  PendingFuture(this._context, this.source, this._computeValue) {
-    _completer = new CancelableCompleter<T>(_onCancel);
-  }
-
-  /**
-   * Retrieve the future which will be completed when this object is
-   * successfully evaluated.
-   */
-  CancelableFuture<T> get future => _completer.future;
-
-  /**
-   * Execute [_computeValue], passing it the given [sourceEntry], and complete
-   * the pending future if it's appropriate to do so.  If the pending future is
-   * completed by this call, true is returned; otherwise false is returned.
-   *
-   * Once this function has returned true, it should not be called again.
-   *
-   * Other than completing the future, this method is free of side effects.
-   * Note that any code the client has attached to the future will be executed
-   * in a microtask, so there is no danger of side effects occurring due to
-   * client callbacks.
-   */
-  bool evaluate(SourceEntry sourceEntry) {
-    assert(!_completer.isCompleted);
-    try {
-      T result = _computeValue(sourceEntry);
-      if (result == null) {
-        return false;
-      } else {
-        _completer.complete(result);
-        return true;
-      }
-    } catch (exception, stackTrace) {
-      _completer.completeError(exception, stackTrace);
-      return true;
-    }
-  }
-
-  /**
-   * No further analysis updates are expected which affect this future, so
-   * complete it with an AnalysisNotScheduledError in order to avoid
-   * deadlocking the client.
-   */
-  void forciblyComplete() {
-    try {
-      throw new AnalysisNotScheduledError();
-    } catch (exception, stackTrace) {
-      _completer.completeError(exception, stackTrace);
-    }
-  }
-
-  void _onCancel() {
-    _context._cancelFuture(this);
-  }
-}
-
-/**
  * Container with global [AnalysisContext] performance statistics.
  */
 class PerformanceStatistics {
@@ -10370,44 +2177,6 @@
   }
 }
 
-class RecursiveXmlVisitor_ParseHtmlTask_internalPerform
-    extends ht.RecursiveXmlVisitor<Object> {
-  final ParseHtmlTask ParseHtmlTask_this;
-
-  RecordingErrorListener errorListener;
-
-  RecursiveXmlVisitor_ParseHtmlTask_internalPerform(
-      this.ParseHtmlTask_this, this.errorListener)
-      : super();
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    ParseHtmlTask_this._resolveScriptDirectives(node.script, errorListener);
-    return null;
-  }
-}
-
-class RecursiveXmlVisitor_ResolveHtmlTask_internalPerform
-    extends ht.RecursiveXmlVisitor<Object> {
-  final ResolveHtmlTask ResolveHtmlTask_this;
-
-  RecordingErrorListener errorListener;
-
-  RecursiveXmlVisitor_ResolveHtmlTask_internalPerform(
-      this.ResolveHtmlTask_this, this.errorListener)
-      : super();
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    CompilationUnit script = node.script;
-    if (script != null) {
-      GenerateDartErrorsTask.validateDirectives(ResolveHtmlTask_this.context,
-          ResolveHtmlTask_this.source, script, errorListener);
-    }
-    return null;
-  }
-}
-
 /**
  * An visitor that removes any resolution information from an AST structure when
  * used to visit that structure.
@@ -10557,1257 +2326,6 @@
 }
 
 /**
- * The information produced by resolving a compilation unit as part of a
- * specific library.
- */
-class ResolutionState {
-  /**
-   * The next resolution state or `null` if none.
-   */
-  ResolutionState _nextState;
-
-  /**
-   * The source for the defining compilation unit of the library that contains
-   * this unit. If this unit is the defining compilation unit for it's library,
-   * then this will be the source for this unit.
-   */
-  Source _librarySource;
-
-  /**
-   * A table mapping descriptors to the cached results for those descriptors.
-   * If there is no entry for a given descriptor then the state is implicitly
-   * [CacheState.INVALID] and the value is implicitly the default value.
-   */
-  Map<DataDescriptor, CachedResult> resultMap =
-      new HashMap<DataDescriptor, CachedResult>();
-
-  /**
-   * Flush any AST structures being maintained by this state.
-   */
-  void flushAstStructures() {
-    _flush(DartEntry.BUILT_UNIT);
-    _flush(DartEntry.RESOLVED_UNIT);
-    if (_nextState != null) {
-      _nextState.flushAstStructures();
-    }
-  }
-
-  /**
-   * Return the state of the data represented by the given [descriptor].
-   */
-  CacheState getState(DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return CacheState.INVALID;
-    }
-    return result.state;
-  }
-
-  /**
-   * Return the value of the data represented by the given [descriptor], or
-   * `null` if the data represented by the descriptor is not valid.
-   */
-  /*<V>*/ dynamic /*V*/ getValue(DataDescriptor /*<V>*/ descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return descriptor.defaultValue;
-    }
-    return result.value;
-  }
-
-  /**
-   * Return `true` if the state of any data value is [CacheState.ERROR].
-   */
-  bool hasErrorState() {
-    for (CachedResult result in resultMap.values) {
-      if (result.state == CacheState.ERROR) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Invalidate all of the resolution information associated with the compilation unit.
-   */
-  void invalidateAllResolutionInformation() {
-    _nextState = null;
-    _librarySource = null;
-    setState(DartEntry.BUILT_UNIT, CacheState.INVALID);
-    setState(DartEntry.BUILT_ELEMENT, CacheState.INVALID);
-    setState(DartEntry.HINTS, CacheState.INVALID);
-    setState(DartEntry.LINTS, CacheState.INVALID);
-    setState(DartEntry.RESOLVED_UNIT, CacheState.INVALID);
-    setState(DartEntry.RESOLUTION_ERRORS, CacheState.INVALID);
-    setState(DartEntry.VERIFICATION_ERRORS, CacheState.INVALID);
-  }
-
-  /**
-   * Record that an exception occurred while attempting to build the element
-   * model for the source associated with this state.
-   */
-  void recordBuildElementError() {
-    setState(DartEntry.BUILT_UNIT, CacheState.ERROR);
-    setState(DartEntry.BUILT_ELEMENT, CacheState.ERROR);
-    recordResolutionError();
-  }
-
-  /**
-   * Record that an exception occurred while attempting to generate hints for
-   * the source associated with this entry. This will set the state of all
-   * verification information as being in error.
-   */
-  void recordHintError() {
-    setState(DartEntry.HINTS, CacheState.ERROR);
-  }
-
-  /**
-   * Record that an exception occurred while attempting to generate lints for
-   * the source associated with this entry. This will set the state of all
-   * verification information as being in error.
-   */
-  void recordLintError() {
-    setState(DartEntry.LINTS, CacheState.ERROR);
-  }
-
-  /**
-   * Record that an exception occurred while attempting to resolve the source
-   * associated with this state.
-   */
-  void recordResolutionError() {
-    setState(DartEntry.RESOLVED_UNIT, CacheState.ERROR);
-    setState(DartEntry.RESOLUTION_ERRORS, CacheState.ERROR);
-    recordVerificationError();
-  }
-
-  /**
-   * Record that an exception occurred while attempting to scan or parse the
-   * source associated with this entry. This will set the state of all
-   * resolution-based information as being in error.
-   */
-  void recordResolutionErrorsInAllLibraries() {
-    recordBuildElementError();
-    if (_nextState != null) {
-      _nextState.recordResolutionErrorsInAllLibraries();
-    }
-  }
-
-  /**
-   * Record that an exception occurred while attempting to generate errors and
-   * warnings for the source associated with this entry. This will set the state
-   * of all verification information as being in error.
-   */
-  void recordVerificationError() {
-    setState(DartEntry.VERIFICATION_ERRORS, CacheState.ERROR);
-    recordHintError();
-  }
-
-  /**
-   * Set the state of the data represented by the given [descriptor] to the
-   * given [state].
-   */
-  void setState(DataDescriptor descriptor, CacheState state) {
-    if (state == CacheState.VALID) {
-      throw new ArgumentError("use setValue() to set the state to VALID");
-    }
-    if (state == CacheState.INVALID) {
-      resultMap.remove(descriptor);
-    } else {
-      CachedResult result =
-          resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-      result.state = state;
-      if (state != CacheState.IN_PROCESS) {
-        //
-        // If the state is in-process, we can leave the current value in the
-        // cache for any 'get' methods to access.
-        //
-        result.value = descriptor.defaultValue;
-      }
-    }
-  }
-
-  /**
-   * Set the value of the data represented by the given [descriptor] to the
-   * given [value].
-   */
-  void setValue(DataDescriptor /*<V>*/ descriptor, dynamic /*V*/ value) {
-    CachedResult result =
-        resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-    SourceEntry.countTransition(descriptor, result);
-    result.state = CacheState.VALID;
-    result.value = value == null ? descriptor.defaultValue : value;
-  }
-
-  /**
-   * Flush the value of the data described by the [descriptor].
-   */
-  void _flush(DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result != null && result.state == CacheState.VALID) {
-      result.state = CacheState.FLUSHED;
-      result.value = descriptor.defaultValue;
-    }
-  }
-
-  /**
-   * Write a textual representation of the difference between the old entry and
-   * this entry to the given string [buffer]. A separator will be written before
-   * the first difference if [needsSeparator] is `true`. The [oldEntry] is the
-   * entry that was replaced by this entry. Return `true` is a separator is
-   * needed before writing any subsequent differences.
-   */
-  bool _writeDiffOn(
-      StringBuffer buffer, bool needsSeparator, DartEntry oldEntry) {
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator, "resolvedUnit",
-        DartEntry.RESOLVED_UNIT, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "resolutionErrors", DartEntry.RESOLUTION_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(buffer, needsSeparator,
-        "verificationErrors", DartEntry.VERIFICATION_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "hints", DartEntry.HINTS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "lints", DartEntry.LINTS, oldEntry);
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of this state to the given [buffer]. The
-   * result will only be used for debugging purposes.
-   */
-  void _writeOn(StringBuffer buffer) {
-    if (_librarySource != null) {
-      _writeStateOn(buffer, "builtElement", DartEntry.BUILT_ELEMENT);
-      _writeStateOn(buffer, "builtUnit", DartEntry.BUILT_UNIT);
-      _writeStateOn(buffer, "resolvedUnit", DartEntry.RESOLVED_UNIT);
-      _writeStateOn(buffer, "resolutionErrors", DartEntry.RESOLUTION_ERRORS);
-      _writeStateOn(
-          buffer, "verificationErrors", DartEntry.VERIFICATION_ERRORS);
-      _writeStateOn(buffer, "hints", DartEntry.HINTS);
-      _writeStateOn(buffer, "lints", DartEntry.LINTS);
-      if (_nextState != null) {
-        _nextState._writeOn(buffer);
-      }
-    }
-  }
-
-  /**
-   * Write a textual representation of the difference between the state of the
-   * value described by the given [descriptor] between the [oldEntry] and this
-   * entry to the given [buffer]. Return `true` if some difference was written.
-   */
-  bool _writeStateDiffOn(StringBuffer buffer, bool needsSeparator, String label,
-      DataDescriptor descriptor, SourceEntry oldEntry) {
-    CacheState oldState = oldEntry.getState(descriptor);
-    CacheState newState = getState(descriptor);
-    if (oldState != newState) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write(label);
-      buffer.write(" = ");
-      buffer.write(oldState);
-      buffer.write(" -> ");
-      buffer.write(newState);
-      return true;
-    }
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of the state of the value described by the
-   * given [descriptor] to the given bugger, prefixed by the given [label] to
-   * the given [buffer].
-   */
-  void _writeStateOn(
-      StringBuffer buffer, String label, DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    buffer.write("; ");
-    buffer.write(label);
-    buffer.write(" = ");
-    buffer.write(result == null ? CacheState.INVALID : result.state);
-  }
-}
-
-/**
- * A compilation unit that is not referenced by any other objects. It is used by
- * the [LibraryResolver] to resolve a library.
- */
-class ResolvableCompilationUnit {
-  /**
-   * The source of the compilation unit.
-   */
-  final Source source;
-
-  /**
-   * The compilation unit.
-   */
-  final CompilationUnit compilationUnit;
-
-  /**
-   * Initialize a newly created holder to hold the given [source] and
-   * [compilationUnit].
-   */
-  ResolvableCompilationUnit(this.source, this.compilationUnit);
-}
-
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific Dart library.
- */
-class ResolveDartLibraryCycleTask extends AnalysisTask {
-  /**
-   * The source representing the file whose compilation unit is to be returned. TODO(brianwilkerson)
-   * This should probably be removed, but is being left in for now to ease the transition.
-   */
-  final Source unitSource;
-
-  /**
-   * The source representing the library to be resolved.
-   */
-  final Source librarySource;
-
-  /**
-   * The libraries that are part of the cycle containing the library to be resolved.
-   */
-  final List<ResolvableLibrary> _librariesInCycle;
-
-  /**
-   * The library resolver holding information about the libraries that were resolved.
-   */
-  LibraryResolver2 _resolver;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param unitSource the source representing the file whose compilation unit is to be returned
-   * @param librarySource the source representing the library to be resolved
-   * @param librariesInCycle the libraries that are part of the cycle containing the library to be
-   *          resolved
-   */
-  ResolveDartLibraryCycleTask(InternalAnalysisContext context, this.unitSource,
-      this.librarySource, this._librariesInCycle)
-      : super(context);
-
-  /**
-   * Return the library resolver holding information about the libraries that were resolved.
-   *
-   * @return the library resolver holding information about the libraries that were resolved
-   */
-  LibraryResolver2 get libraryResolver => _resolver;
-
-  @override
-  String get taskDescription {
-    if (librarySource == null) {
-      return "resolve library null source";
-    }
-    return "resolve library ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitResolveDartLibraryCycleTask(this);
-
-  @override
-  void internalPerform() {
-    _resolver = new LibraryResolver2(context);
-    _resolver.resolveLibrary(librarySource, _librariesInCycle);
-  }
-}
-
-/**
- * Instances of the class `ResolveDartLibraryTask` resolve a specific Dart library.
- */
-class ResolveDartLibraryTask extends AnalysisTask {
-  /**
-   * The source representing the file whose compilation unit is to be returned.
-   */
-  final Source unitSource;
-
-  /**
-   * The source representing the library to be resolved.
-   */
-  final Source librarySource;
-
-  /**
-   * The library resolver holding information about the libraries that were resolved.
-   */
-  LibraryResolver _resolver;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param unitSource the source representing the file whose compilation unit is to be returned
-   * @param librarySource the source representing the library to be resolved
-   */
-  ResolveDartLibraryTask(
-      InternalAnalysisContext context, this.unitSource, this.librarySource)
-      : super(context);
-
-  /**
-   * Return the library resolver holding information about the libraries that were resolved.
-   *
-   * @return the library resolver holding information about the libraries that were resolved
-   */
-  LibraryResolver get libraryResolver => _resolver;
-
-  @override
-  String get taskDescription {
-    if (librarySource == null) {
-      return "resolve library null source";
-    }
-    return "resolve library ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) =>
-      visitor.visitResolveDartLibraryTask(this);
-
-  @override
-  void internalPerform() {
-    LibraryResolverFactory resolverFactory = context.libraryResolverFactory;
-    _resolver = resolverFactory == null
-        ? new LibraryResolver(context)
-        : resolverFactory(context);
-    _resolver.resolveLibrary(librarySource, true);
-  }
-}
-
-/**
- * Instances of the class `ResolveDartUnitTask` resolve a single Dart file based on a existing
- * element model.
- */
-class ResolveDartUnitTask extends AnalysisTask {
-  /**
-   * The source that is to be resolved.
-   */
-  final Source source;
-
-  /**
-   * The element model for the library containing the source.
-   */
-  final LibraryElement _libraryElement;
-
-  /**
-   * The compilation unit that was resolved by this task.
-   */
-  CompilationUnit _resolvedUnit;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param libraryElement the element model for the library containing the source
-   */
-  ResolveDartUnitTask(
-      InternalAnalysisContext context, this.source, this._libraryElement)
-      : super(context);
-
-  /**
-   * Return the source for the library containing the source that is to be resolved.
-   *
-   * @return the source for the library containing the source that is to be resolved
-   */
-  Source get librarySource => _libraryElement.source;
-
-  /**
-   * Return the compilation unit that was resolved by this task.
-   *
-   * @return the compilation unit that was resolved by this task
-   */
-  CompilationUnit get resolvedUnit => _resolvedUnit;
-
-  @override
-  String get taskDescription {
-    Source librarySource = _libraryElement.source;
-    if (librarySource == null) {
-      return "resolve unit null source";
-    }
-    return "resolve unit ${librarySource.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitResolveDartUnitTask(this);
-
-  @override
-  void internalPerform() {
-    TypeProvider typeProvider = _libraryElement.context.typeProvider;
-    CompilationUnit unit = context.computeResolvableCompilationUnit(source);
-    if (unit == null) {
-      throw new AnalysisException(
-          "Internal error: computeResolvableCompilationUnit returned a value without a parsed Dart unit");
-    }
-    //
-    // Resolve names in declarations.
-    //
-    new DeclarationResolver().resolve(unit, _find(_libraryElement, source));
-    //
-    // Resolve the type names.
-    //
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-    TypeResolverVisitor typeResolverVisitor = new TypeResolverVisitor(
-        _libraryElement, source, typeProvider, errorListener);
-    unit.accept(typeResolverVisitor);
-    //
-    // Resolve the rest of the structure
-    //
-    InheritanceManager inheritanceManager =
-        new InheritanceManager(_libraryElement);
-    ResolverVisitor resolverVisitor = new ResolverVisitor(
-        _libraryElement, source, typeProvider, errorListener,
-        inheritanceManager: inheritanceManager);
-    unit.accept(resolverVisitor);
-    //
-    // Perform additional error checking.
-    //
-    PerformanceStatistics.errors.makeCurrentWhile(() {
-      ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
-      ErrorVerifier errorVerifier = new ErrorVerifier(
-          errorReporter,
-          _libraryElement,
-          typeProvider,
-          inheritanceManager,
-          context.analysisOptions.enableSuperMixins);
-      unit.accept(errorVerifier);
-      // TODO(paulberry): as a temporary workaround for issue 21572,
-      // ConstantVerifier is being run right after ConstantValueComputer, so we
-      // don't need to run it here.  Once issue 21572 is fixed, re-enable the
-      // call to ConstantVerifier.
-//       ConstantVerifier constantVerifier = new ConstantVerifier(errorReporter, _libraryElement, typeProvider);
-//       unit.accept(constantVerifier);
-    });
-    //
-    // Capture the results.
-    //
-    _resolvedUnit = unit;
-  }
-
-  /**
-   * Search the compilation units that are part of the given library and return the element
-   * representing the compilation unit with the given source. Return `null` if there is no
-   * such compilation unit.
-   *
-   * @param libraryElement the element representing the library being searched through
-   * @param unitSource the source for the compilation unit whose element is to be returned
-   * @return the element representing the compilation unit
-   */
-  CompilationUnitElement _find(
-      LibraryElement libraryElement, Source unitSource) {
-    CompilationUnitElement element = libraryElement.definingCompilationUnit;
-    if (element.source == unitSource) {
-      return element;
-    }
-    for (CompilationUnitElement partElement in libraryElement.parts) {
-      if (partElement.source == unitSource) {
-        return partElement;
-      }
-    }
-    return null;
-  }
-}
-
-/**
- * Instances of the class `ResolveHtmlTask` resolve a specific source as an HTML file.
- */
-class ResolveHtmlTask extends AnalysisTask {
-  /**
-   * The source to be resolved.
-   */
-  final Source source;
-
-  /**
-   * The time at which the contents of the source were last modified.
-   */
-  final int modificationTime;
-
-  /**
-   * The HTML unit to be resolved.
-   */
-  final ht.HtmlUnit _unit;
-
-  /**
-   * The [HtmlUnit] that was resolved by this task.
-   */
-  ht.HtmlUnit _resolvedUnit;
-
-  /**
-   * The element produced by resolving the source.
-   */
-  HtmlElement _element = null;
-
-  /**
-   * The resolution errors that were discovered while resolving the source.
-   */
-  List<AnalysisError> _resolutionErrors = AnalysisError.NO_ERRORS;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be resolved
-   * @param modificationTime the time at which the contents of the source were last modified
-   * @param unit the HTML unit to be resolved
-   */
-  ResolveHtmlTask(InternalAnalysisContext context, this.source,
-      this.modificationTime, this._unit)
-      : super(context);
-
-  HtmlElement get element => _element;
-
-  List<AnalysisError> get resolutionErrors => _resolutionErrors;
-
-  /**
-   * Return the [HtmlUnit] that was resolved by this task.
-   *
-   * @return the [HtmlUnit] that was resolved by this task
-   */
-  ht.HtmlUnit get resolvedUnit => _resolvedUnit;
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "resolve as html null source";
-    }
-    return "resolve as html ${source.fullName}";
-  }
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitResolveHtmlTask(this);
-
-  @override
-  void internalPerform() {
-    //
-    // Build the standard HTML element.
-    //
-    HtmlUnitBuilder builder = new HtmlUnitBuilder(context);
-    _element = builder.buildHtmlElement(source, _unit);
-    RecordingErrorListener errorListener = builder.errorListener;
-    //
-    // Validate the directives
-    //
-    _unit.accept(new RecursiveXmlVisitor_ResolveHtmlTask_internalPerform(
-        this, errorListener));
-    //
-    // Record all resolution errors.
-    //
-    _resolutionErrors = errorListener.getErrorsForSource(source);
-    //
-    // Remember the resolved unit.
-    //
-    _resolvedUnit = _unit;
-  }
-}
-
-/**
- * The priority of data in the cache in terms of the desirability of retaining
- * some specified data about a specified source.
- */
-class RetentionPriority extends Enum<RetentionPriority> {
-  /**
-   * A priority indicating that a given piece of data can be removed from the
-   * cache without reservation.
-   */
-  static const RetentionPriority LOW = const RetentionPriority('LOW', 0);
-
-  /**
-   * A priority indicating that a given piece of data should not be removed from
-   * the cache unless there are no sources for which the corresponding data has
-   * a lower priority. Currently used for data that is needed in order to finish
-   * some outstanding analysis task.
-   */
-  static const RetentionPriority MEDIUM = const RetentionPriority('MEDIUM', 1);
-
-  /**
-   * A priority indicating that a given piece of data should not be removed from
-   * the cache. Currently used for data related to a priority source.
-   */
-  static const RetentionPriority HIGH = const RetentionPriority('HIGH', 2);
-
-  static const List<RetentionPriority> values = const [LOW, MEDIUM, HIGH];
-
-  const RetentionPriority(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
- * Instances of the class `ScanDartTask` scan a specific source as a Dart file.
- */
-class ScanDartTask extends AnalysisTask {
-  /**
-   * The source to be scanned.
-   */
-  final Source source;
-
-  /**
-   * The contents of the source.
-   */
-  final String _content;
-
-  /**
-   * The token stream that was produced by scanning the source.
-   */
-  Token _tokenStream;
-
-  /**
-   * The line information that was produced.
-   */
-  LineInfo _lineInfo;
-
-  /**
-   * The errors that were produced by scanning the source.
-   */
-  List<AnalysisError> _errors = AnalysisError.NO_ERRORS;
-
-  /**
-   * Initialize a newly created task to perform analysis within the given context.
-   *
-   * @param context the context in which the task is to be performed
-   * @param source the source to be parsed
-   * @param content the contents of the source
-   */
-  ScanDartTask(InternalAnalysisContext context, this.source, this._content)
-      : super(context);
-
-  /**
-   * Return the errors that were produced by scanning the source, or `null` if the task has
-   * not yet been performed or if an exception occurred.
-   *
-   * @return the errors that were produced by scanning the source
-   */
-  List<AnalysisError> get errors => _errors;
-
-  /**
-   * Return the line information that was produced, or `null` if the task has not yet been
-   * performed or if an exception occurred.
-   *
-   * @return the line information that was produced
-   */
-  LineInfo get lineInfo => _lineInfo;
-
-  @override
-  String get taskDescription {
-    if (source == null) {
-      return "scan as dart null source";
-    }
-    return "scan as dart ${source.fullName}";
-  }
-
-  /**
-   * Return the token stream that was produced by scanning the source, or `null` if the task
-   * has not yet been performed or if an exception occurred.
-   *
-   * @return the token stream that was produced by scanning the source
-   */
-  Token get tokenStream => _tokenStream;
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => visitor.visitScanDartTask(this);
-
-  @override
-  void internalPerform() {
-    PerformanceStatistics.scan.makeCurrentWhile(() {
-      RecordingErrorListener errorListener = new RecordingErrorListener();
-      try {
-        Scanner scanner = new Scanner(
-            source, new CharSequenceReader(_content), errorListener);
-        scanner.preserveComments = context.analysisOptions.preserveComments;
-        _tokenStream = scanner.tokenize();
-        _lineInfo = new LineInfo(scanner.lineStarts);
-        _errors = errorListener.getErrorsForSource(source);
-      } catch (exception, stackTrace) {
-        throw new AnalysisException(
-            "Exception", new CaughtException(exception, stackTrace));
-      }
-    });
-  }
-}
-
-/**
- * An [AnalysisContext] that only contains sources for a Dart SDK.
- */
-class SdkAnalysisContext extends AnalysisContextImpl {
-  @override
-  AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
-    if (factory == null) {
-      return super.createCacheFromSourceFactory(factory);
-    }
-    DartSdk sdk = factory.dartSdk;
-    if (sdk == null) {
-      throw new IllegalArgumentException(
-          "The source factory for an SDK analysis context must have a DartUriResolver");
-    }
-    return new AnalysisCache(
-        <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
-  }
-}
-
-/**
- * A cache partition that contains all of the sources in the SDK.
- */
-class SdkCachePartition extends CachePartition {
-  /**
-   * Initialize a newly created partition. The [context] is the context that
-   * owns this partition. The [maxCacheSize] is the maximum number of sources
-   * for which AST structures should be kept in the cache.
-   */
-  SdkCachePartition(InternalAnalysisContext context, int maxCacheSize)
-      : super(context, maxCacheSize, DefaultRetentionPolicy.POLICY);
-
-  @override
-  bool contains(Source source) => source.isInSystemLibrary;
-}
-
-/**
- * The information cached by an analysis context about an individual source, no
- * matter what kind of source it is.
- */
-abstract class SourceEntry {
-  /**
-   * The data descriptor representing the contents of the source.
-   */
-  static final DataDescriptor<String> CONTENT =
-      new DataDescriptor<String>("SourceEntry.CONTENT");
-
-  /**
-   * The data descriptor representing the errors resulting from reading the
-   * source content.
-   */
-  static final DataDescriptor<List<AnalysisError>> CONTENT_ERRORS =
-      new DataDescriptor<List<AnalysisError>>(
-          "SourceEntry.CONTENT_ERRORS", AnalysisError.NO_ERRORS);
-
-  /**
-   * The data descriptor representing the line information.
-   */
-  static final DataDescriptor<LineInfo> LINE_INFO =
-      new DataDescriptor<LineInfo>("SourceEntry.LINE_INFO");
-
-  /**
-   * The index of the flag indicating whether the source was explicitly added to
-   * the context or whether the source was implicitly added because it was
-   * referenced by another source.
-   */
-  static int _EXPLICITLY_ADDED_FLAG = 0;
-
-  /**
-   * A table mapping data descriptors to a count of the number of times a value
-   * was set when in a given state.
-   */
-  static final Map<DataDescriptor, Map<CacheState, int>> transitionMap =
-      new HashMap<DataDescriptor, Map<CacheState, int>>();
-
-  /**
-   * The most recent time at which the state of the source matched the state
-   * represented by this entry.
-   */
-  int modificationTime = 0;
-
-  /**
-   * The exception that caused one or more values to have a state of
-   * [CacheState.ERROR].
-   */
-  CaughtException exception;
-
-  /**
-   * A bit-encoding of boolean flags associated with this element.
-   */
-  int _flags = 0;
-
-  /**
-   * A table mapping data descriptors to the cached results for those
-   * descriptors.
-   */
-  Map<DataDescriptor, CachedResult> resultMap =
-      new HashMap<DataDescriptor, CachedResult>();
-
-  /**
-   * Return all of the errors associated with this entry.
-   */
-  List<AnalysisError> get allErrors {
-    return getValue(CONTENT_ERRORS);
-  }
-
-  /**
-   * Get a list of all the library-independent descriptors for which values may
-   * be stored in this SourceEntry.
-   */
-  List<DataDescriptor> get descriptors {
-    return <DataDescriptor>[CONTENT, CONTENT_ERRORS, LINE_INFO];
-  }
-
-  /**
-   * Return `true` if the source was explicitly added to the context or `false`
-   * if the source was implicitly added because it was referenced by another
-   * source.
-   */
-  bool get explicitlyAdded => _getFlag(_EXPLICITLY_ADDED_FLAG);
-
-  /**
-   * Set whether the source was explicitly added to the context to match the
-   * [explicitlyAdded] flag.
-   */
-  void set explicitlyAdded(bool explicitlyAdded) {
-    _setFlag(_EXPLICITLY_ADDED_FLAG, explicitlyAdded);
-  }
-
-  /**
-   * Return the kind of the source, or `null` if the kind is not currently
-   * cached.
-   */
-  SourceKind get kind;
-
-  /**
-   * Fix the state of the [exception] to match the current state of the entry.
-   */
-  void fixExceptionState() {
-    if (hasErrorState()) {
-      if (exception == null) {
-        //
-        // This code should never be reached, but is a fail-safe in case an
-        // exception is not recorded when it should be.
-        //
-        String message = "State set to ERROR without setting an exception";
-        exception = new CaughtException(new AnalysisException(message), null);
-      }
-    } else {
-      exception = null;
-    }
-  }
-
-  /**
-   * Return a textual representation of the difference between the [oldEntry]
-   * and this entry. The difference is represented as a sequence of fields whose
-   * value would change if the old entry were converted into the new entry.
-   */
-  String getDiff(SourceEntry oldEntry) {
-    StringBuffer buffer = new StringBuffer();
-    _writeDiffOn(buffer, oldEntry);
-    return buffer.toString();
-  }
-
-  /**
-   * Return the state of the data represented by the given [descriptor].
-   */
-  CacheState getState(DataDescriptor descriptor) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return CacheState.INVALID;
-    }
-    return result.state;
-  }
-
-  /**
-   * Return the value of the data represented by the given [descriptor], or
-   * `null` if the data represented by the descriptor is not valid.
-   */
-  /*<V>*/ dynamic /*V*/ getValue(DataDescriptor /*<V>*/ descriptor) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    CachedResult result = resultMap[descriptor];
-    if (result == null) {
-      return descriptor.defaultValue;
-    }
-    return result.value;
-  }
-
-  /**
-   * Return `true` if the state of any data value is [CacheState.ERROR].
-   */
-  bool hasErrorState() {
-    for (CachedResult result in resultMap.values) {
-      if (result.state == CacheState.ERROR) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Invalidate all of the information associated with this source.
-   */
-  void invalidateAllInformation() {
-    setState(CONTENT, CacheState.INVALID);
-    setState(CONTENT_ERRORS, CacheState.INVALID);
-    setState(LINE_INFO, CacheState.INVALID);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to get the contents of
-   * the source represented by this entry. This will set the state of all
-   * information, including any resolution-based information, as being in error.
-   */
-  void recordContentError(CaughtException exception) {
-    setState(CONTENT, CacheState.ERROR);
-    recordScanError(exception);
-  }
-
-  /**
-   * Record that an [exception] occurred while attempting to scan or parse the
-   * entry represented by this entry. This will set the state of all
-   * information, including any resolution-based information, as being in error.
-   */
-  void recordScanError(CaughtException exception) {
-    this.exception = exception;
-    setState(LINE_INFO, CacheState.ERROR);
-  }
-
-  /**
-   * Set the state of the data represented by the given [descriptor] to the
-   * given [state].
-   */
-  void setState(DataDescriptor descriptor, CacheState state) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    if (state == CacheState.VALID) {
-      throw new ArgumentError("use setValue() to set the state to VALID");
-    }
-    _validateStateChange(descriptor, state);
-    if (state == CacheState.INVALID) {
-      resultMap.remove(descriptor);
-    } else {
-      CachedResult result =
-          resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-      result.state = state;
-      if (state != CacheState.IN_PROCESS) {
-        //
-        // If the state is in-process, we can leave the current value in the
-        // cache for any 'get' methods to access.
-        //
-        result.value = descriptor.defaultValue;
-      }
-    }
-  }
-
-  /**
-   * Set the value of the data represented by the given [descriptor] to the
-   * given [value].
-   */
-  void setValue(DataDescriptor /*<V>*/ descriptor, dynamic /*V*/ value) {
-    if (!_isValidDescriptor(descriptor)) {
-      throw new ArgumentError("Invalid descriptor: $descriptor");
-    }
-    _validateStateChange(descriptor, CacheState.VALID);
-    CachedResult result =
-        resultMap.putIfAbsent(descriptor, () => new CachedResult(descriptor));
-    countTransition(descriptor, result);
-    result.state = CacheState.VALID;
-    result.value = value == null ? descriptor.defaultValue : value;
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    _writeOn(buffer);
-    return buffer.toString();
-  }
-
-  /**
-   * Flush the value of the data described by the [descriptor].
-   */
-  void _flush(DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    if (result != null && result.state == CacheState.VALID) {
-      _validateStateChange(descriptor, CacheState.FLUSHED);
-      result.state = CacheState.FLUSHED;
-      result.value = descriptor.defaultValue;
-    }
-  }
-
-  /**
-   * Return the value of the flag with the given [index].
-   */
-  bool _getFlag(int index) => BooleanArray.get(_flags, index);
-
-  /**
-   * Return `true` if the [descriptor] is valid for this entry.
-   */
-  bool _isValidDescriptor(DataDescriptor descriptor) {
-    return descriptor == CONTENT ||
-        descriptor == CONTENT_ERRORS ||
-        descriptor == LINE_INFO;
-  }
-
-  /**
-   * Set the value of the flag with the given [index] to the given [value].
-   */
-  void _setFlag(int index, bool value) {
-    _flags = BooleanArray.set(_flags, index, value);
-  }
-
-  /**
-   * If the state of the value described by the given [descriptor] is changing
-   * from ERROR to anything else, capture the information. This is an attempt to
-   * discover the underlying cause of a long-standing bug.
-   */
-  void _validateStateChange(DataDescriptor descriptor, CacheState newState) {
-    // TODO(brianwilkerson) Decide whether we still want to capture this data.
-//    if (descriptor != CONTENT) {
-//      return;
-//    }
-//    CachedResult result = resultMap[CONTENT];
-//    if (result != null && result.state == CacheState.ERROR) {
-//      String message =
-//          "contentState changing from ${result.state} to $newState";
-//      InstrumentationBuilder builder =
-//          Instrumentation.builder2("SourceEntry-validateStateChange");
-//      builder.data3("message", message);
-//      //builder.data("source", source.getFullName());
-//      builder.record(new CaughtException(new AnalysisException(message), null));
-//      builder.log();
-//    }
-  }
-
-  /**
-   * Write a textual representation of the difference between the [oldEntry] and
-   * this entry to the given string [buffer]. Return `true` if some difference
-   * was written.
-   */
-  bool _writeDiffOn(StringBuffer buffer, SourceEntry oldEntry) {
-    bool needsSeparator = false;
-    CaughtException oldException = oldEntry.exception;
-    if (!identical(oldException, exception)) {
-      buffer.write("exception = ");
-      buffer.write(oldException.runtimeType);
-      buffer.write(" -> ");
-      buffer.write(exception.runtimeType);
-      needsSeparator = true;
-    }
-    int oldModificationTime = oldEntry.modificationTime;
-    if (oldModificationTime != modificationTime) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write("time = ");
-      buffer.write(oldModificationTime);
-      buffer.write(" -> ");
-      buffer.write(modificationTime);
-      needsSeparator = true;
-    }
-    needsSeparator =
-        _writeStateDiffOn(buffer, needsSeparator, "content", CONTENT, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "contentErrors", CONTENT_ERRORS, oldEntry);
-    needsSeparator = _writeStateDiffOn(
-        buffer, needsSeparator, "lineInfo", LINE_INFO, oldEntry);
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of this entry to the given [buffer]. The
-   * result should only be used for debugging purposes.
-   */
-  void _writeOn(StringBuffer buffer) {
-    buffer.write("time = ");
-    buffer.write(modificationTime);
-    _writeStateOn(buffer, "content", CONTENT);
-    _writeStateOn(buffer, "contentErrors", CONTENT_ERRORS);
-    _writeStateOn(buffer, "lineInfo", LINE_INFO);
-  }
-
-  /**
-   * Write a textual representation of the difference between the state of the
-   * value described by the given [descriptor] between the [oldEntry] and this
-   * entry to the given [buffer]. Return `true` if some difference was written.
-   */
-  bool _writeStateDiffOn(StringBuffer buffer, bool needsSeparator, String label,
-      DataDescriptor descriptor, SourceEntry oldEntry) {
-    CacheState oldState = oldEntry.getState(descriptor);
-    CacheState newState = getState(descriptor);
-    if (oldState != newState) {
-      if (needsSeparator) {
-        buffer.write("; ");
-      }
-      buffer.write(label);
-      buffer.write(" = ");
-      buffer.write(oldState);
-      buffer.write(" -> ");
-      buffer.write(newState);
-      return true;
-    }
-    return needsSeparator;
-  }
-
-  /**
-   * Write a textual representation of the state of the value described by the
-   * given [descriptor] to the given bugger, prefixed by the given [label] to
-   * the given [buffer].
-   */
-  void _writeStateOn(
-      StringBuffer buffer, String label, DataDescriptor descriptor) {
-    CachedResult result = resultMap[descriptor];
-    buffer.write("; ");
-    buffer.write(label);
-    buffer.write(" = ");
-    buffer.write(result == null ? CacheState.INVALID : result.state);
-  }
-
-  /**
-   * Increment the count of the number of times that data represented by the
-   * given [descriptor] was transitioned from the current state (as found in the
-   * given [result] to a valid state.
-   */
-  static void countTransition(DataDescriptor descriptor, CachedResult result) {
-    Map<CacheState, int> countMap = transitionMap.putIfAbsent(
-        descriptor, () => new HashMap<CacheState, int>());
-    int count = countMap[result.state];
-    countMap[result.state] = count == null ? 1 : count + 1;
-  }
-}
-
-/**
- * The priority levels used to return sources in an optimal order. A smaller
- * ordinal value equates to a higher priority.
- */
-class SourcePriority extends Enum<SourcePriority> {
-  /**
-   * Used for a Dart source that is known to be a part contained in a library
-   * that was recently resolved. These parts are given a higher priority because
-   * there is a high probability that their AST structure is still in the cache
-   * and therefore would not need to be re-created.
-   */
-  static const SourcePriority PRIORITY_PART =
-      const SourcePriority('PRIORITY_PART', 0);
-
-  /**
-   * Used for a Dart source that is known to be a library.
-   */
-  static const SourcePriority LIBRARY = const SourcePriority('LIBRARY', 1);
-
-  /**
-   * Used for a Dart source whose kind is unknown.
-   */
-  static const SourcePriority UNKNOWN = const SourcePriority('UNKNOWN', 2);
-
-  /**
-   * Used for a Dart source that is known to be a part but whose library has not
-   * yet been resolved.
-   */
-  static const SourcePriority NORMAL_PART =
-      const SourcePriority('NORMAL_PART', 3);
-
-  /**
-   * Used for an HTML source.
-   */
-  static const SourcePriority HTML = const SourcePriority('HTML', 4);
-
-  static const List<SourcePriority> values = const [
-    PRIORITY_PART,
-    LIBRARY,
-    UNKNOWN,
-    NORMAL_PART,
-    HTML
-  ];
-
-  const SourcePriority(String name, int ordinal) : super(name, ordinal);
-}
-
-/**
  * [SourcesChangedEvent] indicates which sources have been added, removed,
  * or whose contents have changed.
  */
@@ -11862,8 +2380,8 @@
    */
   bool get wereSourcesRemovedOrDeleted =>
       _changeSet.removedSources.length > 0 ||
-          _changeSet.removedContainers.length > 0 ||
-          _changeSet.deletedSources.length > 0;
+      _changeSet.removedContainers.length > 0 ||
+      _changeSet.deletedSources.length > 0;
 }
 
 /**
@@ -11886,280 +2404,3 @@
    */
   TimestampedData(this.modificationTime, this.data);
 }
-
-/**
- * A cache partition that contains all sources not contained in other
- * partitions.
- */
-class UniversalCachePartition extends CachePartition {
-  /**
-   * Initialize a newly created partition. The [context] is the context that
-   * owns this partition. The [maxCacheSize] is the maximum number of sources
-   * for which AST structures should be kept in the cache. The [retentionPolicy]
-   * is the policy used to determine which pieces of data to remove from the
-   * cache.
-   */
-  UniversalCachePartition(InternalAnalysisContext context, int maxCacheSize,
-      CacheRetentionPolicy retentionPolicy)
-      : super(context, maxCacheSize, retentionPolicy);
-
-  @override
-  bool contains(Source source) => true;
-}
-
-/**
- * The unique instances of the class `WaitForAsyncTask` represents a state in which there is
- * no analysis work that can be done until some asynchronous task (such as IO) has completed, but
- * where analysis is not yet complete.
- */
-class WaitForAsyncTask extends AnalysisTask {
-  /**
-   * The unique instance of this class.
-   */
-  static WaitForAsyncTask _UniqueInstance = new WaitForAsyncTask();
-
-  /**
-   * Return the unique instance of this class.
-   *
-   * @return the unique instance of this class
-   */
-  static WaitForAsyncTask get instance => _UniqueInstance;
-
-  /**
-   * Prevent the creation of instances of this class.
-   */
-  WaitForAsyncTask() : super(null);
-
-  @override
-  String get taskDescription => "Waiting for async analysis";
-
-  @override
-  accept(AnalysisTaskVisitor visitor) => null;
-
-  @override
-  void internalPerform() {
-    // There is no work to be done.
-  }
-}
-
-/**
- * An object that manages a list of sources that need to have analysis work
- * performed on them.
- */
-class WorkManager {
-  /**
-   * A list containing the various queues is priority order.
-   */
-  List<List<Source>> _workQueues;
-
-  /**
-   * Initialize a newly created manager to have no work queued up.
-   */
-  WorkManager() {
-    int queueCount = SourcePriority.values.length;
-    _workQueues = new List<List<Source>>(queueCount);
-    for (int i = 0; i < queueCount; i++) {
-      _workQueues[i] = new List<Source>();
-    }
-  }
-
-  /**
-   * Record that the given [source] needs to be analyzed. The [priority] level
-   * is used to control when the source will be analyzed with respect to other
-   * sources. If the source was previously added then it's priority is updated.
-   * If it was previously added with the same priority then it's position in the
-   * queue is unchanged.
-   */
-  void add(Source source, SourcePriority priority) {
-    int queueCount = _workQueues.length;
-    int ordinal = priority.ordinal;
-    for (int i = 0; i < queueCount; i++) {
-      List<Source> queue = _workQueues[i];
-      if (i == ordinal) {
-        if (!queue.contains(source)) {
-          queue.add(source);
-        }
-      } else {
-        queue.remove(source);
-      }
-    }
-  }
-
-  /**
-   * Record that the given [source] needs to be analyzed. The [priority] level
-   * is used to control when the source will be analyzed with respect to other
-   * sources. If the source was previously added then it's priority is updated.
-   * In either case, it will be analyzed before other sources of the same
-   * priority.
-   */
-  void addFirst(Source source, SourcePriority priority) {
-    int queueCount = _workQueues.length;
-    int ordinal = priority.ordinal;
-    for (int i = 0; i < queueCount; i++) {
-      List<Source> queue = _workQueues[i];
-      if (i == ordinal) {
-        queue.remove(source);
-        queue.insert(0, source);
-      } else {
-        queue.remove(source);
-      }
-    }
-  }
-
-  /**
-   * Return an iterator that can be used to access the sources to be analyzed in
-   * the order in which they should be analyzed.
-   *
-   * <b>Note:</b> As with other iterators, no sources can be added or removed
-   * from this work manager while the iterator is being used. Unlike some
-   * implementations, however, the iterator will not detect when this
-   * requirement has been violated; it might work correctly, it might return the
-   * wrong source, or it might throw an exception.
-   */
-  WorkManager_WorkIterator iterator() => new WorkManager_WorkIterator(this);
-
-  /**
-   * Record that the given source is fully analyzed.
-   */
-  void remove(Source source) {
-    int queueCount = _workQueues.length;
-    for (int i = 0; i < queueCount; i++) {
-      _workQueues[i].remove(source);
-    }
-  }
-
-  @override
-  String toString() {
-    StringBuffer buffer = new StringBuffer();
-    List<SourcePriority> priorities = SourcePriority.values;
-    bool needsSeparator = false;
-    int queueCount = _workQueues.length;
-    for (int i = 0; i < queueCount; i++) {
-      List<Source> queue = _workQueues[i];
-      if (!queue.isEmpty) {
-        if (needsSeparator) {
-          buffer.write("; ");
-        }
-        buffer.write(priorities[i]);
-        buffer.write(": ");
-        int queueSize = queue.length;
-        for (int j = 0; j < queueSize; j++) {
-          if (j > 0) {
-            buffer.write(", ");
-          }
-          buffer.write(queue[j].fullName);
-        }
-        needsSeparator = true;
-      }
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * An iterator that returns the sources in a work manager in the order in which
- * they are to be analyzed.
- */
-class WorkManager_WorkIterator {
-  final WorkManager _manager;
-
-  /**
-   * The index of the work queue through which we are currently iterating.
-   */
-  int _queueIndex = 0;
-
-  /**
-   * The index of the next element of the work queue to be returned.
-   */
-  int _index = -1;
-
-  /**
-   * Initialize a newly created iterator to be ready to return the first element
-   * in the iteration.
-   */
-  WorkManager_WorkIterator(this._manager) {
-    _advance();
-  }
-
-  /**
-   * Return `true` if there is another [Source] available for processing.
-   */
-  bool get hasNext => _queueIndex < _manager._workQueues.length;
-
-  /**
-   * Return the next [Source] available for processing and advance so that the
-   * returned source will not be returned again.
-   */
-  Source next() {
-    if (!hasNext) {
-      throw new NoSuchElementException();
-    }
-    Source source = _manager._workQueues[_queueIndex][_index];
-    _advance();
-    return source;
-  }
-
-  /**
-   * Increment the [index] and [queueIndex] so that they are either indicating
-   * the next source to be returned or are indicating that there are no more
-   * sources to be returned.
-   */
-  void _advance() {
-    _index++;
-    if (_index >= _manager._workQueues[_queueIndex].length) {
-      _index = 0;
-      _queueIndex++;
-      while (_queueIndex < _manager._workQueues.length &&
-          _manager._workQueues[_queueIndex].isEmpty) {
-        _queueIndex++;
-      }
-    }
-  }
-}
-
-/**
- * A helper class used to create futures for AnalysisContextImpl. Using a helper
- * class allows us to preserve the generic parameter T.
- */
-class _AnalysisFutureHelper<T> {
-  final AnalysisContextImpl _context;
-
-  _AnalysisFutureHelper(this._context);
-
-  /**
-   * Return a future that will be completed with the result of calling
-   * [computeValue].  If [computeValue] returns non-null, the future will be
-   * completed immediately with the resulting value.  If it returns null, then
-   * it will be re-executed in the future, after the next time the cached
-   * information for [source] has changed.  If [computeValue] throws an
-   * exception, the future will fail with that exception.
-   *
-   * If the [computeValue] still returns null after there is no further
-   * analysis to be done for [source], then the future will be completed with
-   * the error AnalysisNotScheduledError.
-   *
-   * Since [computeValue] will be called while the state of analysis is being
-   * updated, it should be free of side effects so that it doesn't cause
-   * reentrant changes to the analysis state.
-   */
-  CancelableFuture<T> computeAsync(
-      Source source, T computeValue(SourceEntry sourceEntry)) {
-    if (_context.isDisposed) {
-      // No further analysis is expected, so return a future that completes
-      // immediately with AnalysisNotScheduledError.
-      return new CancelableFuture.error(new AnalysisNotScheduledError());
-    }
-    SourceEntry sourceEntry = _context.getReadableSourceEntryOrNull(source);
-    if (sourceEntry == null) {
-      return new CancelableFuture.error(new AnalysisNotScheduledError());
-    }
-    PendingFuture pendingFuture =
-        new PendingFuture<T>(_context, source, computeValue);
-    if (!pendingFuture.evaluate(sourceEntry)) {
-      _context._pendingFutureSources
-          .putIfAbsent(source, () => <PendingFuture>[])
-          .add(pendingFuture);
-    }
-    return pendingFuture.future;
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index f547807..621b72d 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -2,10 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.error;
+library analyzer.src.generated.error;
 
 import 'dart:collection';
 
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/ast.dart' show AstNode;
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -18,18 +19,11 @@
 import 'package:source_span/source_span.dart';
 
 /**
- * The descriptor used to associate error filters with analysis contexts in
+ * The descriptor used to associate error processors with analysis contexts in
  * configuration data.
  */
-final ListResultDescriptor<List<ErrorFilter>> CONFIGURED_ERROR_FILTERS =
-    new ListResultDescriptorImpl('configured.errors', const <ErrorFilter>[]);
-
-/**
- * A predicate used to potentially filter an [error].
- *
- * Returns `true` if this error should be filtered from analysis results.
- */
-typedef bool ErrorFilter(AnalysisError error);
+final ListResultDescriptor<List<ErrorProcessor>> CONFIGURED_ERROR_PROCESSORS =
+    new ListResultDescriptorImpl('configured.errors', const <ErrorProcessor>[]);
 
 /**
  * An error discovered during the analysis of some Dart code.
@@ -124,27 +118,6 @@
   }
 
   /**
-   * Initialize a newly created analysis error for the specified [source]. The
-   * error will have the given [errorCode] and the list of [arguments] will be
-   * used to complete the message. The error has no location information.
-   */
-  @deprecated // Use new AnalysisError(source, 0, 0, errorCode, arguments)
-  AnalysisError.con1(Source source, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, 0, 0, errorCode, arguments);
-
-  /**
-   * Initialize a newly created analysis error for the specified [source] at the
-   * given [offset] with the given [length]. The error will have the given
-   * [errorCode] and the list of [arguments] will be used to complete the
-   * message.
-   */
-  @deprecated // Use new AnalysisError(source, offset, length, errorCode, arguments)
-  AnalysisError.con2(Source source, int offset, int length, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, offset, length, errorCode, arguments);
-
-  /**
    * Return the template used to create the correction to be displayed for this
    * error, or `null` if there is no correction information for this error. The
    * correction should indicate how the user can fix the error.
@@ -278,28 +251,6 @@
       [List<Object> arguments])
       : super(source, offset, length, errorCode, arguments);
 
-  /**
-   * Initialize a newly created analysis error for the specified [source]. The
-   * error will have the given [errorCode] and the list of [arguments] will be
-   * used to complete the message. The error has no location information.
-   */
-  @deprecated // Use new AnalysisErrorWithProperties(source, 0, 0, errorCode, arguments)
-  AnalysisErrorWithProperties.con1(Source source, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, 0, 0, errorCode, arguments);
-
-  /**
-   * Initialize a newly created analysis error for the specified [source] at the
-   * given [offset] with the given [length]. The error will have the given
-   * [errorCode] and the list of [arguments] will be used to complete the
-   * message.
-   */
-  @deprecated // Use new AnalysisErrorWithProperties(source, offset, length, errorCode, arguments)
-  AnalysisErrorWithProperties.con2(
-      Source source, int offset, int length, ErrorCode errorCode,
-      [List<Object> arguments])
-      : this(source, offset, length, errorCode, arguments);
-
   @override
   Object getProperty(ErrorProperty property) => _propertyMap[property];
 
@@ -1178,6 +1129,15 @@
           "This class cannot extend the deferred class '{0}'");
 
   /**
+   * DEP 37 extends the syntax for assert() to allow a second "message"
+   * argument.  We issue this error if the user tries to supply a "message"
+   * argument but the DEP is not enabled.
+   */
+  static const CompileTimeErrorCode EXTRA_ARGUMENT_TO_ASSERT =
+      const CompileTimeErrorCode('EXTRA_ARGUMENT_TO_ASSERT',
+          "Assertions only accept a single argument");
+
+  /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
    * h</i> or if <i>m &gt; n</i>.
    *
@@ -3690,6 +3650,12 @@
       const HintCode('UNNECESSARY_CAST', "Unnecessary cast");
 
   /**
+   * Unnecessary `noSuchMethod` declaration.
+   */
+  static const HintCode UNNECESSARY_NO_SUCH_METHOD = const HintCode(
+      'UNNECESSARY_NO_SUCH_METHOD', "Unnecessary 'noSuchMethod' declaration");
+
+  /**
    * Unnecessary type checks, the result is always true.
    */
   static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = const HintCode(
@@ -4897,6 +4863,35 @@
           "The parameter type '{0}' is not assignable to '{1}' as required by the method it is overriding from '{2}'");
 
   /**
+   * Generic Method DEP: number of type parameters must match.
+   * <https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md#function-subtyping>
+   *
+   * Parameters:
+   * 0: the number of type parameters in the method
+   * 1: the number of type parameters in the overridden method
+   * 2: the name of the class where the overridden method is declared
+   */
+  static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS =
+      const StaticWarningCode('INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS',
+          "The method has {0} type parameters, but it is overriding a method with {1} type parameters from '{2}'");
+
+  /**
+   * Generic Method DEP: bounds of type parameters must be compatible.
+   * <https://github.com/leafpetersen/dep-generic-methods/blob/master/proposal.md#function-subtyping>
+   *
+   * Parameters:
+   * 0: the type parameter name
+   * 1: the type parameter bound
+   * 2: the overridden type parameter name
+   * 3: the overridden type parameter bound
+   * 4: the name of the class where the overridden method is declared
+   */
+  static const StaticWarningCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND =
+      const StaticWarningCode(
+          'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
+          "The type parameter '{0}' extends '{1}', but that is stricter than '{2}' extends '{3}' in the overridden method from '{4}'");
+
+  /**
    * 7.1 Instance Methods: It is a static warning if an instance method
    * <i>m1</i> overrides an instance method <i>m2</i> and the type of <i>m1</i>
    * is not a subtype of the type of <i>m2</i>.
@@ -4974,11 +4969,12 @@
    *
    * Parameters:
    * 0: the number of named parameters in the overridden member
-   * 1: the name of the class from the overridden method
+   * 1: the signature of the overridden member
+   * 2: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_NAMED = const StaticWarningCode(
       'INVALID_OVERRIDE_NAMED',
-      "Missing the named parameter '{0}' to match the overridden method from '{1}'");
+      "Missing the named parameter '{0}' to match the overridden method from '{1}' from '{2}'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -4987,11 +4983,12 @@
    *
    * Parameters:
    * 0: the number of positional parameters in the overridden member
-   * 1: the name of the class from the overridden method
+   * 1: the signature of the overridden member
+   * 2: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_POSITIONAL =
       const StaticWarningCode('INVALID_OVERRIDE_POSITIONAL',
-          "Must have at least {0} parameters to match the overridden method from '{1}'");
+          "Must have at least {0} parameters to match the overridden method '{1}' from '{2}'");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -5000,11 +4997,12 @@
    *
    * Parameters:
    * 0: the number of required parameters in the overridden member
-   * 1: the name of the class from the overridden method
+   * 1: the signature of the overridden member
+   * 2: the name of the class from the overridden method
    */
   static const StaticWarningCode INVALID_OVERRIDE_REQUIRED =
       const StaticWarningCode('INVALID_OVERRIDE_REQUIRED',
-          "Must have {0} required parameters or less to match the overridden method from '{1}'");
+          "Must have {0} required parameters or less to match the overridden method '{1}' from '{2}'");
 
   /**
    * 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a
@@ -5477,7 +5475,7 @@
    */
   static const StaticWarningCode TYPE_PARAMETER_REFERENCED_BY_STATIC =
       const StaticWarningCode('TYPE_PARAMETER_REFERENCED_BY_STATIC',
-          "Static members cannot reference type parameters");
+          "Static members cannot reference type parameters of the class");
 
   /**
    * 12.16.3 Static Invocation: A static method invocation <i>i</i> has the form
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index f76ab09..ef6300b 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2,24 +2,24 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver.error_verifier;
+library analyzer.src.generated.error_verifier;
 
 import 'dart:collection';
 import "dart:math" as math;
 
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart'
+    show Parser, ParserErrorCode;
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk, SdkLibrary;
 import 'package:analyzer/src/generated/static_type_analyzer.dart';
-
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'element_resolver.dart';
-import 'error.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser, ParserErrorCode;
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'sdk.dart' show DartSdk, SdkLibrary;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
  * A visitor used to traverse an AST structure looking for additional errors and
@@ -266,10 +266,21 @@
   final bool enableSuperMixins;
 
   /**
+   * If `true`, asserts are allowed to take a second argument representing the
+   * assertion failure message (see DEP 37).
+   */
+  final bool enableAssertMessage;
+
+  /**
    * Initialize a newly created error verifier.
    */
-  ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider,
-      this._inheritanceManager, this.enableSuperMixins) {
+  ErrorVerifier(
+      this._errorReporter,
+      this._currentLibrary,
+      this._typeProvider,
+      this._inheritanceManager,
+      this.enableSuperMixins,
+      this.enableAssertMessage) {
     this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
     this._hasExtUri = _currentLibrary.hasExtUri;
     _isEnclosingConstructorConst = false;
@@ -306,6 +317,7 @@
   @override
   Object visitAssertStatement(AssertStatement node) {
     _checkForNonBoolExpression(node);
+    _checkAssertMessage(node);
     return super.visitAssertStatement(node);
   }
 
@@ -1117,6 +1129,19 @@
   }
 
   /**
+   * If the given assert [statement] specifies a message, verify that support
+   * for assertions with messages is enabled.
+   */
+  void _checkAssertMessage(AssertStatement statement) {
+    Expression expression = statement.message;
+    if (expression != null && !enableAssertMessage) {
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT, expression);
+      return;
+    }
+  }
+
+  /**
    * Verify that the given list of [typeArguments] contains exactly two
    * elements.
    *
@@ -1322,6 +1347,71 @@
     if (overridingFT == null || overriddenFT == null) {
       return false;
     }
+
+  // Handle generic function type parameters.
+    // TODO(jmesserly): this duplicates some code in isSubtypeOf and most of
+    // _isGenericFunctionSubtypeOf. Ideally, we'd let TypeSystem produce
+    // an error message once it's ready to "return false".
+    if (!overridingFT.boundTypeParameters.isEmpty) {
+      if (overriddenFT.boundTypeParameters.isEmpty) {
+        overriddenFT = _typeSystem.instantiateToBounds(overriddenFT);
+      } else {
+        List<TypeParameterElement> params1 = overridingFT.boundTypeParameters;
+        List<TypeParameterElement> params2 = overriddenFT.boundTypeParameters;
+        int count = params1.length;
+        if (params2.length != count) {
+          _errorReporter.reportErrorForNode(
+              StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS,
+              errorNameTarget, [
+            count,
+            params2.length,
+            overriddenExecutable.enclosingElement.displayName
+          ]);
+          return true;
+        }
+        // We build up a substitution matching up the type parameters
+        // from the two types, {variablesFresh/variables1} and
+        // {variablesFresh/variables2}
+        List<DartType> variables1 = new List<DartType>();
+        List<DartType> variables2 = new List<DartType>();
+        List<DartType> variablesFresh = new List<DartType>();
+        for (int i = 0; i < count; i++) {
+          TypeParameterElement p1 = params1[i];
+          TypeParameterElement p2 = params2[i];
+          TypeParameterElementImpl pFresh =
+              new TypeParameterElementImpl(p1.name, -1);
+
+          DartType variable1 = p1.type;
+          DartType variable2 = p2.type;
+          DartType variableFresh = new TypeParameterTypeImpl(pFresh);
+
+          variables1.add(variable1);
+          variables2.add(variable2);
+          variablesFresh.add(variableFresh);
+          DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
+          DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
+          bound1 = bound1.substitute2(variablesFresh, variables1);
+          bound2 = bound2.substitute2(variablesFresh, variables2);
+          pFresh.bound = bound2;
+          if (!_typeSystem.isSubtypeOf(bound2, bound1)) {
+            _errorReporter.reportErrorForNode(
+                StaticWarningCode.INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND,
+                errorNameTarget, [
+              p1.displayName,
+              p1.bound,
+              p2.displayName,
+              p2.bound,
+              overriddenExecutable.enclosingElement.displayName
+            ]);
+            return true;
+          }
+        }
+        // Proceed with the rest of the checks, using instantiated types.
+        overridingFT = overridingFT.instantiate(variablesFresh);
+        overriddenFT = overriddenFT.instantiate(variablesFresh);
+      }
+    }
+
     DartType overridingFTReturnType = overridingFT.returnType;
     DartType overriddenFTReturnType = overriddenFT.returnType;
     List<DartType> overridingNormalPT = overridingFT.normalParameterTypes;
@@ -1336,6 +1426,7 @@
       _errorReporter.reportErrorForNode(
           StaticWarningCode.INVALID_OVERRIDE_REQUIRED, errorNameTarget, [
         overriddenNormalPT.length,
+        overriddenExecutable,
         overriddenExecutable.enclosingElement.displayName
       ]);
       return true;
@@ -1345,6 +1436,7 @@
       _errorReporter.reportErrorForNode(
           StaticWarningCode.INVALID_OVERRIDE_POSITIONAL, errorNameTarget, [
         overriddenPositionalPT.length + overriddenNormalPT.length,
+        overriddenExecutable,
         overriddenExecutable.enclosingElement.displayName
       ]);
       return true;
@@ -1358,6 +1450,7 @@
         _errorReporter.reportErrorForNode(
             StaticWarningCode.INVALID_OVERRIDE_NAMED, errorNameTarget, [
           overriddenParamName,
+          overriddenExecutable,
           overriddenExecutable.enclosingElement.displayName
         ]);
         return true;
@@ -5210,9 +5303,14 @@
     if (_isInStaticMethod || _isInStaticVariableDeclaration) {
       DartType type = name.type;
       if (type is TypeParameterType) {
-        _errorReporter.reportErrorForNode(
-            StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
-        return true;
+        // The class's type parameters are not in scope for static methods.
+        // However all other type parameters are legal (e.g. the static method's
+        // type parameters, or a local function's type parameters).
+        if (type.element.enclosingElement is ClassElement) {
+          _errorReporter.reportErrorForNode(
+              StaticWarningCode.TYPE_PARAMETER_REFERENCED_BY_STATIC, name);
+          return true;
+        }
       }
     }
     return false;
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
deleted file mode 100644
index c0012c5..0000000
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ /dev/null
@@ -1,1905 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library engine.html;
-
-import 'dart:collection';
-
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart' show AnalysisOptions, AnalysisEngine;
-import 'error.dart' show AnalysisErrorListener;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'parser.dart' show Parser;
-import 'scanner.dart' as sc show Scanner, SubSequenceReader, Token;
-import 'source.dart';
-
-/**
- * The abstract class `AbstractScanner` implements a scanner for HTML code. Subclasses are
- * required to implement the interface used to access the characters being scanned.
- */
-abstract class AbstractScanner {
-  static List<String> _NO_PASS_THROUGH_ELEMENTS = <String>[];
-
-  /**
-   * The source being scanned.
-   */
-  final Source source;
-
-  /**
-   * The token pointing to the head of the linked list of tokens.
-   */
-  Token _tokens;
-
-  /**
-   * The last token that was scanned.
-   */
-  Token _tail;
-
-  /**
-   * A list containing the offsets of the first character of each line in the source code.
-   */
-  List<int> _lineStarts = new List<int>();
-
-  /**
-   * An array of element tags for which the content between tags should be consider a single token.
-   */
-  List<String> _passThroughElements = _NO_PASS_THROUGH_ELEMENTS;
-
-  /**
-   * Initialize a newly created scanner.
-   *
-   * @param source the source being scanned
-   */
-  AbstractScanner(this.source) {
-    _tokens = new Token.con1(TokenType.EOF, -1);
-    _tokens.setNext(_tokens);
-    _tail = _tokens;
-    recordStartOfLine();
-  }
-
-  /**
-   * Return an array containing the offsets of the first character of each line in the source code.
-   *
-   * @return an array containing the offsets of the first character of each line in the source code
-   */
-  List<int> get lineStarts => _lineStarts;
-
-  /**
-   * Return the current offset relative to the beginning of the file. Return the initial offset if
-   * the scanner has not yet scanned the source code, and one (1) past the end of the source code if
-   * the source code has been scanned.
-   *
-   * @return the current offset of the scanner in the source
-   */
-  int get offset;
-
-  /**
-   * Set array of element tags for which the content between tags should be consider a single token.
-   */
-  void set passThroughElements(List<String> passThroughElements) {
-    this._passThroughElements = passThroughElements != null
-        ? passThroughElements
-        : _NO_PASS_THROUGH_ELEMENTS;
-  }
-
-  /**
-   * Advance the current position and return the character at the new current position.
-   *
-   * @return the character at the new current position
-   */
-  int advance();
-
-  /**
-   * Return the substring of the source code between the start offset and the modified current
-   * position. The current position is modified by adding the end delta.
-   *
-   * @param start the offset to the beginning of the string, relative to the start of the file
-   * @param endDelta the number of character after the current location to be included in the
-   *          string, or the number of characters before the current location to be excluded if the
-   *          offset is negative
-   * @return the specified substring of the source code
-   */
-  String getString(int start, int endDelta);
-
-  /**
-   * Return the character at the current position without changing the current position.
-   *
-   * @return the character at the current position
-   */
-  int peek();
-
-  /**
-   * Record the fact that we are at the beginning of a new line in the source.
-   */
-  void recordStartOfLine() {
-    _lineStarts.add(offset);
-  }
-
-  /**
-   * Scan the source code to produce a list of tokens representing the source.
-   *
-   * @return the first token in the list of tokens that were produced
-   */
-  Token tokenize() {
-    _scan();
-    _appendEofToken();
-    return _firstToken();
-  }
-
-  void _appendEofToken() {
-    Token eofToken = new Token.con1(TokenType.EOF, offset);
-    // The EOF token points to itself so that there is always infinite
-    // look-ahead.
-    eofToken.setNext(eofToken);
-    _tail = _tail.setNext(eofToken);
-  }
-
-  Token _emit(Token token) {
-    _tail.setNext(token);
-    _tail = token;
-    return token;
-  }
-
-  Token _emitWithOffset(TokenType type, int start) =>
-      _emit(new Token.con1(type, start));
-
-  Token _emitWithOffsetAndLength(TokenType type, int start, int count) =>
-      _emit(new Token.con2(type, start, getString(start, count)));
-
-  Token _firstToken() => _tokens.next;
-
-  int _recordStartOfLineAndAdvance(int c) {
-    if (c == 0xD) {
-      c = advance();
-      if (c == 0xA) {
-        c = advance();
-      }
-      recordStartOfLine();
-    } else if (c == 0xA) {
-      c = advance();
-      recordStartOfLine();
-    } else {
-      c = advance();
-    }
-    return c;
-  }
-
-  void _scan() {
-    bool inBrackets = false;
-    String endPassThrough = null;
-    int c = advance();
-    while (c >= 0) {
-      int start = offset;
-      if (c == 0x3C) {
-        c = advance();
-        if (c == 0x21) {
-          c = advance();
-          if (c == 0x2D && peek() == 0x2D) {
-            // handle a comment
-            c = advance();
-            int dashCount = 1;
-            while (c >= 0) {
-              if (c == 0x2D) {
-                dashCount++;
-              } else if (c == 0x3E && dashCount >= 2) {
-                c = advance();
-                break;
-              } else {
-                dashCount = 0;
-              }
-              c = _recordStartOfLineAndAdvance(c);
-            }
-            _emitWithOffsetAndLength(TokenType.COMMENT, start, -1);
-            // Capture <!--> and <!---> as tokens but report an error
-            if (_tail.length < 7) {
-              // TODO (danrubel): Report invalid HTML comment
-            }
-          } else {
-            // handle a declaration
-            while (c >= 0) {
-              if (c == 0x3E) {
-                c = advance();
-                break;
-              }
-              c = _recordStartOfLineAndAdvance(c);
-            }
-            _emitWithOffsetAndLength(TokenType.DECLARATION, start, -1);
-            if (!StringUtilities.endsWithChar(_tail.lexeme, 0x3E)) {
-              // TODO (danrubel): Report missing '>' in directive
-            }
-          }
-        } else if (c == 0x3F) {
-          // handle a directive
-          while (c >= 0) {
-            if (c == 0x3F) {
-              c = advance();
-              if (c == 0x3E) {
-                c = advance();
-                break;
-              }
-            } else {
-              c = _recordStartOfLineAndAdvance(c);
-            }
-          }
-          _emitWithOffsetAndLength(TokenType.DIRECTIVE, start, -1);
-          if (_tail.length < 4) {
-            // TODO (danrubel): Report invalid directive
-          }
-        } else if (c == 0x2F) {
-          _emitWithOffset(TokenType.LT_SLASH, start);
-          inBrackets = true;
-          c = advance();
-        } else {
-          inBrackets = true;
-          _emitWithOffset(TokenType.LT, start);
-          // ignore whitespace in braces
-          while (Character.isWhitespace(c)) {
-            c = _recordStartOfLineAndAdvance(c);
-          }
-          // get tag
-          if (Character.isLetterOrDigit(c)) {
-            int tagStart = offset;
-            c = advance();
-            while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
-              c = advance();
-            }
-            _emitWithOffsetAndLength(TokenType.TAG, tagStart, -1);
-            // check tag against passThrough elements
-            String tag = _tail.lexeme;
-            for (String str in _passThroughElements) {
-              if (str == tag) {
-                endPassThrough = "</$str>";
-                break;
-              }
-            }
-          }
-        }
-      } else if (c == 0x3E) {
-        _emitWithOffset(TokenType.GT, start);
-        inBrackets = false;
-        c = advance();
-        // if passThrough != null, read until we match it
-        if (endPassThrough != null) {
-          bool endFound = false;
-          int len = endPassThrough.length;
-          int firstC = endPassThrough.codeUnitAt(0);
-          int index = 0;
-          int nextC = firstC;
-          while (c >= 0) {
-            if (c == nextC) {
-              index++;
-              if (index == len) {
-                endFound = true;
-                break;
-              }
-              nextC = endPassThrough.codeUnitAt(index);
-            } else if (c == firstC) {
-              index = 1;
-              nextC = endPassThrough.codeUnitAt(1);
-            } else {
-              index = 0;
-              nextC = firstC;
-            }
-            c = _recordStartOfLineAndAdvance(c);
-          }
-          if (start + 1 < offset) {
-            if (endFound) {
-              _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -len);
-              _emitWithOffset(TokenType.LT_SLASH, offset - len + 1);
-              _emitWithOffsetAndLength(TokenType.TAG, offset - len + 3, -1);
-            } else {
-              _emitWithOffsetAndLength(TokenType.TEXT, start + 1, -1);
-            }
-          }
-          endPassThrough = null;
-        }
-      } else if (c == 0x2F && peek() == 0x3E) {
-        advance();
-        _emitWithOffset(TokenType.SLASH_GT, start);
-        inBrackets = false;
-        c = advance();
-      } else if (!inBrackets) {
-        c = _recordStartOfLineAndAdvance(c);
-        while (c != 0x3C && c >= 0) {
-          c = _recordStartOfLineAndAdvance(c);
-        }
-        _emitWithOffsetAndLength(TokenType.TEXT, start, -1);
-      } else if (c == 0x22 || c == 0x27) {
-        // read a string
-        int endQuote = c;
-        c = advance();
-        while (c >= 0) {
-          if (c == endQuote) {
-            c = advance();
-            break;
-          }
-          c = _recordStartOfLineAndAdvance(c);
-        }
-        _emitWithOffsetAndLength(TokenType.STRING, start, -1);
-      } else if (c == 0x3D) {
-        // a non-char token
-        _emitWithOffset(TokenType.EQ, start);
-        c = advance();
-      } else if (Character.isWhitespace(c)) {
-        // ignore whitespace in braces
-        do {
-          c = _recordStartOfLineAndAdvance(c);
-        } while (Character.isWhitespace(c));
-      } else if (Character.isLetterOrDigit(c)) {
-        c = advance();
-        while (Character.isLetterOrDigit(c) || c == 0x2D || c == 0x5F) {
-          c = advance();
-        }
-        _emitWithOffsetAndLength(TokenType.TAG, start, -1);
-      } else {
-        // a non-char token
-        _emitWithOffsetAndLength(TokenType.TEXT, start, 0);
-        c = advance();
-      }
-    }
-  }
-}
-
-/**
- * Instances of the class `HtmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class HtmlParser extends XmlParser {
-  static String _APPLICATION_DART_IN_DOUBLE_QUOTES = "\"application/dart\"";
-
-  static String _APPLICATION_DART_IN_SINGLE_QUOTES = "'application/dart'";
-
-  static String _SCRIPT = "script";
-
-  static String _TYPE = "type";
-
-  /**
-   * A set containing the names of tags that do not have a closing tag.
-   */
-  static Set<String> SELF_CLOSING = new HashSet<String>.from(<String>[
-    "area",
-    "base",
-    "basefont",
-    "br",
-    "col",
-    "frame",
-    "hr",
-    "img",
-    "input",
-    "link",
-    "meta",
-    "param",
-    "!"
-  ]);
-
-  /**
-   * The line information associated with the source being parsed.
-   */
-  LineInfo _lineInfo;
-
-  /**
-   * The error listener to which errors will be reported.
-   */
-  final AnalysisErrorListener _errorListener;
-
-  final AnalysisOptions _options;
-
-  /**
-   * Construct a parser for the specified source.
-   *
-   * [source] is the source being parsed.  [_errorListener] is the error
-   * listener to which errors will be reported.  [_options] is the analysis
-   * options which should be used for parsing.
-   */
-  HtmlParser(Source source, this._errorListener, this._options) : super(source);
-
-  @override
-  XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
-      new XmlAttributeNode(name, equals, value);
-
-  @override
-  XmlTagNode createTagNode(
-      Token nodeStart,
-      Token tag,
-      List<XmlAttributeNode> attributes,
-      Token attributeEnd,
-      List<XmlTagNode> tagNodes,
-      Token contentEnd,
-      Token closingTag,
-      Token nodeEnd) {
-    if (_isScriptNode(tag, attributes, tagNodes)) {
-      HtmlScriptTagNode tagNode = new HtmlScriptTagNode(nodeStart, tag,
-          attributes, attributeEnd, tagNodes, contentEnd, closingTag, nodeEnd);
-      String contents = tagNode.content;
-      int contentOffset = attributeEnd.end;
-      LineInfo_Location location = _lineInfo.getLocation(contentOffset);
-      sc.Scanner scanner = new sc.Scanner(source,
-          new sc.SubSequenceReader(contents, contentOffset), _errorListener);
-      scanner.setSourceStart(location.lineNumber, location.columnNumber);
-      sc.Token firstToken = scanner.tokenize();
-      Parser parser = new Parser(source, _errorListener);
-      CompilationUnit unit = parser.parseCompilationUnit(firstToken);
-      unit.lineInfo = _lineInfo;
-      tagNode.script = unit;
-      return tagNode;
-    }
-    return new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
-        contentEnd, closingTag, nodeEnd);
-  }
-
-  @override
-  bool isSelfClosing(Token tag) => SELF_CLOSING.contains(tag.lexeme);
-
-  /**
-   * Parse the given tokens.
-   *
-   * @param token the first token in the stream of tokens to be parsed
-   * @param lineInfo the line information created by the scanner
-   * @return the parse result (not `null`)
-   */
-  HtmlUnit parse(Token token, LineInfo lineInfo) {
-    this._lineInfo = lineInfo;
-    List<XmlTagNode> tagNodes = parseTopTagNodes(token);
-    return new HtmlUnit(token, tagNodes, currentToken);
-  }
-
-  /**
-   * Determine if the specified node is a Dart script.
-   *
-   * @param node the node to be tested (not `null`)
-   * @return `true` if the node is a Dart script
-   */
-  bool _isScriptNode(
-      Token tag, List<XmlAttributeNode> attributes, List<XmlTagNode> tagNodes) {
-    if (tagNodes.length != 0 || tag.lexeme != _SCRIPT) {
-      return false;
-    }
-    for (XmlAttributeNode attribute in attributes) {
-      if (attribute.name == _TYPE) {
-        Token valueToken = attribute.valueToken;
-        if (valueToken != null) {
-          String value = valueToken.lexeme;
-          if (value == _APPLICATION_DART_IN_DOUBLE_QUOTES ||
-              value == _APPLICATION_DART_IN_SINGLE_QUOTES) {
-            return true;
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  /**
-   * Given the contents of an embedded expression that occurs at the given offset, parse it as a
-   * Dart expression. The contents should not include the expression's delimiters.
-   *
-   * @param source the source that contains that given token
-   * @param token the token to start parsing from
-   * @return the Dart expression that was parsed
-   */
-  static Expression parseEmbeddedExpression(
-      Source source, sc.Token token, AnalysisErrorListener errorListener) {
-    Parser parser = new Parser(source, errorListener);
-    return parser.parseExpression(token);
-  }
-
-  /**
-   * Given the contents of an embedded expression that occurs at the given offset, scans it as a
-   * Dart code.
-   *
-   * @param source the source of that contains the given contents
-   * @param contents the contents to scan
-   * @param contentOffset the offset of the contents in the larger file
-   * @return the first Dart token
-   */
-  static sc.Token scanDartSource(Source source, LineInfo lineInfo,
-      String contents, int contentOffset, AnalysisErrorListener errorListener) {
-    LineInfo_Location location = lineInfo.getLocation(contentOffset);
-    sc.Scanner scanner = new sc.Scanner(source,
-        new sc.SubSequenceReader(contents, contentOffset), errorListener);
-    scanner.setSourceStart(location.lineNumber, location.columnNumber);
-    return scanner.tokenize();
-  }
-}
-
-/**
- * Instances of the class `HtmlScriptTagNode` represent a script tag within an HTML file that
- * references a Dart script.
- */
-@deprecated
-class HtmlScriptTagNode extends XmlTagNode {
-  /**
-   * The AST structure representing the Dart code within this tag.
-   */
-  CompilationUnit _script;
-
-  /**
-   * The element representing this script.
-   */
-  HtmlScriptElement scriptElement;
-
-  /**
-   * Initialize a newly created node to represent a script tag within an HTML file that references a
-   * Dart script.
-   *
-   * @param nodeStart the token marking the beginning of the tag
-   * @param tag the name of the tag
-   * @param attributes the attributes in the tag
-   * @param attributeEnd the token terminating the region where attributes can be
-   * @param tagNodes the children of the tag
-   * @param contentEnd the token that starts the closing tag
-   * @param closingTag the name of the tag that occurs in the closing tag
-   * @param nodeEnd the last token in the tag
-   */
-  HtmlScriptTagNode(
-      Token nodeStart,
-      Token tag,
-      List<XmlAttributeNode> attributes,
-      Token attributeEnd,
-      List<XmlTagNode> tagNodes,
-      Token contentEnd,
-      Token closingTag,
-      Token nodeEnd)
-      : super(nodeStart, tag, attributes, attributeEnd, tagNodes, contentEnd,
-            closingTag, nodeEnd);
-
-  /**
-   * Return the AST structure representing the Dart code within this tag, or `null` if this
-   * tag references an external script.
-   *
-   * @return the AST structure representing the Dart code within this tag
-   */
-  CompilationUnit get script => _script;
-
-  /**
-   * Set the AST structure representing the Dart code within this tag to the given compilation unit.
-   *
-   * @param unit the AST structure representing the Dart code within this tag
-   */
-  void set script(CompilationUnit unit) {
-    _script = unit;
-  }
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitHtmlScriptTagNode(this);
-}
-
-/**
- * Instances of the class `HtmlUnit` represent the contents of an HTML file.
- */
-@deprecated
-class HtmlUnit extends XmlNode {
-  /**
-   * The first token in the token stream that was parsed to form this HTML unit.
-   */
-  final Token beginToken;
-
-  /**
-   * The last token in the token stream that was parsed to form this compilation unit. This token
-   * should always have a type of [TokenType.EOF].
-   */
-  final Token endToken;
-
-  /**
-   * The tag nodes contained in the receiver (not `null`, contains no `null`s).
-   */
-  List<XmlTagNode> _tagNodes;
-
-  /**
-   * Construct a new instance representing the content of an HTML file.
-   *
-   * @param beginToken the first token in the file (not `null`)
-   * @param tagNodes child tag nodes of the receiver (not `null`, contains no `null`s)
-   * @param endToken the last token in the token stream which should be of type
-   *          [TokenType.EOF]
-   */
-  HtmlUnit(this.beginToken, List<XmlTagNode> tagNodes, this.endToken) {
-    this._tagNodes = becomeParentOfAll(tagNodes);
-  }
-
-  /**
-   * Return the element associated with this HTML unit.
-   *
-   * @return the element or `null` if the receiver is not resolved
-   */
-  @override
-  HtmlElement get element => super.element as HtmlElement;
-
-  @override
-  void set element(Element element) {
-    if (element != null && element is! HtmlElement) {
-      throw new IllegalArgumentException(
-          "HtmlElement expected, but ${element.runtimeType} given");
-    }
-    super.element = element;
-  }
-
-  /**
-   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
-   * to edit the AST structure.
-   *
-   * @return the children (not `null`, contains no `null`s)
-   */
-  List<XmlTagNode> get tagNodes => _tagNodes;
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitHtmlUnit(this);
-
-  @override
-  void visitChildren(XmlVisitor visitor) {
-    for (XmlTagNode node in _tagNodes) {
-      node.accept(visitor);
-    }
-  }
-}
-
-/**
- * Instances of the class `RecursiveXmlVisitor` implement an XML visitor that will recursively
- * visit all of the nodes in an XML structure. For example, using an instance of this class to visit
- * a [XmlTagNode] will also cause all of the contained [XmlAttributeNode]s and
- * [XmlTagNode]s to be visited.
- *
- * Subclasses that override a visit method must either invoke the overridden visit method or must
- * explicitly ask the visited node to visit its children. Failure to do so will cause the children
- * of the visited node to not be visited.
- */
-class RecursiveXmlVisitor<R> implements XmlVisitor<R> {
-  @override
-  R visitHtmlScriptTagNode(HtmlScriptTagNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitHtmlUnit(HtmlUnit node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitXmlAttributeNode(XmlAttributeNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-
-  @override
-  R visitXmlTagNode(XmlTagNode node) {
-    node.visitChildren(this);
-    return null;
-  }
-}
-
-/**
- * Instances of the class `SimpleXmlVisitor` implement an AST visitor that will do nothing
- * when visiting an AST node. It is intended to be a superclass for classes that use the visitor
- * pattern primarily as a dispatch mechanism (and hence don't need to recursively visit a whole
- * structure) and that only need to visit a small number of node types.
- */
-class SimpleXmlVisitor<R> implements XmlVisitor<R> {
-  @override
-  R visitHtmlScriptTagNode(HtmlScriptTagNode node) => null;
-
-  @override
-  R visitHtmlUnit(HtmlUnit htmlUnit) => null;
-
-  @override
-  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode) => null;
-
-  @override
-  R visitXmlTagNode(XmlTagNode xmlTagNode) => null;
-}
-
-/**
- * Instances of the class `StringScanner` implement a scanner that reads from a string. The
- * scanning logic is in the superclass.
- */
-class StringScanner extends AbstractScanner {
-  /**
-   * The string from which characters will be read.
-   */
-  final String _string;
-
-  /**
-   * The number of characters in the string.
-   */
-  int _stringLength = 0;
-
-  /**
-   * The index, relative to the string, of the last character that was read.
-   */
-  int _charOffset = 0;
-
-  /**
-   * Initialize a newly created scanner to scan the characters in the given string.
-   *
-   * @param source the source being scanned
-   * @param string the string from which characters will be read
-   */
-  StringScanner(Source source, this._string) : super(source) {
-    this._stringLength = _string.length;
-    this._charOffset = -1;
-  }
-
-  @override
-  int get offset => _charOffset;
-
-  void set offset(int offset) {
-    _charOffset = offset;
-  }
-
-  @override
-  int advance() {
-    if (++_charOffset < _stringLength) {
-      return _string.codeUnitAt(_charOffset);
-    }
-    _charOffset = _stringLength;
-    return -1;
-  }
-
-  @override
-  String getString(int start, int endDelta) =>
-      _string.substring(start, _charOffset + 1 + endDelta).toString();
-
-  @override
-  int peek() {
-    if (_charOffset + 1 < _stringLength) {
-      return _string.codeUnitAt(_charOffset + 1);
-    }
-    return -1;
-  }
-}
-
-/**
- * Instances of the class `Token` represent a token that was scanned from the input. Each
- * token knows which token follows it, acting as the head of a linked list of tokens.
- */
-class Token {
-  /**
-   * The offset from the beginning of the file to the first character in the token.
-   */
-  final int offset;
-
-  /**
-   * The previous token in the token stream.
-   */
-  Token previous;
-
-  /**
-   * The next token in the token stream.
-   */
-  Token _next;
-
-  /**
-   * The type of the token.
-   */
-  final TokenType type;
-
-  /**
-   * The lexeme represented by this token.
-   */
-  String _value;
-
-  /**
-   * Initialize a newly created token.
-   *
-   * @param type the token type (not `null`)
-   * @param offset the offset from the beginning of the file to the first character in the token
-   */
-  Token.con1(TokenType type, int offset) : this.con2(type, offset, type.lexeme);
-
-  /**
-   * Initialize a newly created token.
-   *
-   * @param type the token type (not `null`)
-   * @param offset the offset from the beginning of the file to the first character in the token
-   * @param value the lexeme represented by this token (not `null`)
-   */
-  Token.con2(this.type, this.offset, String value) {
-    this._value = StringUtilities.intern(value);
-  }
-
-  /**
-   * Return the offset from the beginning of the file to the character after last character of the
-   * token.
-   *
-   * @return the offset from the beginning of the file to the first character after last character
-   *         of the token
-   */
-  int get end => offset + length;
-
-  /**
-   * Return `true` if this token is a synthetic token. A synthetic token is a token that was
-   * introduced by the parser in order to recover from an error in the code. Synthetic tokens always
-   * have a length of zero (`0`).
-   *
-   * @return `true` if this token is a synthetic token
-   */
-  bool get isSynthetic => length == 0;
-
-  /**
-   * Return the number of characters in the node's source range.
-   *
-   * @return the number of characters in the node's source range
-   */
-  int get length => lexeme.length;
-
-  /**
-   * Return the lexeme that represents this token.
-   *
-   * @return the lexeme (not `null`)
-   */
-  String get lexeme => _value;
-
-  /**
-   * Return the next token in the token stream.
-   *
-   * @return the next token in the token stream
-   */
-  Token get next => _next;
-
-  /**
-   * Set the next token in the token stream to the given token. This has the side-effect of setting
-   * this token to be the previous token for the given token.
-   *
-   * @param token the next token in the token stream
-   * @return the token that was passed in
-   */
-  Token setNext(Token token) {
-    _next = token;
-    token.previous = this;
-    return token;
-  }
-
-  @override
-  String toString() => lexeme;
-}
-
-/**
- * The enumeration `TokenType` defines the types of tokens that can be returned by the
- * scanner.
- */
-class TokenType extends Enum<TokenType> {
-  /**
-   * The type of the token that marks the end of the input.
-   */
-  static const TokenType EOF = const TokenType_EOF('EOF', 0, "");
-
-  static const TokenType EQ = const TokenType('EQ', 1, "=");
-
-  static const TokenType GT = const TokenType('GT', 2, ">");
-
-  static const TokenType LT_SLASH = const TokenType('LT_SLASH', 3, "</");
-
-  static const TokenType LT = const TokenType('LT', 4, "<");
-
-  static const TokenType SLASH_GT = const TokenType('SLASH_GT', 5, "/>");
-
-  static const TokenType COMMENT = const TokenType('COMMENT', 6, null);
-
-  static const TokenType DECLARATION = const TokenType('DECLARATION', 7, null);
-
-  static const TokenType DIRECTIVE = const TokenType('DIRECTIVE', 8, null);
-
-  static const TokenType STRING = const TokenType('STRING', 9, null);
-
-  static const TokenType TAG = const TokenType('TAG', 10, null);
-
-  static const TokenType TEXT = const TokenType('TEXT', 11, null);
-
-  static const List<TokenType> values = const [
-    EOF,
-    EQ,
-    GT,
-    LT_SLASH,
-    LT,
-    SLASH_GT,
-    COMMENT,
-    DECLARATION,
-    DIRECTIVE,
-    STRING,
-    TAG,
-    TEXT
-  ];
-
-  /**
-   * The lexeme that defines this type of token, or `null` if there is more than one possible
-   * lexeme for this type of token.
-   */
-  final String lexeme;
-
-  const TokenType(String name, int ordinal, this.lexeme) : super(name, ordinal);
-}
-
-class TokenType_EOF extends TokenType {
-  const TokenType_EOF(String name, int ordinal, String arg0)
-      : super(name, ordinal, arg0);
-
-  @override
-  String toString() => "-eof-";
-}
-
-/**
- * Instances of the class `ToSourceVisitor` write a source representation of a visited XML
- * node (and all of it's children) to a writer.
- */
-class ToSourceVisitor implements XmlVisitor<Object> {
-  /**
-   * The writer to which the source is to be written.
-   */
-  final PrintWriter _writer;
-
-  /**
-   * Initialize a newly created visitor to write source code representing the visited nodes to the
-   * given writer.
-   *
-   * @param writer the writer to which the source is to be written
-   */
-  ToSourceVisitor(this._writer);
-
-  @override
-  Object visitHtmlScriptTagNode(HtmlScriptTagNode node) =>
-      visitXmlTagNode(node);
-
-  @override
-  Object visitHtmlUnit(HtmlUnit node) {
-    for (XmlTagNode child in node.tagNodes) {
-      _visit(child);
-    }
-    return null;
-  }
-
-  @override
-  Object visitXmlAttributeNode(XmlAttributeNode node) {
-    String name = node.name;
-    Token value = node.valueToken;
-    if (name.length == 0) {
-      _writer.print("__");
-    } else {
-      _writer.print(name);
-    }
-    _writer.print("=");
-    if (value == null) {
-      _writer.print("__");
-    } else {
-      _writer.print(value.lexeme);
-    }
-    return null;
-  }
-
-  @override
-  Object visitXmlTagNode(XmlTagNode node) {
-    _writer.print("<");
-    String tagName = node.tag;
-    _writer.print(tagName);
-    for (XmlAttributeNode attribute in node.attributes) {
-      _writer.print(" ");
-      _visit(attribute);
-    }
-    _writer.print(node.attributeEnd.lexeme);
-    if (node.closingTag != null) {
-      for (XmlTagNode child in node.tagNodes) {
-        _visit(child);
-      }
-      _writer.print("</");
-      _writer.print(tagName);
-      _writer.print(">");
-    }
-    return null;
-  }
-
-  /**
-   * Safely visit the given node.
-   *
-   * @param node the node to be visited
-   */
-  void _visit(XmlNode node) {
-    if (node != null) {
-      node.accept(this);
-    }
-  }
-}
-
-/**
- * Instances of `XmlAttributeNode` represent name/value pairs owned by an [XmlTagNode].
- */
-class XmlAttributeNode extends XmlNode {
-  /**
-   * An empty list of XML attribute nodes.
-   */
-  static const List<XmlAttributeNode> EMPTY_LIST = const <XmlAttributeNode>[];
-
-  final Token _name;
-
-  final Token equals;
-
-  final Token _value;
-
-  List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
-  /**
-   * Construct a new instance representing an XML attribute.
-   *
-   * @param name the name token (not `null`). This may be a zero length token if the attribute
-   *          is badly formed.
-   * @param equals the equals sign or `null` if none
-   * @param value the value token (not `null`)
-   */
-  XmlAttributeNode(this._name, this.equals, this._value);
-
-  @override
-  Token get beginToken => _name;
-
-  @override
-  Token get endToken => _value;
-
-  /**
-   * Answer the attribute name. This may be a zero length string if the attribute is badly formed.
-   *
-   * @return the name (not `null`)
-   */
-  String get name => _name.lexeme;
-
-  /**
-   * Answer the attribute name token. This may be a zero length token if the attribute is badly
-   * formed.
-   *
-   * @return the name token (not `null`)
-   */
-  Token get nameToken => _name;
-
-  /**
-   * Answer the lexeme for the value token without the leading and trailing quotes.
-   *
-   * @return the text or `null` if the value is not specified
-   */
-  String get text {
-    if (_value == null) {
-      return null;
-    }
-    //TODO (danrubel): replace HTML character encodings with the actual
-    // characters
-    String text = _value.lexeme;
-    int len = text.length;
-    if (len > 0) {
-      if (text.codeUnitAt(0) == 0x22) {
-        if (len > 1 && text.codeUnitAt(len - 1) == 0x22) {
-          return text.substring(1, len - 1);
-        } else {
-          return text.substring(1);
-        }
-      } else if (text.codeUnitAt(0) == 0x27) {
-        if (len > 1 && text.codeUnitAt(len - 1) == 0x27) {
-          return text.substring(1, len - 1);
-        } else {
-          return text.substring(1);
-        }
-      }
-    }
-    return text;
-  }
-
-  /**
-   * Answer the offset of the value after the leading quote.
-   *
-   * @return the offset of the value, or `-1` if the value is not specified
-   */
-  int get textOffset {
-    if (_value == null) {
-      return -1;
-    }
-    String text = _value.lexeme;
-    if (StringUtilities.startsWithChar(text, 0x22) ||
-        StringUtilities.startsWithChar(text, 0x27)) {
-      return _value.offset + 1;
-    }
-    return _value.offset;
-  }
-
-  /**
-   * Answer the attribute value token. A properly formed value will start and end with matching
-   * quote characters, but the value returned may not be properly formed.
-   *
-   * @return the value token or `null` if this represents a badly formed attribute
-   */
-  Token get valueToken => _value;
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitXmlAttributeNode(this);
-
-  @override
-  void visitChildren(XmlVisitor visitor) {
-    // no children to visit
-  }
-}
-
-/**
- * Instances of the class `XmlExpression` represent an abstract expression embedded into
- * [XmlNode].
- */
-abstract class XmlExpression {
-  /**
-   * An empty list of expressions.
-   */
-  static const List<XmlExpression> EMPTY_ARRAY = const <XmlExpression>[];
-
-  /**
-   * Return the offset of the character immediately following the last character of this
-   * expression's source range. This is equivalent to `getOffset() + getLength()`.
-   *
-   * @return the offset of the character just past the expression's source range
-   */
-  int get end;
-
-  /**
-   * Return the number of characters in the expression's source range.
-   */
-  int get length;
-
-  /**
-   * Return the offset of the first character in the expression's source range.
-   */
-  int get offset;
-
-  /**
-   * Check if the given offset belongs to the expression's source range.
-   */
-  bool contains(int offset) => this.offset <= offset && offset < end;
-
-  /**
-   * Return the [Reference] at the given offset.
-   *
-   * @param offset the offset from the beginning of the file
-   * @return the [Reference] at the given offset, maybe `null`
-   */
-  XmlExpression_Reference getReference(int offset);
-}
-
-/**
- * The reference to the [Element].
- */
-class XmlExpression_Reference {
-  Element element;
-
-  int offset = 0;
-
-  int length = 0;
-
-  XmlExpression_Reference(this.element, this.offset, this.length);
-}
-
-/**
- * The abstract class `XmlNode` defines behavior common to all XML/HTML nodes.
- */
-abstract class XmlNode {
-  /**
-   * The parent of the node, or `null` if the node is the root of an AST structure.
-   */
-  XmlNode _parent;
-
-  /**
-   * The element associated with this node or `null` if the receiver is not resolved.
-   */
-  Element _element;
-
-  /**
-   * Return the first token included in this node's source range.
-   *
-   * @return the first token or `null` if none
-   */
-  Token get beginToken;
-
-  /**
-   * Return the element associated with this node.
-   *
-   * @return the element or `null` if the receiver is not resolved
-   */
-  Element get element => _element;
-
-  /**
-   * Set the element associated with this node.
-   *
-   * @param element the element
-   */
-  void set element(Element element) {
-    this._element = element;
-  }
-
-  /**
-   * Return the offset of the character immediately following the last character of this node's
-   * source range. This is equivalent to `node.getOffset() + node.getLength()`. For an html
-   * unit this will be equal to the length of the unit's source.
-   *
-   * @return the offset of the character just past the node's source range
-   */
-  int get end => offset + length;
-
-  /**
-   * Return the last token included in this node's source range.
-   *
-   * @return the last token or `null` if none
-   */
-  Token get endToken;
-
-  /**
-   * Return the number of characters in the node's source range.
-   *
-   * @return the number of characters in the node's source range
-   */
-  int get length {
-    Token beginToken = this.beginToken;
-    Token endToken = this.endToken;
-    if (beginToken == null || endToken == null) {
-      return -1;
-    }
-    return endToken.offset + endToken.length - beginToken.offset;
-  }
-
-  /**
-   * Return the offset from the beginning of the file to the first character in the node's source
-   * range.
-   *
-   * @return the offset from the beginning of the file to the first character in the node's source
-   *         range
-   */
-  int get offset {
-    Token beginToken = this.beginToken;
-    if (beginToken == null) {
-      return -1;
-    }
-    return this.beginToken.offset;
-  }
-
-  /**
-   * Return this node's parent node, or `null` if this node is the root of an AST structure.
-   *
-   * Note that the relationship between an AST node and its parent node may change over the lifetime
-   * of a node.
-   *
-   * @return the parent of this node, or `null` if none
-   */
-  XmlNode get parent => _parent;
-
-  /**
-   * Set the parent of this node to the given node.
-   *
-   * @param newParent the node that is to be made the parent of this node
-   */
-  void set parent(XmlNode newParent) {
-    XmlNode current = newParent;
-    while (current != null) {
-      if (identical(current, this)) {
-        AnalysisEngine.instance.logger.logError(
-            "Circular structure while setting an XML node's parent",
-            new CaughtException(
-                new ArgumentError(_buildRecursiveStructureMessage(newParent)),
-                null));
-        return;
-      }
-      current = current.parent;
-    }
-    _parent = newParent;
-  }
-
-  /**
-   * Use the given visitor to visit this node.
-   *
-   * @param visitor the visitor that will visit this node
-   * @return the value returned by the visitor as a result of visiting this node
-   */
-  accept(XmlVisitor visitor);
-
-  /**
-   * Make this node the parent of the given child node.
-   *
-   * @param child the node that will become a child of this node
-   * @return the node that was made a child of this node
-   */
-  XmlNode becomeParentOf(XmlNode child) {
-    if (child != null) {
-      XmlNode node = child;
-      node.parent = this;
-    }
-    return child;
-  }
-
-  /**
-   * Make this node the parent of the given child nodes.
-   *
-   * @param children the nodes that will become the children of this node
-   * @param ifEmpty the (empty) nodes to return if "children" is empty
-   * @return the nodes that were made children of this node
-   */
-  List becomeParentOfAll(List children, {List ifEmpty}) {
-    if (children == null || children.isEmpty) {
-      if (ifEmpty != null) {
-        return ifEmpty;
-      }
-    }
-    if (children != null) {
-      children.forEach((XmlNode node) {
-        node.parent = this;
-      });
-    }
-    return children;
-  }
-
-  @override
-  String toString() {
-    PrintStringWriter writer = new PrintStringWriter();
-    accept(new ToSourceVisitor(writer));
-    return writer.toString();
-  }
-
-  /**
-   * Use the given visitor to visit all of the children of this node. The children will be visited
-   * in source order.
-   *
-   * @param visitor the visitor that will be used to visit the children of this node
-   */
-  void visitChildren(XmlVisitor visitor);
-
-  /**
-   * This method exists for debugging purposes only.
-   */
-  void _appendIdentifier(StringBuffer buffer, XmlNode node) {
-    if (node is XmlTagNode) {
-      buffer.write(node.tag);
-    } else if (node is XmlAttributeNode) {
-      buffer.write(node.name);
-    } else {
-      buffer.write("htmlUnit");
-    }
-  }
-
-  /**
-   * This method exists for debugging purposes only.
-   */
-  String _buildRecursiveStructureMessage(XmlNode newParent) {
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("Attempt to create recursive structure: ");
-    XmlNode current = newParent;
-    while (current != null) {
-      if (!identical(current, newParent)) {
-        buffer.write(" -> ");
-      }
-      if (identical(current, this)) {
-        buffer.writeCharCode(0x2A);
-        _appendIdentifier(buffer, current);
-        buffer.writeCharCode(0x2A);
-      } else {
-        _appendIdentifier(buffer, current);
-      }
-      current = current.parent;
-    }
-    return buffer.toString();
-  }
-}
-
-/**
- * Instances of the class `XmlParser` are used to parse tokens into a AST structure comprised
- * of [XmlNode]s.
- */
-class XmlParser {
-  /**
-   * The source being parsed.
-   */
-  final Source source;
-
-  /**
-   * The next token to be parsed.
-   */
-  Token _currentToken;
-
-  /**
-   * Construct a parser for the specified source.
-   *
-   * @param source the source being parsed
-   */
-  XmlParser(this.source);
-
-  /**
-   * Answer the current token.
-   *
-   * @return the current token
-   */
-  Token get currentToken => _currentToken;
-
-  /**
-   * Create a node representing an attribute.
-   *
-   * @param name the name of the attribute
-   * @param equals the equals sign, or `null` if there is no value
-   * @param value the value of the attribute
-   * @return the node that was created
-   */
-  XmlAttributeNode createAttributeNode(Token name, Token equals, Token value) =>
-      new XmlAttributeNode(name, equals, value);
-
-  /**
-   * Create a node representing a tag.
-   *
-   * @param nodeStart the token marking the beginning of the tag
-   * @param tag the name of the tag
-   * @param attributes the attributes in the tag
-   * @param attributeEnd the token terminating the region where attributes can be
-   * @param tagNodes the children of the tag
-   * @param contentEnd the token that starts the closing tag
-   * @param closingTag the name of the tag that occurs in the closing tag
-   * @param nodeEnd the last token in the tag
-   * @return the node that was created
-   */
-  XmlTagNode createTagNode(
-          Token nodeStart,
-          Token tag,
-          List<XmlAttributeNode> attributes,
-          Token attributeEnd,
-          List<XmlTagNode> tagNodes,
-          Token contentEnd,
-          Token closingTag,
-          Token nodeEnd) =>
-      new XmlTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
-          contentEnd, closingTag, nodeEnd);
-
-  /**
-   * Answer `true` if the specified tag is self closing and thus should never have content or
-   * child tag nodes.
-   *
-   * @param tag the tag (not `null`)
-   * @return `true` if self closing
-   */
-  bool isSelfClosing(Token tag) => false;
-
-  /**
-   * Parse the entire token stream and in the process, advance the current token to the end of the
-   * token stream.
-   *
-   * @return the list of tag nodes found (not `null`, contains no `null`)
-   */
-  List<XmlTagNode> parseTopTagNodes(Token firstToken) {
-    _currentToken = firstToken;
-    List<XmlTagNode> tagNodes = new List<XmlTagNode>();
-    TokenType type = _currentToken.type;
-    while (type != TokenType.EOF) {
-      if (type == TokenType.LT) {
-        tagNodes.add(_parseTagNode());
-      } else if (type == TokenType.DECLARATION ||
-          type == TokenType.DIRECTIVE ||
-          type == TokenType.COMMENT) {
-        // ignored tokens
-        _currentToken = _currentToken.next;
-      } else {
-        _reportUnexpectedToken();
-        _currentToken = _currentToken.next;
-      }
-      type = _currentToken.type;
-    }
-    return tagNodes;
-  }
-
-  /**
-   * Insert a synthetic token of the specified type before the current token
-   *
-   * @param type the type of token to be inserted (not `null`)
-   * @return the synthetic token that was inserted (not `null`)
-   */
-  Token _insertSyntheticToken(TokenType type) {
-    Token token = new Token.con2(type, _currentToken.offset, "");
-    _currentToken.previous.setNext(token);
-    token.setNext(_currentToken);
-    return token;
-  }
-
-  /**
-   * Parse the token stream for an attribute. This method advances the current token over the
-   * attribute, but should not be called if the [currentToken] is not [TokenType.TAG].
-   *
-   * @return the attribute (not `null`)
-   */
-  XmlAttributeNode _parseAttribute() {
-    // Assume the current token is a tag
-    Token name = _currentToken;
-    _currentToken = _currentToken.next;
-    // Equals sign
-    Token equals;
-    if (_currentToken.type == TokenType.EQ) {
-      equals = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      equals = _insertSyntheticToken(TokenType.EQ);
-    }
-    // String value
-    Token value;
-    if (_currentToken.type == TokenType.STRING) {
-      value = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      value = _insertSyntheticToken(TokenType.STRING);
-    }
-    return createAttributeNode(name, equals, value);
-  }
-
-  /**
-   * Parse the stream for a sequence of attributes. This method advances the current token to the
-   * next [TokenType.GT], [TokenType.SLASH_GT], or [TokenType.EOF].
-   *
-   * @return a collection of zero or more attributes (not `null`, contains no `null`s)
-   */
-  List<XmlAttributeNode> _parseAttributes() {
-    TokenType type = _currentToken.type;
-    if (type == TokenType.GT ||
-        type == TokenType.SLASH_GT ||
-        type == TokenType.EOF) {
-      return XmlTagNode.NO_ATTRIBUTES;
-    }
-    List<XmlAttributeNode> attributes = new List<XmlAttributeNode>();
-    while (type != TokenType.GT &&
-        type != TokenType.SLASH_GT &&
-        type != TokenType.EOF) {
-      if (type == TokenType.TAG) {
-        attributes.add(_parseAttribute());
-      } else {
-        _reportUnexpectedToken();
-        _currentToken = _currentToken.next;
-      }
-      type = _currentToken.type;
-    }
-    return attributes;
-  }
-
-  /**
-   * Parse the stream for a sequence of tag nodes existing within a parent tag node. This method
-   * advances the current token to the next [TokenType.LT_SLASH] or [TokenType.EOF].
-   *
-   * @return a list of nodes (not `null`, contains no `null`s)
-   */
-  List<XmlTagNode> _parseChildTagNodes() {
-    TokenType type = _currentToken.type;
-    if (type == TokenType.LT_SLASH || type == TokenType.EOF) {
-      return XmlTagNode.NO_TAG_NODES;
-    }
-    List<XmlTagNode> nodes = new List<XmlTagNode>();
-    while (type != TokenType.LT_SLASH && type != TokenType.EOF) {
-      if (type == TokenType.LT) {
-        nodes.add(_parseTagNode());
-      } else if (type == TokenType.COMMENT) {
-        // ignored token
-        _currentToken = _currentToken.next;
-      } else {
-        _reportUnexpectedToken();
-        _currentToken = _currentToken.next;
-      }
-      type = _currentToken.type;
-    }
-    return nodes;
-  }
-
-  /**
-   * Parse the token stream for the next tag node. This method advances current token over the
-   * parsed tag node, but should only be called if the current token is [TokenType.LT]
-   *
-   * @return the tag node or `null` if none found
-   */
-  XmlTagNode _parseTagNode() {
-    // Assume that the current node is a tag node start TokenType.LT
-    Token nodeStart = _currentToken;
-    _currentToken = _currentToken.next;
-    // Get the tag or create a synthetic tag and report an error
-    Token tag;
-    if (_currentToken.type == TokenType.TAG) {
-      tag = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      tag = _insertSyntheticToken(TokenType.TAG);
-    }
-    // Parse the attributes
-    List<XmlAttributeNode> attributes = _parseAttributes();
-    // Token ending attribute list
-    Token attributeEnd;
-    if (_currentToken.type == TokenType.GT ||
-        _currentToken.type == TokenType.SLASH_GT) {
-      attributeEnd = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      attributeEnd = _insertSyntheticToken(TokenType.SLASH_GT);
-    }
-    // If the node has no children, then return the node
-    if (attributeEnd.type == TokenType.SLASH_GT || isSelfClosing(tag)) {
-      return createTagNode(nodeStart, tag, attributes, attributeEnd,
-          XmlTagNode.NO_TAG_NODES, _currentToken, null, attributeEnd);
-    }
-    // Parse the child tag nodes
-    List<XmlTagNode> tagNodes = _parseChildTagNodes();
-    // Token ending child tag nodes
-    Token contentEnd;
-    if (_currentToken.type == TokenType.LT_SLASH) {
-      contentEnd = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      // TODO (danrubel): handle self closing HTML elements by inserting
-      // synthetic tokens but not reporting an error
-      _reportUnexpectedToken();
-      contentEnd = _insertSyntheticToken(TokenType.LT_SLASH);
-    }
-    // Closing tag
-    Token closingTag;
-    if (_currentToken.type == TokenType.TAG) {
-      closingTag = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      closingTag = _insertSyntheticToken(TokenType.TAG);
-    }
-    // Token ending node
-    Token nodeEnd;
-    if (_currentToken.type == TokenType.GT) {
-      nodeEnd = _currentToken;
-      _currentToken = _currentToken.next;
-    } else {
-      _reportUnexpectedToken();
-      nodeEnd = _insertSyntheticToken(TokenType.GT);
-    }
-    return createTagNode(nodeStart, tag, attributes, attributeEnd, tagNodes,
-        contentEnd, closingTag, nodeEnd);
-  }
-
-  /**
-   * Report the current token as unexpected
-   */
-  void _reportUnexpectedToken() {
-    // TODO (danrubel): report unexpected token
-  }
-}
-
-/**
- * Instances of `XmlTagNode` represent XML or HTML elements such as `` and
- * `<body foo="bar"> ... </body>`.
- */
-class XmlTagNode extends XmlNode {
-  /**
-   * Constant representing empty list of attributes.
-   */
-  static List<XmlAttributeNode> NO_ATTRIBUTES =
-      new UnmodifiableListView(new List<XmlAttributeNode>());
-
-  /**
-   * Constant representing empty list of tag nodes.
-   */
-  static List<XmlTagNode> NO_TAG_NODES =
-      new UnmodifiableListView(new List<XmlTagNode>());
-
-  /**
-   * The starting [TokenType.LT] token (not `null`).
-   */
-  final Token nodeStart;
-
-  /**
-   * The [TokenType.TAG] token after the starting '&lt;' (not `null`).
-   */
-  final Token _tag;
-
-  /**
-   * The attributes contained by the receiver (not `null`, contains no `null`s).
-   */
-  List<XmlAttributeNode> _attributes;
-
-  /**
-   * The [TokenType.GT] or [TokenType.SLASH_GT] token after the attributes (not
-   * `null`). The token may be the same token as [nodeEnd] if there are no child
-   * [tagNodes].
-   */
-  final Token attributeEnd;
-
-  /**
-   * The tag nodes contained in the receiver (not `null`, contains no `null`s).
-   */
-  List<XmlTagNode> _tagNodes;
-
-  /**
-   * The token (not `null`) after the content, which may be
-   * * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
-   * * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is self
-   * closing or the attributeEnd is [TokenType.SLASH_GT], or
-   * * (3) [TokenType.EOF] if the node does not have a closing tag and is the last node in
-   * the stream [TokenType.LT_SLASH] token after the content, or `null` if there is no
-   * content and the attributes ended with [TokenType.SLASH_GT].
-   */
-  final Token contentEnd;
-
-  /**
-   * The closing [TokenType.TAG] after the child elements or `null` if there is no
-   * content and the attributes ended with [TokenType.SLASH_GT]
-   */
-  final Token closingTag;
-
-  /**
-   * The ending [TokenType.GT] or [TokenType.SLASH_GT] token (not `null`).
-   */
-  final Token nodeEnd;
-
-  /**
-   * The expressions that are embedded in the tag's content.
-   */
-  List<XmlExpression> expressions = XmlExpression.EMPTY_ARRAY;
-
-  /**
-   * Construct a new instance representing an XML or HTML element
-   *
-   * @param nodeStart the starting [TokenType.LT] token (not `null`)
-   * @param tag the [TokenType.TAG] token after the starting '&lt;' (not `null`).
-   * @param attributes the attributes associated with this element or [NO_ATTRIBUTES] (not
-   *          `null`, contains no `null`s)
-   * @param attributeEnd The [TokenType.GT] or [TokenType.SLASH_GT] token after the
-   *          attributes (not `null`). The token may be the same token as [nodeEnd] if
-   *          there are no child [tagNodes].
-   * @param tagNodes child tag nodes of the receiver or [NO_TAG_NODES] (not `null`,
-   *          contains no `null`s)
-   * @param contentEnd the token (not `null`) after the content, which may be
-   *          * (1) [TokenType.LT_SLASH] for nodes with open and close tags, or
-   *          * (2) the [TokenType.LT] nodeStart of the next sibling node if this node is
-   *          self closing or the attributeEnd is [TokenType.SLASH_GT], or
-   *          * (3) [TokenType.EOF] if the node does not have a closing tag and is the last
-   *          node in the stream [TokenType.LT_SLASH] token after the content, or `null`
-   *          if there is no content and the attributes ended with [TokenType.SLASH_GT].
-   * @param closingTag the closing [TokenType.TAG] after the child elements or `null` if
-   *          there is no content and the attributes ended with [TokenType.SLASH_GT]
-   * @param nodeEnd the ending [TokenType.GT] or [TokenType.SLASH_GT] token (not
-   *          `null`)
-   */
-  XmlTagNode(
-      this.nodeStart,
-      this._tag,
-      List<XmlAttributeNode> attributes,
-      this.attributeEnd,
-      List<XmlTagNode> tagNodes,
-      this.contentEnd,
-      this.closingTag,
-      this.nodeEnd) {
-    this._attributes = becomeParentOfAll(attributes, ifEmpty: NO_ATTRIBUTES);
-    this._tagNodes = becomeParentOfAll(tagNodes, ifEmpty: NO_TAG_NODES);
-  }
-
-  /**
-   * Answer the receiver's attributes. Callers should not manipulate the returned list to edit the
-   * AST structure.
-   *
-   * @return the attributes (not `null`, contains no `null`s)
-   */
-  List<XmlAttributeNode> get attributes => _attributes;
-
-  @override
-  Token get beginToken => nodeStart;
-
-  /**
-   * Return a string representing the content contained in the receiver. This
-   * includes the textual representation of any child tag nodes ([getTagNodes]).
-   * Whitespace between '&lt;', '&lt;/', and '>', '/>' is discarded, but all
-   * other whitespace is preserved.
-   */
-  String get content {
-    Token token = attributeEnd.next;
-    if (identical(token, contentEnd)) {
-      return "";
-    }
-    // TODO(danrubel) Handle CDATA and replace HTML character encodings with
-    // the actual characters.
-    String content = token.lexeme;
-    token = token.next;
-    if (identical(token, contentEnd)) {
-      return content;
-    }
-    StringBuffer buffer = new StringBuffer();
-    buffer.write(content);
-    while (!identical(token, contentEnd)) {
-      buffer.write(token.lexeme);
-      token = token.next;
-    }
-    return buffer.toString();
-  }
-
-  @override
-  Token get endToken {
-    if (nodeEnd != null) {
-      return nodeEnd;
-    }
-    if (closingTag != null) {
-      return closingTag;
-    }
-    if (contentEnd != null) {
-      return contentEnd;
-    }
-    if (!_tagNodes.isEmpty) {
-      return _tagNodes[_tagNodes.length - 1].endToken;
-    }
-    if (attributeEnd != null) {
-      return attributeEnd;
-    }
-    if (!_attributes.isEmpty) {
-      return _attributes[_attributes.length - 1].endToken;
-    }
-    return _tag;
-  }
-
-  /**
-   * Answer the tag name after the starting '&lt;'.
-   *
-   * @return the tag name (not `null`)
-   */
-  String get tag => _tag.lexeme;
-
-  /**
-   * Answer the tag nodes contained in the receiver. Callers should not manipulate the returned list
-   * to edit the AST structure.
-   *
-   * @return the children (not `null`, contains no `null`s)
-   */
-  List<XmlTagNode> get tagNodes => _tagNodes;
-
-  /**
-   * Answer the [TokenType.TAG] token after the starting '&lt;'.
-   *
-   * @return the token (not `null`)
-   */
-  Token get tagToken => _tag;
-
-  @override
-  accept(XmlVisitor visitor) => visitor.visitXmlTagNode(this);
-
-  /**
-   * Answer the attribute with the specified name.
-   *
-   * @param name the attribute name
-   * @return the attribute or `null` if no matching attribute is found
-   */
-  XmlAttributeNode getAttribute(String name) {
-    for (XmlAttributeNode attribute in _attributes) {
-      if (attribute.name == name) {
-        return attribute;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Find the attribute with the given name (see [getAttribute] and answer the lexeme
-   * for the attribute's value token without the leading and trailing quotes (see
-   * [XmlAttributeNode.getText]).
-   *
-   * @param name the attribute name
-   * @return the attribute text or `null` if no matching attribute is found
-   */
-  String getAttributeText(String name) {
-    XmlAttributeNode attribute = getAttribute(name);
-    return attribute != null ? attribute.text : null;
-  }
-
-  @override
-  void visitChildren(XmlVisitor visitor) {
-    for (XmlAttributeNode node in _attributes) {
-      node.accept(visitor);
-    }
-    for (XmlTagNode node in _tagNodes) {
-      node.accept(visitor);
-    }
-  }
-}
-
-/**
- * The interface `XmlVisitor` defines the behavior of objects that can be used to visit an
- * [XmlNode] structure.
- */
-abstract class XmlVisitor<R> {
-  R visitHtmlScriptTagNode(HtmlScriptTagNode node);
-
-  R visitHtmlUnit(HtmlUnit htmlUnit);
-
-  R visitXmlAttributeNode(XmlAttributeNode xmlAttributeNode);
-
-  R visitXmlTagNode(XmlTagNode xmlTagNode);
-}
diff --git a/pkg/analyzer/lib/src/generated/incremental_logger.dart b/pkg/analyzer/lib/src/generated/incremental_logger.dart
index 8abc6fe..d942aba 100644
--- a/pkg/analyzer/lib/src/generated/incremental_logger.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_logger.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_logger;
+library analyzer.src.generated.incremental_logger;
 
 /**
  * The shared instance of [Logger] used by several incremental resolution
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
index bab107e..6cf9af1 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_resolution_validator;
+library analyzer.src.generated.incremental_resolution_validator;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -63,6 +63,7 @@
   visitAssertStatement(AssertStatement node) {
     AssertStatement other = this.other;
     _visitNode(node.condition, other.condition);
+    _visitNode(node.message, other.message);
   }
 
   @override
@@ -185,6 +186,14 @@
   }
 
   @override
+  visitConfiguration(Configuration node) {
+    Configuration other = this.other;
+    _visitNode(node.name, other.name);
+    _visitNode(node.value, other.value);
+    _visitNode(node.libraryUri, other.libraryUri);
+  }
+
+  @override
   visitConstructorDeclaration(ConstructorDeclaration node) {
     ConstructorDeclaration other = this.other;
     _visitDeclaration(node, other);
@@ -238,6 +247,12 @@
   }
 
   @override
+  visitDottedName(DottedName node) {
+    DottedName other = this.other;
+    _visitList(node.components, other.components);
+  }
+
+  @override
   visitDoubleLiteral(DoubleLiteral node) {
     DoubleLiteral other = this.other;
     _visitExpression(node, other);
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 1192f2c..a80de52 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -2,41 +2,30 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_resolver;
+library analyzer.src.generated.incremental_resolver;
 
 import 'dart:collection';
 import 'dart:math' as math;
 
-import 'package:analyzer/src/context/cache.dart'
-    show CacheEntry, Delta, DeltaResult;
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/error_verifier.dart';
+import 'package:analyzer/src/generated/incremental_logger.dart'
+    show logger, LoggingTimer;
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/task/dart.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart' show CONTENT, LINE_INFO;
-import 'package:analyzer/task/model.dart'
-    show AnalysisTarget, ResultDescriptor, TargetedResult, TaskDescriptor;
-
-import 'ast.dart';
-import 'element.dart';
-import 'engine.dart'
-    show
-        AnalysisContext,
-        AnalysisOptions,
-        CacheState,
-        DartEntry,
-        DataDescriptor,
-        InternalAnalysisContext,
-        RecordingErrorListener,
-        SourceEntry;
-import 'error.dart';
-import 'error_verifier.dart';
-import 'incremental_logger.dart' show logger, LoggingTimer;
-import 'java_engine.dart';
-import 'parser.dart';
-import 'resolver.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_dart.dart';
+import 'package:analyzer/task/model.dart';
 
 /**
  * If `true`, an attempt to resolve API-changing modifications is made.
@@ -971,11 +960,6 @@
   LibraryElementImpl _definingLibrary;
 
   /**
-   * The [DartEntry] corresponding to the source being resolved.
-   */
-  DartEntry oldEntry;
-
-  /**
    * The [CacheEntry] corresponding to the source being resolved.
    */
   CacheEntry newSourceEntry;
@@ -1031,7 +1015,6 @@
    * given source in the given library.
    */
   IncrementalResolver(
-      this.oldEntry,
       this.newSourceEntry,
       this.newUnitEntry,
       this._definingUnit,
@@ -1243,14 +1226,6 @@
   }
 
   void _shiftEntryErrors() {
-    if (oldEntry != null) {
-      _shiftEntryErrors_OLD();
-    } else {
-      _shiftEntryErrors_NEW();
-    }
-  }
-
-  void _shiftEntryErrors_NEW() {
     _shiftErrors_NEW(HINTS);
     _shiftErrors_NEW(LINTS);
     _shiftErrors_NEW(LIBRARY_UNIT_ERRORS);
@@ -1261,13 +1236,6 @@
     _shiftErrors_NEW(VERIFY_ERRORS);
   }
 
-  void _shiftEntryErrors_OLD() {
-    _shiftErrors_OLD(DartEntry.RESOLUTION_ERRORS);
-    _shiftErrors_OLD(DartEntry.VERIFICATION_ERRORS);
-    _shiftErrors_OLD(DartEntry.HINTS);
-    _shiftErrors_OLD(DartEntry.LINTS);
-  }
-
   void _shiftErrors(List<AnalysisError> errors) {
     for (AnalysisError error in errors) {
       if (_alreadyShiftedErrors.add(error)) {
@@ -1284,12 +1252,6 @@
     _shiftErrors(errors);
   }
 
-  void _shiftErrors_OLD(DataDescriptor<List<AnalysisError>> descriptor) {
-    List<AnalysisError> errors =
-        oldEntry.getValueInLibrary(descriptor, _librarySource);
-    _shiftErrors(errors);
-  }
-
   void _updateCache() {
     if (newSourceEntry != null) {
       LoggingTimer timer = logger.startTimer();
@@ -1315,14 +1277,6 @@
   }
 
   void _updateEntry() {
-    if (oldEntry != null) {
-      _updateEntry_OLD();
-    } else {
-      _updateEntry_NEW();
-    }
-  }
-
-  void _updateEntry_NEW() {
     _updateErrors_NEW(RESOLVE_TYPE_NAMES_ERRORS, []);
     _updateErrors_NEW(RESOLVE_UNIT_ERRORS, _resolveErrors);
     _updateErrors_NEW(VARIABLE_REFERENCE_ERRORS, []);
@@ -1335,11 +1289,6 @@
     newUnitEntry.setState(LINTS, CacheState.INVALID);
   }
 
-  void _updateEntry_OLD() {
-    _updateErrors_OLD(DartEntry.RESOLUTION_ERRORS, _resolveErrors);
-    _updateErrors_OLD(DartEntry.VERIFICATION_ERRORS, _verifyErrors);
-  }
-
   List<AnalysisError> _updateErrors(
       List<AnalysisError> oldErrors, List<AnalysisError> newErrors) {
     List<AnalysisError> errors = new List<AnalysisError>();
@@ -1371,14 +1320,6 @@
     newUnitEntry.setValueIncremental(descriptor, errors, true);
   }
 
-  void _updateErrors_OLD(DataDescriptor<List<AnalysisError>> descriptor,
-      List<AnalysisError> newErrors) {
-    List<AnalysisError> oldErrors =
-        oldEntry.getValueInLibrary(descriptor, _librarySource);
-    List<AnalysisError> errors = _updateErrors(oldErrors, newErrors);
-    oldEntry.setValueInLibrary(descriptor, _librarySource, errors);
-  }
-
   void _verify(AstNode node) {
     LoggingTimer timer = logger.startTimer();
     try {
@@ -1389,7 +1330,8 @@
           _definingLibrary,
           _typeProvider,
           new InheritanceManager(_definingLibrary),
-          _context.analysisOptions.enableSuperMixins);
+          _context.analysisOptions.enableSuperMixins,
+          _context.analysisOptions.enableAssertMessage);
       if (_resolutionContext.enclosingClassDeclaration != null) {
         errorVerifier.visitClassDeclarationIncrementally(
             _resolutionContext.enclosingClassDeclaration);
@@ -1407,19 +1349,14 @@
   final Source _unitSource;
 
   /**
-   * The [DartEntry] corresponding to the source being resolved.
-   */
-  DartEntry _oldEntry;
-
-  /**
    * The [CacheEntry] corresponding to the source being resolved.
    */
-  CacheEntry _newSourceEntry;
+  CacheEntry _sourceEntry;
 
   /**
    * The [CacheEntry] corresponding to the [LibrarySpecificUnit] being resolved.
    */
-  CacheEntry _newUnitEntry;
+  CacheEntry _unitEntry;
 
   final CompilationUnit _oldUnit;
   CompilationUnitElement _unitElement;
@@ -1436,9 +1373,8 @@
   PoorMansIncrementalResolver(
       this._typeProvider,
       this._unitSource,
-      this._oldEntry,
-      this._newSourceEntry,
-      this._newUnitEntry,
+      this._sourceEntry,
+      this._unitEntry,
       this._oldUnit,
       bool resolveApiChanges) {
     _resolveApiChanges = resolveApiChanges;
@@ -1497,9 +1433,8 @@
             _shiftTokens(firstPair.oldToken);
             {
               IncrementalResolver incrementalResolver = new IncrementalResolver(
-                  _oldEntry,
-                  _newSourceEntry,
-                  _newUnitEntry,
+                  _sourceEntry,
+                  _unitEntry,
                   _unitElement,
                   _updateOffset,
                   _updateEndOld,
@@ -1594,9 +1529,8 @@
         }
         // perform incremental resolution
         IncrementalResolver incrementalResolver = new IncrementalResolver(
-            _oldEntry,
-            _newSourceEntry,
-            _newUnitEntry,
+            _sourceEntry,
+            _unitEntry,
             _unitElement,
             _updateOffset,
             _updateEndOld,
@@ -1665,9 +1599,8 @@
     NodeReplacer.replace(oldComment, newComment);
     // update elements
     IncrementalResolver incrementalResolver = new IncrementalResolver(
-        _oldEntry,
-        _newSourceEntry,
-        _newUnitEntry,
+        _sourceEntry,
+        _unitEntry,
         _unitElement,
         _updateOffset,
         _updateEndOld,
@@ -1731,26 +1664,12 @@
   }
 
   void _updateEntry() {
-    if (_oldEntry != null) {
-      _updateEntry_OLD();
-    } else {
-      _updateEntry_NEW();
-    }
-  }
-
-  void _updateEntry_NEW() {
     // scan results
-    _newSourceEntry.setValueIncremental(SCAN_ERRORS, _newScanErrors, true);
-    _newSourceEntry.setValueIncremental(LINE_INFO, _newLineInfo, false);
+    _sourceEntry.setValueIncremental(SCAN_ERRORS, _newScanErrors, true);
+    _sourceEntry.setValueIncremental(LINE_INFO, _newLineInfo, false);
     // parse results
-    _newSourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
-    _newSourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
-  }
-
-  void _updateEntry_OLD() {
-    _oldEntry.setValue(SourceEntry.LINE_INFO, _newLineInfo);
-    _oldEntry.setValue(DartEntry.SCAN_ERRORS, _newScanErrors);
-    _oldEntry.setValue(DartEntry.PARSE_ERRORS, _newParseErrors);
+    _sourceEntry.setValueIncremental(PARSE_ERRORS, _newParseErrors, true);
+    _sourceEntry.setValueIncremental(PARSED_UNIT, _oldUnit, false);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/incremental_scanner.dart b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
index a2e4daf..6f4abee 100644
--- a/pkg/analyzer/lib/src/generated/incremental_scanner.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_scanner.dart
@@ -2,16 +2,15 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_scanner;
+library analyzer.src.generated.incremental_scanner;
 
 import "dart:math" as math;
 
 import 'package:analyzer/src/generated/engine.dart';
-
-import 'error.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
 
 /**
  * An `IncrementalScanner` is a scanner that scans a subset of a string and
diff --git a/pkg/analyzer/lib/src/generated/interner.dart b/pkg/analyzer/lib/src/generated/interner.dart
index 9ff047b..9741f28 100644
--- a/pkg/analyzer/lib/src/generated/interner.dart
+++ b/pkg/analyzer/lib/src/generated/interner.dart
@@ -2,7 +2,7 @@
 // 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 interner;
+library analyzer.src.generated.interner;
 
 import 'dart:collection';
 
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index 8c96357..acd2337 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -1,4 +1,8 @@
-library java.core;
+// 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.src.generated.java_core;
 
 const int LONG_MAX_VALUE = 0x7fffffffffffffff;
 
@@ -295,14 +299,6 @@
 }
 
 class JavaSystem {
-  @deprecated
-  static void arraycopy(
-      List src, int srcPos, List dest, int destPos, int length) {
-    for (int i = 0; i < length; i++) {
-      dest[destPos + i] = src[srcPos + i];
-    }
-  }
-
   static int currentTimeMillis() {
     return (new DateTime.now()).millisecondsSinceEpoch;
   }
diff --git a/pkg/analyzer/lib/src/generated/java_engine.dart b/pkg/analyzer/lib/src/generated/java_engine.dart
index affcf8d..be2020f 100644
--- a/pkg/analyzer/lib/src/generated/java_engine.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine.dart
@@ -1,7 +1,11 @@
-library java.engine;
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
 
-import 'interner.dart';
-import 'java_core.dart';
+library analyzer.src.generated.java_engine;
+
+import 'package:analyzer/src/generated/interner.dart';
+import 'package:analyzer/src/generated/java_core.dart';
 
 /**
  * A predicate is a one-argument function that returns a boolean value.
diff --git a/pkg/analyzer/lib/src/generated/java_engine_io.dart b/pkg/analyzer/lib/src/generated/java_engine_io.dart
index 749695a..aa7023d 100644
--- a/pkg/analyzer/lib/src/generated/java_engine_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_engine_io.dart
@@ -1,16 +1,21 @@
-library java.engine.io;
+// 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.src.generated.java_engine_io;
 
 import "dart:io";
-import "java_io.dart";
 
-class OSUtilities {
-  static String LINE_SEPARATOR = isWindows() ? '\r\n' : '\n';
-  static bool isWindows() => Platform.operatingSystem == 'windows';
-  static bool isMac() => Platform.operatingSystem == 'macos';
-}
+import "package:analyzer/src/generated/java_io.dart";
 
 class FileUtilities2 {
   static JavaFile createFile(String path) {
     return new JavaFile(path).getAbsoluteFile();
   }
 }
+
+class OSUtilities {
+  static String LINE_SEPARATOR = isWindows() ? '\r\n' : '\n';
+  static bool isMac() => Platform.operatingSystem == 'macos';
+  static bool isWindows() => Platform.operatingSystem == 'windows';
+}
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 000746f..dc054d0 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -1,11 +1,14 @@
-library java.io;
+// 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.src.generated.java_io;
 
 import "dart:io";
 
+import 'package:analyzer/src/generated/java_core.dart' show JavaIOException;
 import 'package:path/path.dart' as path;
 
-import 'java_core.dart' show JavaIOException;
-
 class JavaFile {
   static path.Context pathContext = path.context;
   static final String separator = Platform.pathSeparator;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 2074525..b15a92e 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2,20 +2,21 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.parser;
+library analyzer.src.generated.parser;
 
 import 'dart:collection';
 import "dart:math" as math;
 
-import 'ast.dart';
-import 'engine.dart' show AnalysisEngine, AnalysisOptionsImpl;
-import 'error.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'scanner.dart';
-import 'source.dart';
-import 'utilities_collection.dart' show TokenMap;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart'
+    show AnalysisEngine, AnalysisOptionsImpl;
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_collection.dart' show TokenMap;
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 Map<String, MethodTrampoline> methodTable_Parser = <String, MethodTrampoline>{
   'parseCompilationUnit_1': new MethodTrampoline(
@@ -196,6 +197,8 @@
       1, (Parser target, arg0) => target._parseCommentReferences(arg0)),
   'parseCompilationUnitMember_1': new MethodTrampoline(
       1, (Parser target, arg0) => target._parseCompilationUnitMember(arg0)),
+  'parseConfiguration_0':
+      new MethodTrampoline(0, (Parser target) => target._parseConfiguration()),
   'parseConstExpression_0': new MethodTrampoline(
       0, (Parser target) => target._parseConstExpression()),
   'parseConstructor_8': new MethodTrampoline(
@@ -214,6 +217,8 @@
       0, (Parser target) => target._parseDocumentationComment()),
   'parseDoStatement_0':
       new MethodTrampoline(0, (Parser target) => target._parseDoStatement()),
+  'parseDottedName_0':
+      new MethodTrampoline(0, (Parser target) => target._parseDottedName()),
   'parseEmptyStatement_0':
       new MethodTrampoline(0, (Parser target) => target._parseEmptyStatement()),
   'parseEnumConstantDeclaration_0': new MethodTrampoline(
@@ -574,6 +579,9 @@
     if (identical(_oldNode, node.condition)) {
       return _parser.parseExpression2();
     }
+    if (identical(_oldNode, node.message)) {
+      return _parser.parseExpression2();
+    }
     return _notAChild(node);
   }
 
@@ -745,6 +753,18 @@
   }
 
   @override
+  AstNode visitConfiguration(Configuration node) {
+    if (identical(_oldNode, node.name)) {
+      throw new InsufficientContextException();
+    } else if (identical(_oldNode, node.value)) {
+      return _parser.parseStringLiteral();
+    } else if (identical(_oldNode, node.libraryUri)) {
+      return _parser.parseStringLiteral();
+    }
+    return _notAChild(node);
+  }
+
+  @override
   AstNode visitConstructorDeclaration(ConstructorDeclaration node) {
     if (identical(_oldNode, node.documentationComment)) {
       throw new InsufficientContextException();
@@ -829,6 +849,14 @@
   }
 
   @override
+  AstNode visitDottedName(DottedName node) {
+    if (node.components.contains(_oldNode)) {
+      throw new InsufficientContextException();
+    }
+    return _notAChild(node);
+  }
+
+  @override
   AstNode visitDoubleLiteral(DoubleLiteral node) => _notAChild(node);
 
   @override
@@ -2118,6 +2146,12 @@
   bool _inInitializer = false;
 
   /**
+   * A flag indicating whether the parser is to parse conditional directives
+   * syntax.
+   */
+  bool parseConditionalDirectives = false;
+
+  /**
    * A flag indicating whether the parser is to parse generic method syntax.
    */
   bool parseGenericMethods = false;
@@ -2154,30 +2188,6 @@
   }
 
   /**
-   * Set whether the parser is to parse the async support.
-   */
-  @deprecated
-  void set parseAsync(bool parseAsync) {
-    // Async support cannot be disabled
-  }
-
-  /**
-   * Set whether the parser is to parse deferred libraries.
-   */
-  @deprecated
-  void set parseDeferredLibraries(bool parseDeferredLibraries) {
-    // Deferred libraries support cannot be disabled
-  }
-
-  /**
-   * Set whether the parser is to parse enum declarations.
-   */
-  @deprecated
-  void set parseEnum(bool parseEnum) {
-    // Enum support cannot be disabled
-  }
-
-  /**
    * Set whether parser is to parse function bodies.
    */
   void set parseFunctionBodies(bool parseFunctionBodies) {
@@ -4378,10 +4388,16 @@
       _reportErrorForNode(
           ParserErrorCode.ASSERT_DOES_NOT_TAKE_RETHROW, expression);
     }
+    Token comma;
+    Expression message;
+    if (_matches(TokenType.COMMA)) {
+      comma = getAndAdvance();
+      message = parseExpression2();
+    }
     Token rightParen = _expect(TokenType.CLOSE_PAREN);
     Token semicolon = _expect(TokenType.SEMICOLON);
     return new AssertStatement(
-        keyword, leftParen, expression, rightParen, semicolon);
+        keyword, leftParen, expression, comma, message, rightParen, semicolon);
   }
 
   /**
@@ -5262,6 +5278,52 @@
   }
 
   /**
+   * Parse a configuration in either an import or export directive.
+   *
+   *     configuration ::=
+   *         'if' '(' test ')' uri
+   *
+   *     test ::=
+   *         dottedName ('==' stringLiteral)?
+   *
+   *     dottedName ::=
+   *         identifier ('.' identifier)*
+   */
+  Configuration _parseConfiguration() {
+    Token ifKeyword = _expectKeyword(Keyword.IF);
+    Token leftParenthesis = _expect(TokenType.OPEN_PAREN);
+    DottedName name = _parseDottedName();
+    Token equalToken = null;
+    StringLiteral value = null;
+    if (_matches(TokenType.EQ_EQ)) {
+      equalToken = getAndAdvance();
+      value = parseStringLiteral();
+      if (value is StringInterpolation) {
+        _reportErrorForNode(
+            ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION, value);
+      }
+    }
+    Token rightParenthesis = _expect(TokenType.CLOSE_PAREN);
+    StringLiteral libraryUri = _parseUri();
+    return new Configuration(ifKeyword, leftParenthesis, name, equalToken,
+        value, rightParenthesis, libraryUri);
+  }
+
+  /**
+   * Parse a list of configurations. If conditional directives are not
+   * supported, return an empty list without attempting to parse anything.
+   */
+  List<Configuration> _parseConfigurations() {
+    List<Configuration> configurations = <Configuration>[];
+    if (parseConditionalDirectives) {
+      while (_matchesKeyword(Keyword.IF)) {
+        configurations.add(_parseConfiguration());
+      }
+    }
+    return configurations;
+  }
+
+  /**
    * Parse a const expression. Return the const expression that was parsed.
    *
    *     constExpression ::=
@@ -5577,6 +5639,22 @@
   }
 
   /**
+   * Parse a dotted name. Return the dotted name that was parsed.
+   *
+   *     dottedName ::=
+   *         identifier ('.' identifier)*
+   */
+  DottedName _parseDottedName() {
+    List<SimpleIdentifier> components = new List<SimpleIdentifier>();
+    components.add(parseSimpleIdentifier());
+    while (_matches(TokenType.PERIOD)) {
+      _advance();
+      components.add(parseSimpleIdentifier());
+    }
+    return new DottedName(components);
+  }
+
+  /**
    * Parse an empty statement. Return the empty statement that was parsed.
    *
    *     emptyStatement ::=
@@ -5683,11 +5761,12 @@
    * associated with the directive. Return the export directive that was parsed.
    *
    *     exportDirective ::=
-   *         metadata 'export' stringLiteral combinator*';'
+   *         metadata 'export' stringLiteral configuration* combinator*';'
    */
   ExportDirective _parseExportDirective(CommentAndMetadata commentAndMetadata) {
     Token exportKeyword = _expectKeyword(Keyword.EXPORT);
     StringLiteral libraryUri = _parseUri();
+    List<Configuration> configurations = _parseConfigurations();
     List<Combinator> combinators = _parseCombinators();
     Token semicolon = _expectSemicolon();
     return new ExportDirective(
@@ -5695,6 +5774,7 @@
         commentAndMetadata.metadata,
         exportKeyword,
         libraryUri,
+        configurations,
         combinators,
         semicolon);
   }
@@ -6350,11 +6430,12 @@
    * associated with the directive. Return the import directive that was parsed.
    *
    *     importDirective ::=
-   *         metadata 'import' stringLiteral (deferred)? ('as' identifier)? combinator*';'
+   *         metadata 'import' stringLiteral configuration* (deferred)? ('as' identifier)? combinator*';'
    */
   ImportDirective _parseImportDirective(CommentAndMetadata commentAndMetadata) {
     Token importKeyword = _expectKeyword(Keyword.IMPORT);
     StringLiteral libraryUri = _parseUri();
+    List<Configuration> configurations = _parseConfigurations();
     Token deferredToken = null;
     Token asToken = null;
     SimpleIdentifier prefix = null;
@@ -6390,6 +6471,7 @@
         commentAndMetadata.metadata,
         importKeyword,
         libraryUri,
+        configurations,
         deferredToken,
         asToken,
         prefix,
@@ -9469,6 +9551,10 @@
       'INVALID_HEX_ESCAPE',
       "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
 
+  static const ParserErrorCode INVALID_LITERAL_IN_CONFIGURATION =
+      const ParserErrorCode('INVALID_LITERAL_IN_CONFIGURATION',
+          "The literal in a configuration cannot contain interpolation");
+
   static const ParserErrorCode INVALID_OPERATOR = const ParserErrorCode(
       'INVALID_OPERATOR', "The string '{0}' is not a valid operator");
 
@@ -9862,6 +9948,8 @@
         _isEqualTokens(node.assertKeyword, toNode.assertKeyword),
         _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
         _isEqualNodes(node.condition, toNode.condition),
+        _isEqualTokens(node.comma, toNode.comma),
+        _isEqualNodes(node.message, toNode.message),
         _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
         _isEqualTokens(node.semicolon, toNode.semicolon));
   }
@@ -10057,6 +10145,22 @@
   }
 
   @override
+  bool visitConfiguration(Configuration node) {
+    Configuration toNode = this._toNode as Configuration;
+    if (_and(
+        _isEqualTokens(node.ifKeyword, toNode.ifKeyword),
+        _isEqualTokens(node.leftParenthesis, toNode.leftParenthesis),
+        _isEqualNodes(node.name, toNode.name),
+        _isEqualTokens(node.equalToken, toNode.equalToken),
+        _isEqualNodes(node.value, toNode.value),
+        _isEqualTokens(node.rightParenthesis, toNode.rightParenthesis),
+        _isEqualNodes(node.libraryUri, toNode.libraryUri))) {
+      return true;
+    }
+    return false;
+  }
+
+  @override
   bool visitConstructorDeclaration(ConstructorDeclaration node) {
     ConstructorDeclaration toNode = this._toNode as ConstructorDeclaration;
     if (_and(
@@ -10152,6 +10256,12 @@
   }
 
   @override
+  bool visitDottedName(DottedName node) {
+    DottedName toNode = this._toNode as DottedName;
+    return _isEqualNodeLists(node.components, toNode.components);
+  }
+
+  @override
   bool visitDoubleLiteral(DoubleLiteral node) {
     DoubleLiteral toNode = this._toNode as DoubleLiteral;
     if (_and(_isEqualTokens(node.literal, toNode.literal),
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 0d17e72..03452f4 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2,53 +2,27 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver;
+library analyzer.src.generated.resolver;
 
 import 'dart:collection';
 
-import '../task/strong/info.dart' show InferredType, StaticInfo;
-import '../task/strong/rules.dart' show TypeRules;
-import 'ast.dart';
-import 'constant.dart';
-import 'element.dart';
-import 'element_resolver.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'error_verifier.dart';
-import 'html.dart' as ht;
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'scanner.dart';
-import 'scanner.dart' as sc;
-import 'sdk.dart' show DartSdk, SdkLibrary;
-import 'source.dart';
-import 'static_type_analyzer.dart';
-import 'type_system.dart';
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/element_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/error_verifier.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/static_type_analyzer.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/task/strong/info.dart' show InferredType, StaticInfo;
 
-export 'type_system.dart';
-
-/**
- * Callback signature used by ImplicitConstructorBuilder to register
- * computations to be performed, and their dependencies.  A call to this
- * callback indicates that [computation] may be used to compute implicit
- * constructors for [classElement], but that the computation may not be invoked
- * until after implicit constructors have been built for [superclassElement].
- */
-typedef void ImplicitConstructorBuilderCallback(ClassElement classElement,
-    ClassElement superclassElement, void computation());
-
-typedef LibraryResolver LibraryResolverFactory(AnalysisContext context);
-
-typedef ResolverVisitor ResolverVisitorFactory(
-    Library library, Source source, TypeProvider typeProvider);
-
-typedef StaticTypeAnalyzer StaticTypeAnalyzerFactory(ResolverVisitor visitor);
-
-typedef TypeResolverVisitor TypeResolverVisitorFactory(
-    Library library, Source source, TypeProvider typeProvider);
-
-typedef void VoidFunction();
+export 'package:analyzer/src/generated/type_system.dart';
 
 /**
  * Instances of the class `BestPracticesVerifier` traverse an AST structure looking for
@@ -113,8 +87,8 @@
 
   @override
   Object visitAssignmentExpression(AssignmentExpression node) {
-    sc.TokenType operatorType = node.operator.type;
-    if (operatorType == sc.TokenType.EQ) {
+    TokenType operatorType = node.operator.type;
+    if (operatorType == TokenType.EQ) {
       _checkForUseOfVoidResult(node.rightHandSide);
       _checkForInvalidAssignment(node.leftHandSide, node.rightHandSide);
     } else {
@@ -214,6 +188,7 @@
     // This was determined to not be a good hint, see: dartbug.com/16029
     //checkForOverridingPrivateMember(node);
     _checkForMissingReturn(node.returnType, node.body);
+    _checkForUnnecessaryNoSuchMethod(node);
     return super.visitMethodDeclaration(node);
   }
 
@@ -293,7 +268,7 @@
     }
     String rhsNameStr = typeName.name.name;
     // if x is dynamic
-    if (rhsType.isDynamic && rhsNameStr == sc.Keyword.DYNAMIC.syntax) {
+    if (rhsType.isDynamic && rhsNameStr == Keyword.DYNAMIC.syntax) {
       if (node.notOperator == null) {
         // the is case
         _errorReporter.reportErrorForNode(
@@ -553,7 +528,7 @@
    */
   bool _checkForDivisionOptimizationHint(BinaryExpression node) {
     // Return if the operator is not '/'
-    if (node.operator.type != sc.TokenType.SLASH) {
+    if (node.operator.type != TokenType.SLASH) {
       return false;
     }
     // Return if the '/' operator is not defined in core, or if we don't know
@@ -753,35 +728,6 @@
   }
 
   /**
-   * Check for the passed class declaration for the
-   * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
-   *
-   * @param node the class declaration to check
-   * @return `true` if and only if a hint code is generated on the passed node
-   * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
-   */
-//  bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
-//    ClassElement classElement = node.element;
-//    if (classElement == null) {
-//      return false;
-//    }
-//    MethodElement equalsOperatorMethodElement =
-//        classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
-//    if (equalsOperatorMethodElement != null) {
-//      PropertyAccessorElement hashCodeElement =
-//          classElement.getGetter(_HASHCODE_GETTER_NAME);
-//      if (hashCodeElement == null) {
-//        _errorReporter.reportErrorForNode(
-//            HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
-//            node.name,
-//            [classElement.displayName]);
-//        return true;
-//      }
-//    }
-//    return false;
-//  }
-
-  /**
    * Check for the passed as expression for the [HintCode.UNNECESSARY_CAST] hint code.
    *
    * @param node the as expression to check
@@ -831,6 +777,83 @@
   }
 
   /**
+   * Check for the passed class declaration for the
+   * [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE] hint code.
+   *
+   * @param node the class declaration to check
+   * @return `true` if and only if a hint code is generated on the passed node
+   * See [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE].
+   */
+//  bool _checkForOverrideEqualsButNotHashCode(ClassDeclaration node) {
+//    ClassElement classElement = node.element;
+//    if (classElement == null) {
+//      return false;
+//    }
+//    MethodElement equalsOperatorMethodElement =
+//        classElement.getMethod(sc.TokenType.EQ_EQ.lexeme);
+//    if (equalsOperatorMethodElement != null) {
+//      PropertyAccessorElement hashCodeElement =
+//          classElement.getGetter(_HASHCODE_GETTER_NAME);
+//      if (hashCodeElement == null) {
+//        _errorReporter.reportErrorForNode(
+//            HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE,
+//            node.name,
+//            [classElement.displayName]);
+//        return true;
+//      }
+//    }
+//    return false;
+//  }
+
+  /**
+   * Generate a hint for `noSuchMethod` methods that do nothing except of
+   * calling another `noSuchMethod` that is not defined by `Object`.
+   *
+   * @return `true` if and only if a hint code is generated on the passed node
+   * See [HintCode.UNNECESSARY_NO_SUCH_METHOD].
+   */
+  bool _checkForUnnecessaryNoSuchMethod(MethodDeclaration node) {
+    if (node.name.name != FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+      return false;
+    }
+    bool isNonObjectNoSuchMethodInvocation(Expression invocation) {
+      if (invocation is MethodInvocation &&
+          invocation.target is SuperExpression &&
+          invocation.argumentList.arguments.length == 1) {
+        SimpleIdentifier name = invocation.methodName;
+        if (name.name == FunctionElement.NO_SUCH_METHOD_METHOD_NAME) {
+          Element methodElement = name.staticElement;
+          Element classElement = methodElement?.enclosingElement;
+          return methodElement is MethodElement &&
+              classElement is ClassElement &&
+              !classElement.type.isObject;
+        }
+      }
+      return false;
+    }
+    FunctionBody body = node.body;
+    if (body is ExpressionFunctionBody) {
+      if (isNonObjectNoSuchMethodInvocation(body.expression)) {
+        _errorReporter.reportErrorForNode(
+            HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+        return true;
+      }
+    } else if (body is BlockFunctionBody) {
+      List<Statement> statements = body.block.statements;
+      if (statements.length == 1) {
+        Statement returnStatement = statements.first;
+        if (returnStatement is ReturnStatement &&
+            isNonObjectNoSuchMethodInvocation(returnStatement.expression)) {
+          _errorReporter.reportErrorForNode(
+              HintCode.UNNECESSARY_NO_SUCH_METHOD, node);
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  /**
    * Check for situations where the result of a method or function is used, when it returns 'void'.
    *
    * TODO(jwren) Many other situations of use could be covered. We currently cover the cases var x =
@@ -1647,9 +1670,9 @@
 
   @override
   Object visitBinaryExpression(BinaryExpression node) {
-    sc.Token operator = node.operator;
-    bool isAmpAmp = operator.type == sc.TokenType.AMPERSAND_AMPERSAND;
-    bool isBarBar = operator.type == sc.TokenType.BAR_BAR;
+    Token operator = node.operator;
+    bool isAmpAmp = operator.type == TokenType.AMPERSAND_AMPERSAND;
+    bool isBarBar = operator.type == TokenType.BAR_BAR;
     if (isAmpAmp || isBarBar) {
       Expression lhsCondition = node.leftOperand;
       if (!_isDebugConstant(lhsCondition)) {
@@ -2144,7 +2167,7 @@
     ExecutableElement outerExecutable = _enclosingExecutable;
     try {
       SimpleIdentifier functionName = node.name;
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       if (property == null) {
         if (_enclosingExecutable != null) {
           _enclosingExecutable =
@@ -2160,7 +2183,7 @@
         } else {
           PropertyAccessorElement accessor =
               _findIdentifier(_enclosingUnit.accessors, functionName);
-          if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) {
+          if ((property as KeywordToken).keyword == Keyword.SET) {
             accessor = accessor.variable.setter;
             functionName.staticElement = accessor;
           }
@@ -2254,7 +2277,7 @@
   Object visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement outerExecutable = _enclosingExecutable;
     try {
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       SimpleIdentifier methodName = node.name;
       String nameOfMethod = methodName.name;
       if (property == null) {
@@ -2264,7 +2287,7 @@
       } else {
         PropertyAccessorElement accessor =
             _findIdentifier(_enclosingClass.accessors, methodName);
-        if ((property as sc.KeywordToken).keyword == sc.Keyword.SET) {
+        if ((property as KeywordToken).keyword == Keyword.SET) {
           accessor = accessor.variable.setter;
           methodName.staticElement = accessor;
         }
@@ -2894,7 +2917,7 @@
         _inFunction = wasInFunction;
       }
       FunctionBody body = expression.body;
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       if (property == null || _inFunction) {
         SimpleIdentifier functionName = node.name;
         FunctionElementImpl element =
@@ -3123,12 +3146,12 @@
         _inFunction = wasInFunction;
       }
       bool isStatic = node.isStatic;
-      sc.Token property = node.propertyKeyword;
+      Token property = node.propertyKeyword;
       FunctionBody body = node.body;
       if (property == null) {
         SimpleIdentifier methodName = node.name;
         String nameOfMethod = methodName.name;
-        if (nameOfMethod == sc.TokenType.MINUS.lexeme &&
+        if (nameOfMethod == TokenType.MINUS.lexeme &&
             node.parameters.parameters.length == 0) {
           nameOfMethod = "unary-";
         }
@@ -4129,11 +4152,11 @@
     if (_nodeExits(leftHandSide)) {
       return true;
     }
-    if (node.operator.type == sc.TokenType.QUESTION_QUESTION_EQ) {
+    if (node.operator.type == TokenType.QUESTION_QUESTION_EQ) {
       return false;
     }
     if (leftHandSide is PropertyAccess &&
-        leftHandSide.operator.type == sc.TokenType.QUESTION_PERIOD) {
+        leftHandSide.operator.type == TokenType.QUESTION_PERIOD) {
       return false;
     }
     return _nodeExits(node.rightHandSide);
@@ -4147,13 +4170,13 @@
   bool visitBinaryExpression(BinaryExpression node) {
     Expression lhsExpression = node.leftOperand;
     Expression rhsExpression = node.rightOperand;
-    sc.TokenType operatorType = node.operator.type;
+    TokenType operatorType = node.operator.type;
     // If the operator is ||, then only consider the RHS of the binary
     // expression if the left hand side is the false literal.
     // TODO(jwren) Do we want to take constant expressions into account,
     // evaluate if(false) {} differently than if(<condition>), when <condition>
     // evaluates to a constant false value?
-    if (operatorType == sc.TokenType.BAR_BAR) {
+    if (operatorType == TokenType.BAR_BAR) {
       if (lhsExpression is BooleanLiteral) {
         BooleanLiteral booleanLiteral = lhsExpression;
         if (!booleanLiteral.value) {
@@ -4164,7 +4187,7 @@
     }
     // If the operator is &&, then only consider the RHS of the binary
     // expression if the left hand side is the true literal.
-    if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
+    if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
       if (lhsExpression is BooleanLiteral) {
         BooleanLiteral booleanLiteral = lhsExpression;
         if (booleanLiteral.value) {
@@ -4175,7 +4198,7 @@
     }
     // If the operator is ??, then don't consider the RHS of the binary
     // expression.
-    if (operatorType == sc.TokenType.QUESTION_QUESTION) {
+    if (operatorType == TokenType.QUESTION_QUESTION) {
       return _nodeExits(lhsExpression);
     }
     return _nodeExits(lhsExpression) || _nodeExits(rhsExpression);
@@ -4376,7 +4399,7 @@
       if (target.accept(this)) {
         return true;
       }
-      if (node.operator.type == sc.TokenType.QUESTION_PERIOD) {
+      if (node.operator.type == TokenType.QUESTION_PERIOD) {
         return false;
       }
     }
@@ -4898,7 +4921,10 @@
           return;
         }
         if (parent2 is VariableDeclarationList) {
-          return;
+          // If it's a field's type, it still counts as used.
+          if (parent2.parent is! FieldDeclaration) {
+            return;
+          }
         }
       }
     }
@@ -5011,438 +5037,6 @@
 }
 
 /**
- * Instances of the class {@code HtmlTagInfo} record information about the tags used in an HTML
- * file.
- */
-class HtmlTagInfo {
-  /**
-   * An array containing all of the tags used in the HTML file.
-   */
-  List<String> allTags;
-
-  /**
-   * A table mapping the id's defined in the HTML file to an array containing the names of tags with
-   * that identifier.
-   */
-  HashMap<String, String> idToTagMap;
-
-  /**
-   * A table mapping the classes defined in the HTML file to an array containing the names of tags
-   * with that class.
-   */
-  HashMap<String, List<String>> classToTagsMap;
-
-  /**
-   * Initialize a newly created information holder to hold the given information about the tags in
-   * an HTML file.
-   *
-   * @param allTags an array containing all of the tags used in the HTML file
-   * @param idToTagMap a table mapping the id's defined in the HTML file to an array containing the
-   *          names of tags with that identifier
-   * @param classToTagsMap a table mapping the classes defined in the HTML file to an array
-   *          containing the names of tags with that class
-   */
-  HtmlTagInfo(this.allTags, this.idToTagMap, this.classToTagsMap);
-
-  /**
-   * Return an array containing the tags that have the given class, or {@code null} if there are no
-   * such tags.
-   *
-   * @return an array containing the tags that have the given class
-   */
-  List<String> getTagsWithClass(String identifier) {
-    return classToTagsMap[identifier];
-  }
-
-  /**
-   * Return the tag that has the given identifier, or {@code null} if there is no such tag (the
-   * identifier is not defined).
-   *
-   * @return the tag that has the given identifier
-   */
-  String getTagWithId(String identifier) {
-    return idToTagMap[identifier];
-  }
-}
-
-/**
- * Instances of the class {@code HtmlTagInfoBuilder} gather information about the tags used in one
- * or more HTML structures.
- */
-class HtmlTagInfoBuilder implements ht.XmlVisitor {
-  /**
-   * The name of the 'id' attribute.
-   */
-  static final String ID_ATTRIBUTE = "id";
-
-  /**
-   * The name of the 'class' attribute.
-   */
-  static final String ID_CLASS = "class";
-
-  /**
-   * A set containing all of the tag names used in the HTML.
-   */
-  HashSet<String> tagSet = new HashSet<String>();
-
-  /**
-   * A table mapping the id's that are defined to the tag name with that id.
-   */
-  HashMap<String, String> idMap = new HashMap<String, String>();
-
-  /**
-   * A table mapping the classes that are defined to a set of the tag names with that class.
-   */
-  HashMap<String, HashSet<String>> classMap =
-      new HashMap<String, HashSet<String>>();
-
-  /**
-   * Initialize a newly created HTML tag info builder.
-   */
-  HtmlTagInfoBuilder();
-
-  /**
-   * Create a tag information holder holding all of the information gathered about the tags in the
-   * HTML structures that were visited.
-   *
-   * @return the information gathered about the tags in the visited HTML structures
-   */
-  HtmlTagInfo getTagInfo() {
-    List<String> allTags = tagSet.toList();
-    HashMap<String, List<String>> classToTagsMap =
-        new HashMap<String, List<String>>();
-    classMap.forEach((String key, Set<String> tags) {
-      classToTagsMap[key] = tags.toList();
-    });
-    return new HtmlTagInfo(allTags, idMap, classToTagsMap);
-  }
-
-  @override
-  visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    visitXmlTagNode(node);
-  }
-
-  @override
-  visitHtmlUnit(ht.HtmlUnit node) {
-    node.visitChildren(this);
-  }
-
-  @override
-  visitXmlAttributeNode(ht.XmlAttributeNode node) {}
-
-  @override
-  visitXmlTagNode(ht.XmlTagNode node) {
-    node.visitChildren(this);
-    String tagName = node.tag;
-    tagSet.add(tagName);
-    for (ht.XmlAttributeNode attribute in node.attributes) {
-      String attributeName = attribute.name;
-      if (attributeName == ID_ATTRIBUTE) {
-        String attributeValue = attribute.text;
-        if (attributeValue != null) {
-          String tag = idMap[attributeValue];
-          if (tag == null) {
-            idMap[attributeValue] = tagName;
-          } else {
-//            reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken);
-          }
-        }
-      } else if (attributeName == ID_CLASS) {
-        String attributeValue = attribute.text;
-        if (attributeValue != null) {
-          HashSet<String> tagList = classMap[attributeValue];
-          if (tagList == null) {
-            tagList = new HashSet<String>();
-            classMap[attributeValue] = tagList;
-          } else {
-//            reportError(HtmlWarningCode.MULTIPLY_DEFINED_ID, valueToken);
-          }
-          tagList.add(tagName);
-        }
-      }
-    }
-  }
-
-//  /**
-//   * Report an error with the given error code at the given location. Use the given arguments to
-//   * compose the error message.
-//   *
-//   * @param errorCode the error code of the error to be reported
-//   * @param offset the offset of the first character to be highlighted
-//   * @param length the number of characters to be highlighted
-//   * @param arguments the arguments used to compose the error message
-//   */
-//  private void reportError(ErrorCode errorCode, Token token, Object... arguments) {
-//    errorListener.onError(new AnalysisError(
-//        htmlElement.getSource(),
-//        token.getOffset(),
-//        token.getLength(),
-//        errorCode,
-//        arguments));
-//  }
-//
-//  /**
-//   * Report an error with the given error code at the given location. Use the given arguments to
-//   * compose the error message.
-//   *
-//   * @param errorCode the error code of the error to be reported
-//   * @param offset the offset of the first character to be highlighted
-//   * @param length the number of characters to be highlighted
-//   * @param arguments the arguments used to compose the error message
-//   */
-//  private void reportError(ErrorCode errorCode, int offset, int length, Object... arguments) {
-//    errorListener.onError(new AnalysisError(
-//        htmlElement.getSource(),
-//        offset,
-//        length,
-//        errorCode,
-//        arguments));
-//  }
-}
-
-/**
- * Instances of the class `HtmlUnitBuilder` build an element model for a single HTML unit.
- */
-class HtmlUnitBuilder implements ht.XmlVisitor<Object> {
-  static String _SRC = "src";
-
-  /**
-   * The analysis context in which the element model will be built.
-   */
-  final InternalAnalysisContext _context;
-
-  /**
-   * The error listener to which errors will be reported.
-   */
-  RecordingErrorListener _errorListener;
-
-  /**
-   * The HTML element being built.
-   */
-  HtmlElementImpl _htmlElement;
-
-  /**
-   * The elements in the path from the HTML unit to the current tag node.
-   */
-  List<ht.XmlTagNode> _parentNodes;
-
-  /**
-   * The script elements being built.
-   */
-  List<HtmlScriptElement> _scripts;
-
-  /**
-   * A set of the libraries that were resolved while resolving the HTML unit.
-   */
-  Set<Library> _resolvedLibraries = new HashSet<Library>();
-
-  /**
-   * Initialize a newly created HTML unit builder.
-   *
-   * @param context the analysis context in which the element model will be built
-   */
-  HtmlUnitBuilder(this._context) {
-    this._errorListener = new RecordingErrorListener();
-  }
-
-  /**
-   * Return the listener to which analysis errors will be reported.
-   *
-   * @return the listener to which analysis errors will be reported
-   */
-  RecordingErrorListener get errorListener => _errorListener;
-
-  /**
-   * Return an array containing information about all of the libraries that were resolved.
-   *
-   * @return an array containing the libraries that were resolved
-   */
-  Set<Library> get resolvedLibraries => _resolvedLibraries;
-
-  /**
-   * Build the HTML element for the given source.
-   *
-   * @param source the source describing the compilation unit
-   * @param unit the AST structure representing the HTML
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  HtmlElementImpl buildHtmlElement(Source source, ht.HtmlUnit unit) {
-    HtmlElementImpl result = new HtmlElementImpl(_context, source.shortName);
-    result.source = source;
-    _htmlElement = result;
-    unit.accept(this);
-    _htmlElement = null;
-    unit.element = result;
-    return result;
-  }
-
-  @override
-  Object visitHtmlScriptTagNode(ht.HtmlScriptTagNode node) {
-    if (_parentNodes.contains(node)) {
-      return _reportCircularity(node);
-    }
-    _parentNodes.add(node);
-    try {
-      Source htmlSource = _htmlElement.source;
-      ht.XmlAttributeNode scriptAttribute = _getScriptSourcePath(node);
-      String scriptSourcePath =
-          scriptAttribute == null ? null : scriptAttribute.text;
-      if (node.attributeEnd.type == ht.TokenType.GT &&
-          scriptSourcePath == null) {
-        EmbeddedHtmlScriptElementImpl script =
-            new EmbeddedHtmlScriptElementImpl(node);
-        try {
-          LibraryResolver resolver = new LibraryResolver(_context);
-          LibraryElementImpl library =
-              resolver.resolveEmbeddedLibrary(htmlSource, node.script, true);
-          script.scriptLibrary = library;
-          _resolvedLibraries.addAll(resolver.resolvedLibraries);
-          _errorListener.addAll(resolver.errorListener);
-        } on AnalysisException catch (exception, stackTrace) {
-          //TODO (danrubel): Handle or forward the exception
-          AnalysisEngine.instance.logger.logError(
-              "Could not resolve script tag",
-              new CaughtException(exception, stackTrace));
-        }
-        node.scriptElement = script;
-        _scripts.add(script);
-      } else {
-        ExternalHtmlScriptElementImpl script =
-            new ExternalHtmlScriptElementImpl(node);
-        if (scriptSourcePath != null) {
-          try {
-            scriptSourcePath = Uri.encodeFull(scriptSourcePath);
-            // Force an exception to be thrown if the URI is invalid so that we
-            // can report the problem.
-            parseUriWithException(scriptSourcePath);
-            Source scriptSource =
-                _context.sourceFactory.resolveUri(htmlSource, scriptSourcePath);
-            script.scriptSource = scriptSource;
-            if (!_context.exists(scriptSource)) {
-              _reportValueError(HtmlWarningCode.URI_DOES_NOT_EXIST,
-                  scriptAttribute, [scriptSourcePath]);
-            }
-          } on URISyntaxException {
-            _reportValueError(HtmlWarningCode.INVALID_URI, scriptAttribute,
-                [scriptSourcePath]);
-          }
-        }
-        node.scriptElement = script;
-        _scripts.add(script);
-      }
-    } finally {
-      _parentNodes.remove(node);
-    }
-    return null;
-  }
-
-  @override
-  Object visitHtmlUnit(ht.HtmlUnit node) {
-    _parentNodes = new List<ht.XmlTagNode>();
-    _scripts = new List<HtmlScriptElement>();
-    try {
-      node.visitChildren(this);
-      _htmlElement.scripts = new List.from(_scripts);
-    } finally {
-      _scripts = null;
-      _parentNodes = null;
-    }
-    return null;
-  }
-
-  @override
-  Object visitXmlAttributeNode(ht.XmlAttributeNode node) => null;
-
-  @override
-  Object visitXmlTagNode(ht.XmlTagNode node) {
-    if (_parentNodes.contains(node)) {
-      return _reportCircularity(node);
-    }
-    _parentNodes.add(node);
-    try {
-      node.visitChildren(this);
-    } finally {
-      _parentNodes.remove(node);
-    }
-    return null;
-  }
-
-  /**
-   * Return the first source attribute for the given tag node, or `null` if it does not exist.
-   *
-   * @param node the node containing attributes
-   * @return the source attribute contained in the given tag
-   */
-  ht.XmlAttributeNode _getScriptSourcePath(ht.XmlTagNode node) {
-    for (ht.XmlAttributeNode attribute in node.attributes) {
-      if (attribute.name == _SRC) {
-        return attribute;
-      }
-    }
-    return null;
-  }
-
-  Object _reportCircularity(ht.XmlTagNode node) {
-    //
-    // This should not be possible, but we have an error report that suggests
-    // that it happened at least once. This code will guard against infinite
-    // recursion and might help us identify the cause of the issue.
-    //
-    StringBuffer buffer = new StringBuffer();
-    buffer.write("Found circularity in XML nodes: ");
-    bool first = true;
-    for (ht.XmlTagNode pathNode in _parentNodes) {
-      if (first) {
-        first = false;
-      } else {
-        buffer.write(", ");
-      }
-      String tagName = pathNode.tag;
-      if (identical(pathNode, node)) {
-        buffer.write("*");
-        buffer.write(tagName);
-        buffer.write("*");
-      } else {
-        buffer.write(tagName);
-      }
-    }
-    AnalysisEngine.instance.logger.logError(buffer.toString());
-    return null;
-  }
-
-  /**
-   * Report an error with the given error code at the given location. Use the given arguments to
-   * compose the error message.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param offset the offset of the first character to be highlighted
-   * @param length the number of characters to be highlighted
-   * @param arguments the arguments used to compose the error message
-   */
-  void _reportErrorForOffset(
-      ErrorCode errorCode, int offset, int length, List<Object> arguments) {
-    _errorListener.onError(new AnalysisError(
-        _htmlElement.source, offset, length, errorCode, arguments));
-  }
-
-  /**
-   * Report an error with the given error code at the location of the value of the given attribute.
-   * Use the given arguments to compose the error message.
-   *
-   * @param errorCode the error code of the error to be reported
-   * @param offset the offset of the first character to be highlighted
-   * @param length the number of characters to be highlighted
-   * @param arguments the arguments used to compose the error message
-   */
-  void _reportValueError(ErrorCode errorCode, ht.XmlAttributeNode attribute,
-      List<Object> arguments) {
-    int offset = attribute.valueToken.offset + 1;
-    int length = attribute.valueToken.length - 2;
-    _reportErrorForOffset(errorCode, offset, length, arguments);
-  }
-}
-
-/**
  * Instances of the class `ImplicitLabelScope` represent the scope statements
  * that can be the target of unlabeled break and continue statements.
  */
@@ -5792,11 +5386,6 @@
   final TypeSystem _typeSystem;
 
   /**
-   * The DDC type rules, used to create the inference info nodes.
-   */
-  final TypeRules _rules;
-
-  /**
    * A stack of return types for all of the enclosing
    * functions and methods.
    */
@@ -5804,8 +5393,7 @@
 
   InferenceContext._(this._errorListener, TypeProvider typeProvider,
       this._typeSystem, this._inferenceHints)
-      : _typeProvider = typeProvider,
-        _rules = new TypeRules(typeProvider);
+      : _typeProvider = typeProvider;
 
   /**
    * Get the return type of the current enclosing function, if any.
@@ -5846,7 +5434,7 @@
    * [type] has been inferred as the type of [node].
    */
   void recordInference(Expression node, DartType type) {
-    StaticInfo info = InferredType.create(_rules, node, type);
+    StaticInfo info = InferredType.create(_typeSystem, node, type);
     if (!_inferenceHints || info == null) {
       return;
     }
@@ -6905,7 +6493,7 @@
       List<String> namedParameters) {
     DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
     SimpleIdentifier nameIdentifier = new SimpleIdentifier(
-        new sc.StringToken(sc.TokenType.IDENTIFIER, name, 0));
+        new StringToken(TokenType.IDENTIFIER, name, 0));
     ExecutableElementImpl executable;
     if (elementArrayToMerge[0] is MethodElement) {
       MultiplyInheritedMethodElementImpl unionedMethod =
@@ -7094,652 +6682,6 @@
 }
 
 /**
- * Instances of the class `Library` represent the data about a single library during the
- * resolution of some (possibly different) library. They are not intended to be used except during
- * the resolution process.
- */
-class Library {
-  /**
-   * An empty list that can be used to initialize lists of libraries.
-   */
-  static const List<Library> _EMPTY_ARRAY = const <Library>[];
-
-  /**
-   * The prefix of a URI using the dart-ext scheme to reference a native code library.
-   */
-  static String _DART_EXT_SCHEME = "dart-ext:";
-
-  /**
-   * The analysis context in which this library is being analyzed.
-   */
-  final InternalAnalysisContext _analysisContext;
-
-  /**
-   * The inheritance manager which is used for this member lookups in this library.
-   */
-  InheritanceManager _inheritanceManager;
-
-  /**
-   * The listener to which analysis errors will be reported.
-   */
-  final AnalysisErrorListener errorListener;
-
-  /**
-   * The source specifying the defining compilation unit of this library.
-   */
-  final Source librarySource;
-
-  /**
-   * The library element representing this library.
-   */
-  LibraryElementImpl _libraryElement;
-
-  /**
-   * A list containing all of the libraries that are imported into this library.
-   */
-  List<Library> _importedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * A table mapping URI-based directive to the actual URI value.
-   */
-  HashMap<UriBasedDirective, String> _directiveUris =
-      new HashMap<UriBasedDirective, String>();
-
-  /**
-   * A flag indicating whether this library explicitly imports core.
-   */
-  bool explicitlyImportsCore = false;
-
-  /**
-   * A list containing all of the libraries that are exported from this library.
-   */
-  List<Library> _exportedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * A table mapping the sources for the compilation units in this library to their corresponding
-   * AST structures.
-   */
-  HashMap<Source, CompilationUnit> _astMap =
-      new HashMap<Source, CompilationUnit>();
-
-  /**
-   * The library scope used when resolving elements within this library's compilation units.
-   */
-  LibraryScope _libraryScope;
-
-  /**
-   * Initialize a newly created data holder that can maintain the data associated with a library.
-   *
-   * @param analysisContext the analysis context in which this library is being analyzed
-   * @param errorListener the listener to which analysis errors will be reported
-   * @param librarySource the source specifying the defining compilation unit of this library
-   */
-  Library(this._analysisContext, this.errorListener, this.librarySource) {
-    this._libraryElement =
-        _analysisContext.getLibraryElement(librarySource) as LibraryElementImpl;
-  }
-
-  /**
-   * Return an array of the [CompilationUnit]s that make up the library. The first unit is
-   * always the defining unit.
-   *
-   * @return an array of the [CompilationUnit]s that make up the library. The first unit is
-   *         always the defining unit
-   */
-  List<CompilationUnit> get compilationUnits {
-    List<CompilationUnit> unitArrayList = new List<CompilationUnit>();
-    unitArrayList.add(definingCompilationUnit);
-    for (Source source in _astMap.keys.toSet()) {
-      if (librarySource != source) {
-        unitArrayList.add(getAST(source));
-      }
-    }
-    return unitArrayList;
-  }
-
-  /**
-   * Return a collection containing the sources for the compilation units in this library, including
-   * the defining compilation unit.
-   *
-   * @return the sources for the compilation units in this library
-   */
-  Set<Source> get compilationUnitSources => _astMap.keys.toSet();
-
-  /**
-   * Return the AST structure associated with the defining compilation unit for this library.
-   *
-   * @return the AST structure associated with the defining compilation unit for this library
-   * @throws AnalysisException if an AST structure could not be created for the defining compilation
-   *           unit
-   */
-  CompilationUnit get definingCompilationUnit => getAST(librarySource);
-
-  /**
-   * Set the libraries that are exported by this library to be those in the given array.
-   *
-   * @param exportedLibraries the libraries that are exported by this library
-   */
-  void set exportedLibraries(List<Library> exportedLibraries) {
-    this._exportedLibraries = exportedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are exported from this library.
-   *
-   * @return an array containing the libraries that are exported from this library
-   */
-  List<Library> get exports => _exportedLibraries;
-
-  /**
-   * Set the libraries that are imported into this library to be those in the given array.
-   *
-   * @param importedLibraries the libraries that are imported into this library
-   */
-  void set importedLibraries(List<Library> importedLibraries) {
-    this._importedLibraries = importedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are imported into this library.
-   *
-   * @return an array containing the libraries that are imported into this library
-   */
-  List<Library> get imports => _importedLibraries;
-
-  /**
-   * Return an array containing the libraries that are either imported or exported from this
-   * library.
-   *
-   * @return the libraries that are either imported or exported from this library
-   */
-  List<Library> get importsAndExports {
-    HashSet<Library> libraries = new HashSet<Library>();
-    for (Library library in _importedLibraries) {
-      libraries.add(library);
-    }
-    for (Library library in _exportedLibraries) {
-      libraries.add(library);
-    }
-    return new List.from(libraries);
-  }
-
-  /**
-   * Return the inheritance manager for this library.
-   *
-   * @return the inheritance manager for this library
-   */
-  InheritanceManager get inheritanceManager {
-    if (_inheritanceManager == null) {
-      return _inheritanceManager = new InheritanceManager(_libraryElement);
-    }
-    return _inheritanceManager;
-  }
-
-  /**
-   * Return the library element representing this library, creating it if necessary.
-   *
-   * @return the library element representing this library
-   */
-  LibraryElementImpl get libraryElement {
-    if (_libraryElement == null) {
-      try {
-        _libraryElement = _analysisContext.computeLibraryElement(librarySource)
-            as LibraryElementImpl;
-      } on AnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logError(
-            "Could not compute library element for ${librarySource.fullName}",
-            new CaughtException(exception, stackTrace));
-      }
-    }
-    return _libraryElement;
-  }
-
-  /**
-   * Set the library element representing this library to the given library element.
-   *
-   * @param libraryElement the library element representing this library
-   */
-  void set libraryElement(LibraryElementImpl libraryElement) {
-    this._libraryElement = libraryElement;
-    if (_inheritanceManager != null) {
-      _inheritanceManager.libraryElement = libraryElement;
-    }
-  }
-
-  /**
-   * Return the library scope used when resolving elements within this library's compilation units.
-   *
-   * @return the library scope used when resolving elements within this library's compilation units
-   */
-  LibraryScope get libraryScope {
-    if (_libraryScope == null) {
-      _libraryScope = new LibraryScope(_libraryElement, errorListener);
-    }
-    return _libraryScope;
-  }
-
-  /**
-   * Return the AST structure associated with the given source.
-   *
-   * @param source the source representing the compilation unit whose AST is to be returned
-   * @return the AST structure associated with the given source
-   * @throws AnalysisException if an AST structure could not be created for the compilation unit
-   */
-  CompilationUnit getAST(Source source) {
-    CompilationUnit unit = _astMap[source];
-    if (unit == null) {
-      unit = _analysisContext.computeResolvableCompilationUnit(source);
-      _astMap[source] = unit;
-    }
-    return unit;
-  }
-
-  /**
-   * Return the result of resolving the URI of the given URI-based directive against the URI of the
-   * library, or `null` if the URI is not valid. If the URI is not valid, report the error.
-   *
-   * @param directive the directive which URI should be resolved
-   * @return the result of resolving the URI against the URI of the library
-   */
-  Source getSource(UriBasedDirective directive) {
-    StringLiteral uriLiteral = directive.uri;
-    if (uriLiteral is StringInterpolation) {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.URI_WITH_INTERPOLATION));
-      return null;
-    }
-    String uriContent = uriLiteral.stringValue.trim();
-    _directiveUris[directive] = uriContent;
-    uriContent = Uri.encodeFull(uriContent);
-    if (directive is ImportDirective &&
-        uriContent.startsWith(_DART_EXT_SCHEME)) {
-      _libraryElement.hasExtUri = true;
-      return null;
-    }
-    try {
-      parseUriWithException(uriContent);
-      Source source =
-          _analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
-      if (!_analysisContext.exists(source)) {
-        errorListener.onError(new AnalysisError(
-            librarySource,
-            uriLiteral.offset,
-            uriLiteral.length,
-            CompileTimeErrorCode.URI_DOES_NOT_EXIST,
-            [uriContent]));
-      }
-      return source;
-    } on URISyntaxException {
-      errorListener.onError(new AnalysisError(librarySource, uriLiteral.offset,
-          uriLiteral.length, CompileTimeErrorCode.INVALID_URI, [uriContent]));
-    }
-    return null;
-  }
-
-  /**
-   * Returns the URI value of the given directive.
-   */
-  String getUri(UriBasedDirective directive) => _directiveUris[directive];
-
-  /**
-   * Set the AST structure associated with the defining compilation unit for this library to the
-   * given AST structure.
-   *
-   * @param unit the AST structure associated with the defining compilation unit for this library
-   */
-  void setDefiningCompilationUnit(CompilationUnit unit) {
-    _astMap[librarySource] = unit;
-  }
-
-  @override
-  String toString() => librarySource.shortName;
-}
-
-/**
- * Instances of the class `LibraryElementBuilder` build an element model for a single library.
- */
-class LibraryElementBuilder {
-  /**
-   * The analysis context in which the element model will be built.
-   */
-  final InternalAnalysisContext _analysisContext;
-
-  /**
-   * The listener to which errors will be reported.
-   */
-  final AnalysisErrorListener _errorListener;
-
-  /**
-   * Initialize a newly created library element builder.
-   *
-   * @param analysisContext the analysis context in which the element model will be built
-   * @param errorListener the listener to which errors will be reported
-   */
-  LibraryElementBuilder(this._analysisContext, this._errorListener);
-
-  /**
-   * Build the library element for the given library.
-   *
-   * @param library the library for which an element model is to be built
-   * @return the library element that was built
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  LibraryElementImpl buildLibrary(Library library) {
-    CompilationUnitBuilder builder = new CompilationUnitBuilder();
-    Source librarySource = library.librarySource;
-    CompilationUnit definingCompilationUnit = library.definingCompilationUnit;
-    CompilationUnitElementImpl definingCompilationUnitElement = builder
-        .buildCompilationUnit(
-            librarySource, definingCompilationUnit, librarySource);
-    NodeList<Directive> directives = definingCompilationUnit.directives;
-    LibraryDirective libraryDirective = null;
-    LibraryIdentifier libraryNameNode = null;
-    bool hasPartDirective = false;
-    FunctionElement entryPoint =
-        _findEntryPoint(definingCompilationUnitElement);
-    List<Directive> directivesToResolve = new List<Directive>();
-    List<CompilationUnitElementImpl> sourcedCompilationUnits =
-        new List<CompilationUnitElementImpl>();
-    for (Directive directive in directives) {
-      //
-      // We do not build the elements representing the import and export
-      // directives at this point. That is not done until we get to
-      // LibraryResolver.buildDirectiveModels() because we need the
-      // LibraryElements for the referenced libraries, which might not exist at
-      // this point (due to the possibility of circular references).
-      //
-      if (directive is LibraryDirective) {
-        if (libraryNameNode == null) {
-          libraryDirective = directive;
-          libraryNameNode = directive.name;
-          directivesToResolve.add(directive);
-        }
-      } else if (directive is PartDirective) {
-        PartDirective partDirective = directive;
-        StringLiteral partUri = partDirective.uri;
-        Source partSource = partDirective.source;
-        if (_analysisContext.exists(partSource)) {
-          hasPartDirective = true;
-          CompilationUnit partUnit = library.getAST(partSource);
-          CompilationUnitElementImpl part =
-              builder.buildCompilationUnit(partSource, partUnit, librarySource);
-          part.uriOffset = partUri.offset;
-          part.uriEnd = partUri.end;
-          part.uri = partDirective.uriContent;
-          //
-          // Validate that the part contains a part-of directive with the same
-          // name as the library.
-          //
-          String partLibraryName =
-              _getPartLibraryName(partSource, partUnit, directivesToResolve);
-          if (partLibraryName == null) {
-            _errorListener.onError(new AnalysisError(
-                librarySource,
-                partUri.offset,
-                partUri.length,
-                CompileTimeErrorCode.PART_OF_NON_PART,
-                [partUri.toSource()]));
-          } else if (libraryNameNode == null) {
-            // TODO(brianwilkerson) Collect the names declared by the part.
-            // If they are all the same then we can use that name as the
-            // inferred name of the library and present it in a quick-fix.
-            // partLibraryNames.add(partLibraryName);
-          } else if (libraryNameNode.name != partLibraryName) {
-            _errorListener.onError(new AnalysisError(
-                librarySource,
-                partUri.offset,
-                partUri.length,
-                StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
-                [libraryNameNode.name, partLibraryName]));
-          }
-          if (entryPoint == null) {
-            entryPoint = _findEntryPoint(part);
-          }
-          directive.element = part;
-          sourcedCompilationUnits.add(part);
-        }
-      }
-    }
-    if (hasPartDirective && libraryNameNode == null) {
-      _errorListener.onError(new AnalysisError(librarySource, 0, 0,
-          ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART));
-    }
-    //
-    // Create and populate the library element.
-    //
-    LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
-        _analysisContext.getContextFor(librarySource), libraryNameNode);
-    _setDocRange(libraryElement, libraryDirective);
-    libraryElement.definingCompilationUnit = definingCompilationUnitElement;
-    if (entryPoint != null) {
-      libraryElement.entryPoint = entryPoint;
-    }
-    int sourcedUnitCount = sourcedCompilationUnits.length;
-    libraryElement.parts = sourcedCompilationUnits;
-    for (Directive directive in directivesToResolve) {
-      directive.element = libraryElement;
-    }
-    library.libraryElement = libraryElement;
-    if (sourcedUnitCount > 0) {
-      _patchTopLevelAccessors(libraryElement);
-    }
-    return libraryElement;
-  }
-
-  /**
-   * Build the library element for the given library.  The resulting element is
-   * stored in the [ResolvableLibrary] structure.
-   *
-   * @param library the library for which an element model is to be built
-   * @throws AnalysisException if the analysis could not be performed
-   */
-  void buildLibrary2(ResolvableLibrary library) {
-    CompilationUnitBuilder builder = new CompilationUnitBuilder();
-    Source librarySource = library.librarySource;
-    CompilationUnit definingCompilationUnit = library.definingCompilationUnit;
-    CompilationUnitElementImpl definingCompilationUnitElement = builder
-        .buildCompilationUnit(
-            librarySource, definingCompilationUnit, librarySource);
-    NodeList<Directive> directives = definingCompilationUnit.directives;
-    LibraryDirective libraryDirective = null;
-    LibraryIdentifier libraryNameNode = null;
-    bool hasPartDirective = false;
-    FunctionElement entryPoint =
-        _findEntryPoint(definingCompilationUnitElement);
-    List<Directive> directivesToResolve = new List<Directive>();
-    List<CompilationUnitElementImpl> sourcedCompilationUnits =
-        new List<CompilationUnitElementImpl>();
-    for (Directive directive in directives) {
-      //
-      // We do not build the elements representing the import and export
-      // directives at this point. That is not done until we get to
-      // LibraryResolver.buildDirectiveModels() because we need the
-      // LibraryElements for the referenced libraries, which might not exist at
-      // this point (due to the possibility of circular references).
-      //
-      if (directive is LibraryDirective) {
-        if (libraryNameNode == null) {
-          libraryDirective = directive;
-          libraryNameNode = directive.name;
-          directivesToResolve.add(directive);
-        }
-      } else if (directive is PartDirective) {
-        PartDirective partDirective = directive;
-        StringLiteral partUri = partDirective.uri;
-        Source partSource = partDirective.source;
-        if (_analysisContext.exists(partSource)) {
-          hasPartDirective = true;
-          CompilationUnit partUnit = library.getAST(partSource);
-          if (partUnit != null) {
-            CompilationUnitElementImpl part = builder.buildCompilationUnit(
-                partSource, partUnit, librarySource);
-            part.uriOffset = partUri.offset;
-            part.uriEnd = partUri.end;
-            part.uri = partDirective.uriContent;
-            //
-            // Validate that the part contains a part-of directive with the same
-            // name as the library.
-            //
-            String partLibraryName =
-                _getPartLibraryName(partSource, partUnit, directivesToResolve);
-            if (partLibraryName == null) {
-              _errorListener.onError(new AnalysisError(
-                  librarySource,
-                  partUri.offset,
-                  partUri.length,
-                  CompileTimeErrorCode.PART_OF_NON_PART,
-                  [partUri.toSource()]));
-            } else if (libraryNameNode == null) {
-              // TODO(brianwilkerson) Collect the names declared by the part.
-              // If they are all the same then we can use that name as the
-              // inferred name of the library and present it in a quick-fix.
-              // partLibraryNames.add(partLibraryName);
-            } else if (libraryNameNode.name != partLibraryName) {
-              _errorListener.onError(new AnalysisError(
-                  librarySource,
-                  partUri.offset,
-                  partUri.length,
-                  StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
-                  [libraryNameNode.name, partLibraryName]));
-            }
-            if (entryPoint == null) {
-              entryPoint = _findEntryPoint(part);
-            }
-            directive.element = part;
-            sourcedCompilationUnits.add(part);
-          }
-        }
-      }
-    }
-    if (hasPartDirective && libraryNameNode == null) {
-      _errorListener.onError(new AnalysisError(librarySource, 0, 0,
-          ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART));
-    }
-    //
-    // Create and populate the library element.
-    //
-    LibraryElementImpl libraryElement = new LibraryElementImpl.forNode(
-        _analysisContext.getContextFor(librarySource), libraryNameNode);
-    _setDocRange(libraryElement, libraryDirective);
-    libraryElement.definingCompilationUnit = definingCompilationUnitElement;
-    if (entryPoint != null) {
-      libraryElement.entryPoint = entryPoint;
-    }
-    int sourcedUnitCount = sourcedCompilationUnits.length;
-    libraryElement.parts = sourcedCompilationUnits;
-    for (Directive directive in directivesToResolve) {
-      directive.element = libraryElement;
-    }
-    library.libraryElement = libraryElement;
-    if (sourcedUnitCount > 0) {
-      _patchTopLevelAccessors(libraryElement);
-    }
-  }
-
-  /**
-   * Add all of the non-synthetic getters and setters defined in the given compilation unit that
-   * have no corresponding accessor to one of the given collections.
-   *
-   * @param getters the map to which getters are to be added
-   * @param setters the list to which setters are to be added
-   * @param unit the compilation unit defining the accessors that are potentially being added
-   */
-  void _collectAccessors(HashMap<String, PropertyAccessorElement> getters,
-      List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
-    for (PropertyAccessorElement accessor in unit.accessors) {
-      if (accessor.isGetter) {
-        if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
-          getters[accessor.displayName] = accessor;
-        }
-      } else {
-        if (!accessor.isSynthetic && accessor.correspondingGetter == null) {
-          setters.add(accessor);
-        }
-      }
-    }
-  }
-
-  /**
-   * Search the top-level functions defined in the given compilation unit for the entry point.
-   *
-   * @param element the compilation unit to be searched
-   * @return the entry point that was found, or `null` if the compilation unit does not define
-   *         an entry point
-   */
-  FunctionElement _findEntryPoint(CompilationUnitElementImpl element) {
-    for (FunctionElement function in element.functions) {
-      if (function.isEntryPoint) {
-        return function;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Return the name of the library that the given part is declared to be a part of, or `null`
-   * if the part does not contain a part-of directive.
-   *
-   * @param partSource the source representing the part
-   * @param partUnit the AST structure of the part
-   * @param directivesToResolve a list of directives that should be resolved to the library being
-   *          built
-   * @return the name of the library that the given part is declared to be a part of
-   */
-  String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
-      List<Directive> directivesToResolve) {
-    for (Directive directive in partUnit.directives) {
-      if (directive is PartOfDirective) {
-        directivesToResolve.add(directive);
-        LibraryIdentifier libraryName = directive.libraryName;
-        if (libraryName != null) {
-          return libraryName.name;
-        }
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Look through all of the compilation units defined for the given library, looking for getters
-   * and setters that are defined in different compilation units but that have the same names. If
-   * any are found, make sure that they have the same variable element.
-   *
-   * @param libraryElement the library defining the compilation units to be processed
-   */
-  void _patchTopLevelAccessors(LibraryElementImpl libraryElement) {
-    HashMap<String, PropertyAccessorElement> getters =
-        new HashMap<String, PropertyAccessorElement>();
-    List<PropertyAccessorElement> setters = new List<PropertyAccessorElement>();
-    _collectAccessors(getters, setters, libraryElement.definingCompilationUnit);
-    for (CompilationUnitElement unit in libraryElement.parts) {
-      _collectAccessors(getters, setters, unit);
-    }
-    for (PropertyAccessorElement setter in setters) {
-      PropertyAccessorElement getter = getters[setter.displayName];
-      if (getter != null) {
-        PropertyInducingElementImpl variable =
-            getter.variable as PropertyInducingElementImpl;
-        variable.setter = setter;
-        (setter as PropertyAccessorElementImpl).variable = variable;
-      }
-    }
-  }
-
-  /**
-   * If the given [node] has a documentation comment, remember its range
-   * into the given [element].
-   */
-  void _setDocRange(ElementImpl element, LibraryDirective node) {
-    if (node != null) {
-      Comment comment = node.documentationComment;
-      if (comment != null && comment.isDocumentation) {
-        element.setDocRange(comment.offset, comment.length);
-      }
-    }
-  }
-}
-
-/**
  * Instances of the class `LibraryImportScope` represent the scope containing all of the names
  * available from imported libraries.
  */
@@ -7951,1374 +6893,11 @@
  * Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
  * libraries within a single context.
  */
-class LibraryResolver {
-  /**
-   * The analysis context in which the libraries are being analyzed.
-   */
-  final InternalAnalysisContext analysisContext;
-
-  /**
-   * The listener to which analysis errors will be reported, this error listener is either
-   * references [recordingErrorListener], or it unions the passed
-   * [AnalysisErrorListener] with the [recordingErrorListener].
-   */
-  RecordingErrorListener _errorListener;
-
-  /**
-   * A source object representing the core library (dart:core).
-   */
-  Source _coreLibrarySource;
-
-  /**
-   * A Source object representing the async library (dart:async).
-   */
-  Source _asyncLibrarySource;
-
-  /**
-   * The object representing the core library.
-   */
-  Library _coreLibrary;
-
-  /**
-   * The object representing the async library.
-   */
-  Library _asyncLibrary;
-
-  /**
-   * The object used to access the types from the core library.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * The type system in use for the library
-   */
-  TypeSystem _typeSystem;
-
-  /**
-   * A table mapping library sources to the information being maintained for those libraries.
-   */
-  HashMap<Source, Library> _libraryMap = new HashMap<Source, Library>();
-
-  /**
-   * A collection containing the libraries that are being resolved together.
-   */
-  Set<Library> _librariesInCycles;
-
-  /**
-   * Initialize a newly created library resolver to resolve libraries within the given context.
-   *
-   * @param analysisContext the analysis context in which the library is being analyzed
-   */
-  LibraryResolver(this.analysisContext) {
-    this._errorListener = new RecordingErrorListener();
-    _coreLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC);
-  }
-
-  /**
-   * Return the listener to which analysis errors will be reported.
-   *
-   * @return the listener to which analysis errors will be reported
-   */
-  RecordingErrorListener get errorListener => _errorListener;
-
-  /**
-   * Return an array containing information about all of the libraries that were resolved.
-   *
-   * @return an array containing the libraries that were resolved
-   */
-  Set<Library> get resolvedLibraries => _librariesInCycles;
-
-  /**
-   * The object used to access the types from the core library.
-   */
-  TypeProvider get typeProvider => _typeProvider;
-
-  /**
-   * The type system in use.
-   */
-  TypeSystem get typeSystem => _typeSystem;
-
-  /**
-   * Create an object to represent the information about the library defined by the compilation unit
-   * with the given source.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @return the library object that was created
-   * @throws AnalysisException if the library source is not valid
-   */
-  Library createLibrary(Source librarySource) {
-    Library library =
-        new Library(analysisContext, _errorListener, librarySource);
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Resolve the library specified by the given source in the given context. The library is assumed
-   * to be embedded in the given source.
-   *
-   * @param librarySource the source specifying the defining compilation unit of the library to be
-   *          resolved
-   * @param unit the compilation unit representing the embedded library
-   * @param fullAnalysis `true` if a full analysis should be performed
-   * @return the element representing the resolved library
-   * @throws AnalysisException if the library could not be resolved for some reason
-   */
-  LibraryElement resolveEmbeddedLibrary(
-      Source librarySource, CompilationUnit unit, bool fullAnalysis) {
-    //
-    // Create the objects representing the library being resolved and the core
-    // library.
-    //
-    Library targetLibrary = _createLibraryWithUnit(librarySource, unit);
-    _coreLibrary = _libraryMap[_coreLibrarySource];
-    if (_coreLibrary == null) {
-      // This will only happen if the library being analyzed is the core
-      // library.
-      _coreLibrary = createLibrary(_coreLibrarySource);
-      if (_coreLibrary == null) {
-        LibraryResolver2.missingCoreLibrary(
-            analysisContext, _coreLibrarySource);
-      }
-    }
-    _asyncLibrary = _libraryMap[_asyncLibrarySource];
-    if (_asyncLibrary == null) {
-      // This will only happen if the library being analyzed is the async
-      // library.
-      _asyncLibrary = createLibrary(_asyncLibrarySource);
-      if (_asyncLibrary == null) {
-        LibraryResolver2.missingAsyncLibrary(
-            analysisContext, _asyncLibrarySource);
-      }
-    }
-    //
-    // Compute the set of libraries that need to be resolved together.
-    //
-    _computeEmbeddedLibraryDependencies(targetLibrary, unit);
-    _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
-    //
-    // Build the element models representing the libraries being resolved.
-    // This is done in three steps:
-    //
-    // 1. Build the basic element models without making any connections
-    //    between elements other than the basic parent/child relationships.
-    //    This includes building the elements representing the libraries.
-    // 2. Build the elements for the import and export directives. This
-    //    requires that we have the elements built for the referenced
-    //    libraries, but because of the possibility of circular references
-    //    needs to happen after all of the library elements have been created.
-    // 3. Build the rest of the type model by connecting superclasses, mixins,
-    //    and interfaces. This requires that we be able to compute the names
-    //    visible in the libraries being resolved, which in turn requires that
-    //    we have resolved the import directives.
-    //
-    _buildElementModels();
-    LibraryElement coreElement = _coreLibrary.libraryElement;
-    if (coreElement == null) {
-      throw new AnalysisException("Could not resolve dart:core");
-    }
-    LibraryElement asyncElement = _asyncLibrary.libraryElement;
-    if (asyncElement == null) {
-      throw new AnalysisException("Could not resolve dart:async");
-    }
-    _buildDirectiveModels();
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    _typeSystem = TypeSystem.create(analysisContext);
-    _buildTypeHierarchies();
-    //
-    // Perform resolution and type analysis.
-    //
-    // TODO(brianwilkerson) Decide whether we want to resolve all of the
-    // libraries or whether we want to only resolve the target library.
-    // The advantage to resolving everything is that we have already done part
-    // of the work so we'll avoid duplicated effort. The disadvantage of
-    // resolving everything is that we might do extra work that we don't
-    // really care about. Another possibility is to add a parameter to this
-    // method and punt the decision to the clients.
-    //
-    //if (analyzeAll) {
-    resolveReferencesAndTypes();
-    //} else {
-    //  resolveReferencesAndTypes(targetLibrary);
-    //}
-    _performConstantEvaluation();
-    return targetLibrary.libraryElement;
-  }
-
-  /**
-   * Resolve the library specified by the given source in the given context.
-   *
-   * Note that because Dart allows circular imports between libraries, it is possible that more than
-   * one library will need to be resolved. In such cases the error listener can receive errors from
-   * multiple libraries.
-   *
-   * @param librarySource the source specifying the defining compilation unit of the library to be
-   *          resolved
-   * @param fullAnalysis `true` if a full analysis should be performed
-   * @return the element representing the resolved library
-   * @throws AnalysisException if the library could not be resolved for some reason
-   */
-  LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
-    //
-    // Create the object representing the library being resolved and compute
-    // the dependency relationship.  Note that all libraries depend implicitly
-    // on core, and we inject an ersatz dependency on async, so once this is
-    // done the core and async library elements will have been created.
-    //
-    Library targetLibrary = createLibrary(librarySource);
-    _computeLibraryDependencies(targetLibrary);
-    _coreLibrary = _libraryMap[_coreLibrarySource];
-    _asyncLibrary = _libraryMap[_asyncLibrarySource];
-    //
-    // Compute the set of libraries that need to be resolved together.
-    //
-    _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
-    //
-    // Build the element models representing the libraries being resolved.
-    // This is done in three steps:
-    //
-    // 1. Build the basic element models without making any connections
-    //    between elements other than the basic parent/child relationships.
-    //    This includes building the elements representing the libraries, but
-    //    excludes members defined in enums.
-    // 2. Build the elements for the import and export directives. This
-    //    requires that we have the elements built for the referenced
-    //    libraries, but because of the possibility of circular references
-    //    needs to happen after all of the library elements have been created.
-    // 3. Build the members in enum declarations.
-    // 4. Build the rest of the type model by connecting superclasses, mixins,
-    //    and interfaces. This requires that we be able to compute the names
-    //    visible in the libraries being resolved, which in turn requires that
-    //    we have resolved the import directives.
-    //
-    _buildElementModels();
-    LibraryElement coreElement = _coreLibrary.libraryElement;
-    if (coreElement == null) {
-      throw new AnalysisException("Could not resolve dart:core");
-    }
-    LibraryElement asyncElement = _asyncLibrary.libraryElement;
-    if (asyncElement == null) {
-      throw new AnalysisException("Could not resolve dart:async");
-    }
-    _buildDirectiveModels();
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    _typeSystem = TypeSystem.create(analysisContext);
-    _buildEnumMembers();
-    _buildTypeHierarchies();
-    //
-    // Perform resolution and type analysis.
-    //
-    // TODO(brianwilkerson) Decide whether we want to resolve all of the
-    // libraries or whether we want to only resolve the target library. The
-    // advantage to resolving everything is that we have already done part of
-    // the work so we'll avoid duplicated effort. The disadvantage of
-    // resolving everything is that we might do extra work that we don't
-    // really care about. Another possibility is to add a parameter to this
-    // method and punt the decision to the clients.
-    //
-    //if (analyzeAll) {
-    resolveReferencesAndTypes();
-    //} else {
-    //  resolveReferencesAndTypes(targetLibrary);
-    //}
-    _performConstantEvaluation();
-    return targetLibrary.libraryElement;
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the identifiers could not be resolved or if any of the
-   *           libraries could not have their types analyzed
-   */
-  void resolveReferencesAndTypes() {
-    for (Library library in _librariesInCycles) {
-      _resolveReferencesAndTypesInLibrary(library);
-    }
-  }
-
-  /**
-   * Add a dependency to the given map from the referencing library to the referenced library.
-   *
-   * @param dependencyMap the map to which the dependency is to be added
-   * @param referencingLibrary the library that references the referenced library
-   * @param referencedLibrary the library referenced by the referencing library
-   */
-  void _addDependencyToMap(HashMap<Library, List<Library>> dependencyMap,
-      Library referencingLibrary, Library referencedLibrary) {
-    List<Library> dependentLibraries = dependencyMap[referencedLibrary];
-    if (dependentLibraries == null) {
-      dependentLibraries = new List<Library>();
-      dependencyMap[referencedLibrary] = dependentLibraries;
-    }
-    dependentLibraries.add(referencingLibrary);
-  }
-
-  /**
-   * Given a library that is part of a cycle that includes the root library, add to the given set of
-   * libraries all of the libraries reachable from the root library that are also included in the
-   * cycle.
-   *
-   * @param library the library to be added to the collection of libraries in cycles
-   * @param librariesInCycle a collection of the libraries that are in the cycle
-   * @param dependencyMap a table mapping libraries to the collection of libraries from which those
-   *          libraries are referenced
-   */
-  void _addLibrariesInCycle(Library library, Set<Library> librariesInCycle,
-      HashMap<Library, List<Library>> dependencyMap) {
-    if (librariesInCycle.add(library)) {
-      List<Library> dependentLibraries = dependencyMap[library];
-      if (dependentLibraries != null) {
-        for (Library dependentLibrary in dependentLibraries) {
-          _addLibrariesInCycle(
-              dependentLibrary, librariesInCycle, dependencyMap);
-        }
-      }
-    }
-  }
-
-  /**
-   * Add the given library, and all libraries reachable from it that have not already been visited,
-   * to the given dependency map.
-   *
-   * @param library the library currently being added to the dependency map
-   * @param dependencyMap the dependency map being computed
-   * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
-   *          recursion
-   */
-  void _addToDependencyMap(
-      Library library,
-      HashMap<Library, List<Library>> dependencyMap,
-      Set<Library> visitedLibraries) {
-    if (visitedLibraries.add(library)) {
-      bool asyncFound = false;
-      for (Library referencedLibrary in library.importsAndExports) {
-        _addDependencyToMap(dependencyMap, library, referencedLibrary);
-        _addToDependencyMap(referencedLibrary, dependencyMap, visitedLibraries);
-        if (identical(referencedLibrary, _asyncLibrary)) {
-          asyncFound = true;
-        }
-      }
-      if (!library.explicitlyImportsCore && !identical(library, _coreLibrary)) {
-        _addDependencyToMap(dependencyMap, library, _coreLibrary);
-      }
-      if (!asyncFound && !identical(library, _asyncLibrary)) {
-        _addDependencyToMap(dependencyMap, library, _asyncLibrary);
-        _addToDependencyMap(_asyncLibrary, dependencyMap, visitedLibraries);
-      }
-    }
-  }
-
-  /**
-   * Build the element model representing the combinators declared by the given directive.
-   *
-   * @param directive the directive that declares the combinators
-   * @return an array containing the import combinators that were built
-   */
-  List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
-    List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
-    for (Combinator combinator in directive.combinators) {
-      if (combinator is HideCombinator) {
-        HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
-        hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
-        combinators.add(hide);
-      } else {
-        ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
-        show.offset = combinator.offset;
-        show.end = combinator.end;
-        show.shownNames =
-            _getIdentifiers((combinator as ShowCombinator).shownNames);
-        combinators.add(show);
-      }
-    }
-    return combinators;
-  }
-
-  /**
-   * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
-   * the import and export directives.
-   *
-   * @throws AnalysisException if the defining compilation unit for any of the libraries could not
-   *           be accessed
-   */
-  void _buildDirectiveModels() {
-    for (Library library in _librariesInCycles) {
-      HashMap<String, PrefixElementImpl> nameToPrefixMap =
-          new HashMap<String, PrefixElementImpl>();
-      List<ImportElement> imports = new List<ImportElement>();
-      List<ExportElement> exports = new List<ExportElement>();
-      for (Directive directive in library.definingCompilationUnit.directives) {
-        if (directive is ImportDirective) {
-          ImportDirective importDirective = directive;
-          String uriContent = importDirective.uriContent;
-          if (DartUriResolver.isDartExtUri(uriContent)) {
-            library.libraryElement.hasExtUri = true;
-          }
-          Source importedSource = importDirective.source;
-          if (importedSource != null) {
-            // The imported source will be null if the URI in the import
-            // directive was invalid.
-            Library importedLibrary = _libraryMap[importedSource];
-            if (importedLibrary != null) {
-              ImportElementImpl importElement =
-                  new ImportElementImpl(directive.offset);
-              StringLiteral uriLiteral = importDirective.uri;
-              importElement.uriOffset = uriLiteral.offset;
-              importElement.uriEnd = uriLiteral.end;
-              importElement.uri = uriContent;
-              importElement.deferred = importDirective.deferredKeyword != null;
-              importElement.combinators = _buildCombinators(importDirective);
-              LibraryElement importedLibraryElement =
-                  importedLibrary.libraryElement;
-              if (importedLibraryElement != null) {
-                importElement.importedLibrary = importedLibraryElement;
-              }
-              SimpleIdentifier prefixNode = directive.prefix;
-              if (prefixNode != null) {
-                importElement.prefixOffset = prefixNode.offset;
-                String prefixName = prefixNode.name;
-                PrefixElementImpl prefix = nameToPrefixMap[prefixName];
-                if (prefix == null) {
-                  prefix = new PrefixElementImpl.forNode(prefixNode);
-                  nameToPrefixMap[prefixName] = prefix;
-                }
-                importElement.prefix = prefix;
-                prefixNode.staticElement = prefix;
-              }
-              directive.element = importElement;
-              imports.add(importElement);
-              if (analysisContext.computeKindOf(importedSource) !=
-                  SourceKind.LIBRARY) {
-                ErrorCode errorCode = (importElement.isDeferred
-                    ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
-                    : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    errorCode,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        } else if (directive is ExportDirective) {
-          ExportDirective exportDirective = directive;
-          Source exportedSource = exportDirective.source;
-          if (exportedSource != null) {
-            // The exported source will be null if the URI in the export
-            // directive was invalid.
-            Library exportedLibrary = _libraryMap[exportedSource];
-            if (exportedLibrary != null) {
-              ExportElementImpl exportElement =
-                  new ExportElementImpl(directive.offset);
-              StringLiteral uriLiteral = exportDirective.uri;
-              exportElement.uriOffset = uriLiteral.offset;
-              exportElement.uriEnd = uriLiteral.end;
-              exportElement.uri = exportDirective.uriContent;
-              exportElement.combinators = _buildCombinators(exportDirective);
-              LibraryElement exportedLibraryElement =
-                  exportedLibrary.libraryElement;
-              if (exportedLibraryElement != null) {
-                exportElement.exportedLibrary = exportedLibraryElement;
-              }
-              directive.element = exportElement;
-              exports.add(exportElement);
-              if (analysisContext.computeKindOf(exportedSource) !=
-                  SourceKind.LIBRARY) {
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        }
-      }
-      Source librarySource = library.librarySource;
-      if (!library.explicitlyImportsCore &&
-          _coreLibrarySource != librarySource) {
-        ImportElementImpl importElement = new ImportElementImpl(-1);
-        importElement.importedLibrary = _coreLibrary.libraryElement;
-        importElement.synthetic = true;
-        imports.add(importElement);
-      }
-      LibraryElementImpl libraryElement = library.libraryElement;
-      libraryElement.imports = imports;
-      libraryElement.exports = exports;
-      if (libraryElement.entryPoint == null) {
-        Namespace namespace = new NamespaceBuilder()
-            .createExportNamespaceForLibrary(libraryElement);
-        Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
-        if (element is FunctionElement) {
-          libraryElement.entryPoint = element;
-        }
-      }
-    }
-  }
-
-  /**
-   * Build element models for all of the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the element models cannot be built
-   */
-  void _buildElementModels() {
-    for (Library library in _librariesInCycles) {
-      LibraryElementBuilder builder =
-          new LibraryElementBuilder(analysisContext, errorListener);
-      LibraryElementImpl libraryElement = builder.buildLibrary(library);
-      library.libraryElement = libraryElement;
-    }
-  }
-
-  /**
-   * Build the members in enum declarations. This cannot be done while building the rest of the
-   * element model because it depends on being able to access core types, which cannot happen until
-   * the rest of the element model has been built (when resolving the core library).
-   *
-   * @throws AnalysisException if any of the enum members could not be built
-   */
-  void _buildEnumMembers() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider);
-          library.getAST(source).accept(builder);
-        }
-      }
-    });
-  }
-
-  /**
-   * Resolve the type hierarchy across all of the types declared in the libraries in the current
-   * cycle.
-   *
-   * @throws AnalysisException if any of the type hierarchies could not be resolved
-   */
-  void _buildTypeHierarchies() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          TypeResolverVisitorFactory typeResolverVisitorFactory =
-              analysisContext.typeResolverVisitorFactory;
-          TypeResolverVisitor visitor = (typeResolverVisitorFactory == null)
-              ? new TypeResolverVisitor(library.libraryElement, source,
-                  _typeProvider, library.errorListener,
-                  nameScope: library.libraryScope)
-              : typeResolverVisitorFactory(library, source, _typeProvider);
-          library.getAST(source).accept(visitor);
-        }
-        library.libraryElement.createLoadLibraryFunction(_typeProvider);
-      }
-    });
-  }
-
-  /**
-   * Compute a dependency map of libraries reachable from the given library. A dependency map is a
-   * table that maps individual libraries to a list of the libraries that either import or export
-   * those libraries.
-   *
-   * This map is used to compute all of the libraries involved in a cycle that include the root
-   * library. Given that we only add libraries that are reachable from the root library, when we
-   * work backward we are guaranteed to only get libraries in the cycle.
-   *
-   * @param library the library currently being added to the dependency map
-   */
-  HashMap<Library, List<Library>> _computeDependencyMap(Library library) {
-    HashMap<Library, List<Library>> dependencyMap =
-        new HashMap<Library, List<Library>>();
-    _addToDependencyMap(library, dependencyMap, new HashSet<Library>());
-    return dependencyMap;
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of the
-   * class [Library] to represent them, and record the references in the library objects.
-   *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @throws AnalysisException if some portion of the library graph could not be traversed
-   */
-  void _computeEmbeddedLibraryDependencies(
-      Library library, CompilationUnit unit) {
-    Source librarySource = library.librarySource;
-    HashSet<Source> exportedSources = new HashSet<Source>();
-    HashSet<Source> importedSources = new HashSet<Source>();
-    for (Directive directive in unit.directives) {
-      if (directive is ExportDirective) {
-        Source exportSource = _resolveSource(librarySource, directive);
-        if (exportSource != null) {
-          exportedSources.add(exportSource);
-        }
-      } else if (directive is ImportDirective) {
-        Source importSource = _resolveSource(librarySource, directive);
-        if (importSource != null) {
-          importedSources.add(importSource);
-        }
-      }
-    }
-    _computeLibraryDependenciesFromDirectives(library,
-        new List.from(importedSources), new List.from(exportedSources));
-  }
-
-  /**
-   * Return a collection containing all of the libraries reachable from the given library that are
-   * contained in a cycle that includes the given library.
-   *
-   * @param library the library that must be included in any cycles whose members are to be returned
-   * @return all of the libraries referenced by the given library that have a circular reference
-   *         back to the given library
-   */
-  Set<Library> _computeLibrariesInCycles(Library library) {
-    HashMap<Library, List<Library>> dependencyMap =
-        _computeDependencyMap(library);
-    Set<Library> librariesInCycle = new HashSet<Library>();
-    _addLibrariesInCycle(library, librariesInCycle, dependencyMap);
-    return librariesInCycle;
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of the
-   * class [Library] to represent them, and record the references in the library objects.
-   *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @throws AnalysisException if some portion of the library graph could not be traversed
-   */
-  void _computeLibraryDependencies(Library library) {
-    Source librarySource = library.librarySource;
-    _computeLibraryDependenciesFromDirectives(
-        library,
-        analysisContext.computeImportedLibraries(librarySource),
-        analysisContext.computeExportedLibraries(librarySource));
-  }
-
-  /**
-   * Recursively traverse the libraries reachable from the given library, creating instances of the
-   * class [Library] to represent them, and record the references in the library objects.
-   *
-   * @param library the library to be processed to find libraries that have not yet been traversed
-   * @param importedSources an array containing the sources that are imported into the given library
-   * @param exportedSources an array containing the sources that are exported from the given library
-   * @throws AnalysisException if some portion of the library graph could not be traversed
-   */
-  void _computeLibraryDependenciesFromDirectives(Library library,
-      List<Source> importedSources, List<Source> exportedSources) {
-    List<Library> importedLibraries = new List<Library>();
-    bool explicitlyImportsCore = false;
-    bool importsAsync = false;
-    for (Source importedSource in importedSources) {
-      if (importedSource == _coreLibrarySource) {
-        explicitlyImportsCore = true;
-      }
-      if (importedSource == _asyncLibrarySource) {
-        importsAsync = true;
-      }
-      Library importedLibrary = _libraryMap[importedSource];
-      if (importedLibrary == null) {
-        importedLibrary = _createLibraryOrNull(importedSource);
-        if (importedLibrary != null) {
-          _computeLibraryDependencies(importedLibrary);
-        }
-      }
-      if (importedLibrary != null) {
-        importedLibraries.add(importedLibrary);
-      }
-    }
-    library.importedLibraries = importedLibraries;
-    List<Library> exportedLibraries = new List<Library>();
-    for (Source exportedSource in exportedSources) {
-      Library exportedLibrary = _libraryMap[exportedSource];
-      if (exportedLibrary == null) {
-        exportedLibrary = _createLibraryOrNull(exportedSource);
-        if (exportedLibrary != null) {
-          _computeLibraryDependencies(exportedLibrary);
-        }
-      }
-      if (exportedLibrary != null) {
-        exportedLibraries.add(exportedLibrary);
-      }
-    }
-    library.exportedLibraries = exportedLibraries;
-    library.explicitlyImportsCore = explicitlyImportsCore;
-    if (!explicitlyImportsCore && _coreLibrarySource != library.librarySource) {
-      Library importedLibrary = _libraryMap[_coreLibrarySource];
-      if (importedLibrary == null) {
-        importedLibrary = _createLibraryOrNull(_coreLibrarySource);
-        if (importedLibrary != null) {
-          _computeLibraryDependencies(importedLibrary);
-        }
-      }
-    }
-    if (!importsAsync && _asyncLibrarySource != library.librarySource) {
-      Library importedLibrary = _libraryMap[_asyncLibrarySource];
-      if (importedLibrary == null) {
-        importedLibrary = _createLibraryOrNull(_asyncLibrarySource);
-        if (importedLibrary != null) {
-          _computeLibraryDependencies(importedLibrary);
-        }
-      }
-    }
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by the compilation unit
-   * with the given source. Return the library object that was created, or `null` if the
-   * source is not valid.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @return the library object that was created
-   */
-  Library _createLibraryOrNull(Source librarySource) {
-    if (!analysisContext.exists(librarySource)) {
-      return null;
-    }
-    Library library =
-        new Library(analysisContext, _errorListener, librarySource);
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Create an object to represent the information about the library defined by the compilation unit
-   * with the given source.
-   *
-   * @param librarySource the source of the library's defining compilation unit
-   * @param unit the compilation unit that defines the library
-   * @return the library object that was created
-   * @throws AnalysisException if the library source is not valid
-   */
-  Library _createLibraryWithUnit(Source librarySource, CompilationUnit unit) {
-    Library library =
-        new Library(analysisContext, _errorListener, librarySource);
-    library.setDefiningCompilationUnit(unit);
-    _libraryMap[librarySource] = library;
-    return library;
-  }
-
-  /**
-   * Return an array containing the lexical identifiers associated with the nodes in the given list.
-   *
-   * @param names the AST nodes representing the identifiers
-   * @return the lexical identifiers associated with the nodes in the list
-   */
-  List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
-    int count = names.length;
-    List<String> identifiers = new List<String>(count);
-    for (int i = 0; i < count; i++) {
-      identifiers[i] = names[i].name;
-    }
-    return identifiers;
-  }
-
-  /**
-   * Compute a value for all of the constants in the libraries being analyzed.
-   */
-  void _performConstantEvaluation() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      ConstantValueComputer computer = new ConstantValueComputer(
-          analysisContext,
-          _typeProvider,
-          analysisContext.declaredVariables,
-          null,
-          _typeSystem);
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          try {
-            CompilationUnit unit = library.getAST(source);
-            if (unit != null) {
-              computer.add(unit, source, library.librarySource);
-            }
-          } on AnalysisException catch (exception, stackTrace) {
-            AnalysisEngine.instance.logger.logError(
-                "Internal Error: Could not access AST for ${source.fullName} during constant evaluation",
-                new CaughtException(exception, stackTrace));
-          }
-        }
-      }
-      computer.computeValues();
-      // As a temporary workaround for issue 21572, run ConstantVerifier now.
-      // TODO(paulberry): remove this workaround once issue 21572 is fixed.
-      for (Library library in _librariesInCycles) {
-        for (Source source in library.compilationUnitSources) {
-          try {
-            CompilationUnit unit = library.getAST(source);
-            ErrorReporter errorReporter =
-                new ErrorReporter(_errorListener, source);
-            ConstantVerifier constantVerifier = new ConstantVerifier(
-                errorReporter,
-                library.libraryElement,
-                _typeProvider,
-                analysisContext.declaredVariables);
-            unit.accept(constantVerifier);
-          } on AnalysisException catch (exception, stackTrace) {
-            AnalysisEngine.instance.logger.logError(
-                "Internal Error: Could not access AST for ${source.fullName} "
-                "during constant verification",
-                new CaughtException(exception, stackTrace));
-          }
-        }
-      }
-    });
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the given library.
-   *
-   * @param library the library to be resolved
-   * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
-   *           the library cannot be analyzed
-   */
-  void _resolveReferencesAndTypesInLibrary(Library library) {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (Source source in library.compilationUnitSources) {
-        CompilationUnit ast = library.getAST(source);
-        ast.accept(new VariableResolverVisitor(library.libraryElement, source,
-            _typeProvider, library.errorListener,
-            nameScope: library.libraryScope));
-        ResolverVisitorFactory visitorFactory =
-            analysisContext.resolverVisitorFactory;
-        ResolverVisitor visitor = visitorFactory != null
-            ? visitorFactory(library, source, _typeProvider)
-            : new ResolverVisitor(library.libraryElement, source, _typeProvider,
-                library.errorListener,
-                nameScope: library.libraryScope,
-                inheritanceManager: library.inheritanceManager);
-        ast.accept(visitor);
-      }
-    });
-  }
-
-  /**
-   * Return the result of resolving the URI of the given URI-based directive against the URI of the
-   * given library, or `null` if the URI is not valid.
-   *
-   * @param librarySource the source representing the library containing the directive
-   * @param directive the directive which URI should be resolved
-   * @return the result of resolving the URI against the URI of the library
-   */
-  Source _resolveSource(Source librarySource, UriBasedDirective directive) {
-    StringLiteral uriLiteral = directive.uri;
-    if (uriLiteral is StringInterpolation) {
-      return null;
-    }
-    String uriContent = uriLiteral.stringValue.trim();
-    if (uriContent == null || uriContent.isEmpty) {
-      return null;
-    }
-    uriContent = Uri.encodeFull(uriContent);
-    return analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
-  }
-}
 
 /**
  * Instances of the class `LibraryResolver` are used to resolve one or more mutually dependent
  * libraries within a single context.
  */
-class LibraryResolver2 {
-  /**
-   * The analysis context in which the libraries are being analyzed.
-   */
-  final InternalAnalysisContext analysisContext;
-
-  /**
-   * The listener to which analysis errors will be reported, this error listener is either
-   * references [recordingErrorListener], or it unions the passed
-   * [AnalysisErrorListener] with the [recordingErrorListener].
-   */
-  RecordingErrorListener _errorListener;
-
-  /**
-   * A source object representing the core library (dart:core).
-   */
-  Source _coreLibrarySource;
-
-  /**
-   * A source object representing the async library (dart:async).
-   */
-  Source _asyncLibrarySource;
-
-  /**
-   * The object representing the core library.
-   */
-  ResolvableLibrary _coreLibrary;
-
-  /**
-   * The object representing the async library.
-   */
-  ResolvableLibrary _asyncLibrary;
-
-  /**
-   * The object used to access the types from the core library.
-   */
-  TypeProvider _typeProvider;
-
-  /**
-   * The type system in use for the library
-   */
-  TypeSystem _typeSystem;
-
-  /**
-   * A table mapping library sources to the information being maintained for those libraries.
-   */
-  HashMap<Source, ResolvableLibrary> _libraryMap =
-      new HashMap<Source, ResolvableLibrary>();
-
-  /**
-   * A collection containing the libraries that are being resolved together.
-   */
-  List<ResolvableLibrary> _librariesInCycle;
-
-  /**
-   * Initialize a newly created library resolver to resolve libraries within the given context.
-   *
-   * @param analysisContext the analysis context in which the library is being analyzed
-   */
-  LibraryResolver2(this.analysisContext) {
-    this._errorListener = new RecordingErrorListener();
-    _coreLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource =
-        analysisContext.sourceFactory.forUri(DartSdk.DART_ASYNC);
-  }
-
-  /**
-   * Return the listener to which analysis errors will be reported.
-   *
-   * @return the listener to which analysis errors will be reported
-   */
-  RecordingErrorListener get errorListener => _errorListener;
-
-  /**
-   * Return an array containing information about all of the libraries that were resolved.
-   *
-   * @return an array containing the libraries that were resolved
-   */
-  List<ResolvableLibrary> get resolvedLibraries => _librariesInCycle;
-
-  /**
-   * Resolve the library specified by the given source in the given context.
-   *
-   * Note that because Dart allows circular imports between libraries, it is possible that more than
-   * one library will need to be resolved. In such cases the error listener can receive errors from
-   * multiple libraries.
-   *
-   * @param librarySource the source specifying the defining compilation unit of the library to be
-   *          resolved
-   * @param fullAnalysis `true` if a full analysis should be performed
-   * @return the element representing the resolved library
-   * @throws AnalysisException if the library could not be resolved for some reason
-   */
-  LibraryElement resolveLibrary(
-      Source librarySource, List<ResolvableLibrary> librariesInCycle) {
-    //
-    // Build the map of libraries that are known.
-    //
-    this._librariesInCycle = librariesInCycle;
-    _libraryMap = _buildLibraryMap();
-    ResolvableLibrary targetLibrary = _libraryMap[librarySource];
-    _coreLibrary = _libraryMap[_coreLibrarySource];
-    _asyncLibrary = _libraryMap[_asyncLibrarySource];
-    //
-    // Build the element models representing the libraries being resolved.
-    // This is done in three steps:
-    //
-    // 1. Build the basic element models without making any connections
-    //    between elements other than the basic parent/child relationships.
-    //    This includes building the elements representing the libraries, but
-    //    excludes members defined in enums.
-    // 2. Build the elements for the import and export directives. This
-    //    requires that we have the elements built for the referenced
-    //    libraries, but because of the possibility of circular references
-    //    needs to happen after all of the library elements have been created.
-    // 3. Build the members in enum declarations.
-    // 4. Build the rest of the type model by connecting superclasses, mixins,
-    //    and interfaces. This requires that we be able to compute the names
-    //    visible in the libraries being resolved, which in turn requires that
-    //    we have resolved the import directives.
-    //
-    _buildElementModels();
-    LibraryElement coreElement = _coreLibrary.libraryElement;
-    if (coreElement == null) {
-      missingCoreLibrary(analysisContext, _coreLibrarySource);
-    }
-    LibraryElement asyncElement = _asyncLibrary.libraryElement;
-    if (asyncElement == null) {
-      missingAsyncLibrary(analysisContext, _asyncLibrarySource);
-    }
-    _buildDirectiveModels();
-    _typeProvider = new TypeProviderImpl(coreElement, asyncElement);
-    _typeSystem = TypeSystem.create(analysisContext);
-    _buildEnumMembers();
-    _buildTypeHierarchies();
-    //
-    // Perform resolution and type analysis.
-    //
-    // TODO(brianwilkerson) Decide whether we want to resolve all of the
-    // libraries or whether we want to only resolve the target library. The
-    // advantage to resolving everything is that we have already done part of
-    // the work so we'll avoid duplicated effort. The disadvantage of
-    // resolving everything is that we might do extra work that we don't
-    // really care about. Another possibility is to add a parameter to this
-    // method and punt the decision to the clients.
-    //
-    //if (analyzeAll) {
-    _resolveReferencesAndTypes();
-    //} else {
-    //  resolveReferencesAndTypes(targetLibrary);
-    //}
-    _performConstantEvaluation();
-    return targetLibrary.libraryElement;
-  }
-
-  /**
-   * Build the element model representing the combinators declared by the given directive.
-   *
-   * @param directive the directive that declares the combinators
-   * @return an array containing the import combinators that were built
-   */
-  List<NamespaceCombinator> _buildCombinators(NamespaceDirective directive) {
-    List<NamespaceCombinator> combinators = new List<NamespaceCombinator>();
-    for (Combinator combinator in directive.combinators) {
-      if (combinator is HideCombinator) {
-        HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
-        hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
-        combinators.add(hide);
-      } else {
-        ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
-        show.offset = combinator.offset;
-        show.end = combinator.end;
-        show.shownNames =
-            _getIdentifiers((combinator as ShowCombinator).shownNames);
-        combinators.add(show);
-      }
-    }
-    return combinators;
-  }
-
-  /**
-   * Every library now has a corresponding [LibraryElement], so it is now possible to resolve
-   * the import and export directives.
-   *
-   * @throws AnalysisException if the defining compilation unit for any of the libraries could not
-   *           be accessed
-   */
-  void _buildDirectiveModels() {
-    for (ResolvableLibrary library in _librariesInCycle) {
-      HashMap<String, PrefixElementImpl> nameToPrefixMap =
-          new HashMap<String, PrefixElementImpl>();
-      List<ImportElement> imports = new List<ImportElement>();
-      List<ExportElement> exports = new List<ExportElement>();
-      for (Directive directive in library.definingCompilationUnit.directives) {
-        if (directive is ImportDirective) {
-          ImportDirective importDirective = directive;
-          String uriContent = importDirective.uriContent;
-          if (DartUriResolver.isDartExtUri(uriContent)) {
-            library.libraryElement.hasExtUri = true;
-          }
-          Source importedSource = importDirective.source;
-          if (importedSource != null &&
-              analysisContext.exists(importedSource)) {
-            // The imported source will be null if the URI in the import
-            // directive was invalid.
-            ResolvableLibrary importedLibrary = _libraryMap[importedSource];
-            if (importedLibrary != null) {
-              ImportElementImpl importElement =
-                  new ImportElementImpl(directive.offset);
-              StringLiteral uriLiteral = importDirective.uri;
-              if (uriLiteral != null) {
-                importElement.uriOffset = uriLiteral.offset;
-                importElement.uriEnd = uriLiteral.end;
-              }
-              importElement.uri = uriContent;
-              importElement.deferred = importDirective.deferredKeyword != null;
-              importElement.combinators = _buildCombinators(importDirective);
-              LibraryElement importedLibraryElement =
-                  importedLibrary.libraryElement;
-              if (importedLibraryElement != null) {
-                importElement.importedLibrary = importedLibraryElement;
-              }
-              SimpleIdentifier prefixNode = directive.prefix;
-              if (prefixNode != null) {
-                importElement.prefixOffset = prefixNode.offset;
-                String prefixName = prefixNode.name;
-                PrefixElementImpl prefix = nameToPrefixMap[prefixName];
-                if (prefix == null) {
-                  prefix = new PrefixElementImpl.forNode(prefixNode);
-                  nameToPrefixMap[prefixName] = prefix;
-                }
-                importElement.prefix = prefix;
-                prefixNode.staticElement = prefix;
-              }
-              directive.element = importElement;
-              imports.add(importElement);
-              if (analysisContext.computeKindOf(importedSource) !=
-                  SourceKind.LIBRARY) {
-                ErrorCode errorCode = (importElement.isDeferred
-                    ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
-                    : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    errorCode,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        } else if (directive is ExportDirective) {
-          ExportDirective exportDirective = directive;
-          Source exportedSource = exportDirective.source;
-          if (exportedSource != null &&
-              analysisContext.exists(exportedSource)) {
-            // The exported source will be null if the URI in the export
-            // directive was invalid.
-            ResolvableLibrary exportedLibrary = _libraryMap[exportedSource];
-            if (exportedLibrary != null) {
-              ExportElementImpl exportElement =
-                  new ExportElementImpl(directive.offset);
-              StringLiteral uriLiteral = exportDirective.uri;
-              if (uriLiteral != null) {
-                exportElement.uriOffset = uriLiteral.offset;
-                exportElement.uriEnd = uriLiteral.end;
-              }
-              exportElement.uri = exportDirective.uriContent;
-              exportElement.combinators = _buildCombinators(exportDirective);
-              LibraryElement exportedLibraryElement =
-                  exportedLibrary.libraryElement;
-              if (exportedLibraryElement != null) {
-                exportElement.exportedLibrary = exportedLibraryElement;
-              }
-              directive.element = exportElement;
-              exports.add(exportElement);
-              if (analysisContext.computeKindOf(exportedSource) !=
-                  SourceKind.LIBRARY) {
-                _errorListener.onError(new AnalysisError(
-                    library.librarySource,
-                    uriLiteral.offset,
-                    uriLiteral.length,
-                    CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-                    [uriLiteral.toSource()]));
-              }
-            }
-          }
-        }
-      }
-      Source librarySource = library.librarySource;
-      if (!library.explicitlyImportsCore &&
-          _coreLibrarySource != librarySource) {
-        ImportElementImpl importElement = new ImportElementImpl(-1);
-        importElement.importedLibrary = _coreLibrary.libraryElement;
-        importElement.synthetic = true;
-        imports.add(importElement);
-      }
-      LibraryElementImpl libraryElement = library.libraryElement;
-      libraryElement.imports = imports;
-      libraryElement.exports = exports;
-      if (libraryElement.entryPoint == null) {
-        Namespace namespace = new NamespaceBuilder()
-            .createExportNamespaceForLibrary(libraryElement);
-        Element element = namespace.get(FunctionElement.MAIN_FUNCTION_NAME);
-        if (element is FunctionElement) {
-          libraryElement.entryPoint = element;
-        }
-      }
-    }
-  }
-
-  /**
-   * Build element models for all of the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the element models cannot be built
-   */
-  void _buildElementModels() {
-    for (ResolvableLibrary library in _librariesInCycle) {
-      LibraryElementBuilder builder =
-          new LibraryElementBuilder(analysisContext, errorListener);
-      builder.buildLibrary2(library);
-    }
-  }
-
-  /**
-   * Build the members in enum declarations. This cannot be done while building the rest of the
-   * element model because it depends on being able to access core types, which cannot happen until
-   * the rest of the element model has been built (when resolving the core library).
-   *
-   * @throws AnalysisException if any of the enum members could not be built
-   */
-  void _buildEnumMembers() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (Source source in library.compilationUnitSources) {
-          EnumMemberBuilder builder = new EnumMemberBuilder(_typeProvider);
-          library.getAST(source).accept(builder);
-        }
-      }
-    });
-  }
-
-  HashMap<Source, ResolvableLibrary> _buildLibraryMap() {
-    HashMap<Source, ResolvableLibrary> libraryMap =
-        new HashMap<Source, ResolvableLibrary>();
-    int libraryCount = _librariesInCycle.length;
-    for (int i = 0; i < libraryCount; i++) {
-      ResolvableLibrary library = _librariesInCycle[i];
-      library.errorListener = _errorListener;
-      libraryMap[library.librarySource] = library;
-      List<ResolvableLibrary> dependencies = library.importsAndExports;
-      int dependencyCount = dependencies.length;
-      for (int j = 0; j < dependencyCount; j++) {
-        ResolvableLibrary dependency = dependencies[j];
-        //dependency.setErrorListener(errorListener);
-        libraryMap[dependency.librarySource] = dependency;
-      }
-    }
-    return libraryMap;
-  }
-
-  /**
-   * Resolve the type hierarchy across all of the types declared in the libraries in the current
-   * cycle.
-   *
-   * @throws AnalysisException if any of the type hierarchies could not be resolved
-   */
-  void _buildTypeHierarchies() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (ResolvableCompilationUnit unit
-            in library.resolvableCompilationUnits) {
-          Source source = unit.source;
-          CompilationUnit ast = unit.compilationUnit;
-          TypeResolverVisitor visitor = new TypeResolverVisitor(
-              library.libraryElement,
-              source,
-              _typeProvider,
-              library.libraryScope.errorListener,
-              nameScope: library.libraryScope);
-          ast.accept(visitor);
-        }
-        library.libraryElement.createLoadLibraryFunction(_typeProvider);
-      }
-    });
-  }
-
-  /**
-   * Return an array containing the lexical identifiers associated with the nodes in the given list.
-   *
-   * @param names the AST nodes representing the identifiers
-   * @return the lexical identifiers associated with the nodes in the list
-   */
-  List<String> _getIdentifiers(NodeList<SimpleIdentifier> names) {
-    int count = names.length;
-    List<String> identifiers = new List<String>(count);
-    for (int i = 0; i < count; i++) {
-      identifiers[i] = names[i].name;
-    }
-    return identifiers;
-  }
-
-  /**
-   * Compute a value for all of the constants in the libraries being analyzed.
-   */
-  void _performConstantEvaluation() {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      ConstantValueComputer computer = new ConstantValueComputer(
-          analysisContext,
-          _typeProvider,
-          analysisContext.declaredVariables,
-          null,
-          _typeSystem);
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (ResolvableCompilationUnit unit
-            in library.resolvableCompilationUnits) {
-          CompilationUnit ast = unit.compilationUnit;
-          if (ast != null) {
-            computer.add(ast, unit.source, library.librarySource);
-          }
-        }
-      }
-      computer.computeValues();
-      // As a temporary workaround for issue 21572, run ConstantVerifier now.
-      // TODO(paulberry): remove this workaround once issue 21572 is fixed.
-      for (ResolvableLibrary library in _librariesInCycle) {
-        for (ResolvableCompilationUnit unit
-            in library.resolvableCompilationUnits) {
-          CompilationUnit ast = unit.compilationUnit;
-          ErrorReporter errorReporter =
-              new ErrorReporter(_errorListener, unit.source);
-          ConstantVerifier constantVerifier = new ConstantVerifier(
-              errorReporter,
-              library.libraryElement,
-              _typeProvider,
-              analysisContext.declaredVariables);
-          ast.accept(constantVerifier);
-        }
-      }
-    });
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the libraries in the current cycle.
-   *
-   * @throws AnalysisException if any of the identifiers could not be resolved or if any of the
-   *           libraries could not have their types analyzed
-   */
-  void _resolveReferencesAndTypes() {
-    for (ResolvableLibrary library in _librariesInCycle) {
-      _resolveReferencesAndTypesInLibrary(library);
-    }
-  }
-
-  /**
-   * Resolve the identifiers and perform type analysis in the given library.
-   *
-   * @param library the library to be resolved
-   * @throws AnalysisException if any of the identifiers could not be resolved or if the types in
-   *           the library cannot be analyzed
-   */
-  void _resolveReferencesAndTypesInLibrary(ResolvableLibrary library) {
-    PerformanceStatistics.resolve.makeCurrentWhile(() {
-      for (ResolvableCompilationUnit unit
-          in library.resolvableCompilationUnits) {
-        Source source = unit.source;
-        CompilationUnit ast = unit.compilationUnit;
-        ast.accept(new VariableResolverVisitor(library.libraryElement, source,
-            _typeProvider, library.libraryScope.errorListener,
-            nameScope: library.libraryScope));
-        ResolverVisitor visitor = new ResolverVisitor(library.libraryElement,
-            source, _typeProvider, library._libraryScope.errorListener,
-            nameScope: library._libraryScope,
-            inheritanceManager: library.inheritanceManager);
-        ast.accept(visitor);
-      }
-    });
-  }
-
-  /**
-   * Report that the async library could not be resolved in the given
-   * [analysisContext] and throw an exception.  [asyncLibrarySource] is the source
-   * representing the async library.
-   */
-  static void missingAsyncLibrary(
-      AnalysisContext analysisContext, Source asyncLibrarySource) {
-    throw new AnalysisException("Could not resolve dart:async");
-  }
-
-  /**
-   * Report that the core library could not be resolved in the given analysis context and throw an
-   * exception.
-   *
-   * @param analysisContext the analysis context in which the failure occurred
-   * @param coreLibrarySource the source representing the core library
-   * @throws AnalysisException always
-   */
-  static void missingCoreLibrary(
-      AnalysisContext analysisContext, Source coreLibrarySource) {
-    throw new AnalysisException("Could not resolve dart:core");
-  }
-}
 
 /**
  * Instances of the class `LibraryScope` implement a scope containing all of the names defined
@@ -9431,29 +7010,6 @@
   }
 
   /**
-   * This constructor takes an initial capacity of the map.
-   *
-   * @param initialCapacity the initial capacity
-   */
-  @deprecated // Use new MemberMap(initialCapacity)
-  MemberMap.con1(int initialCapacity) {
-    _initArrays(initialCapacity);
-  }
-
-  /**
-   * Copy constructor.
-   */
-  @deprecated // Use new MemberMap.from(memberMap)
-  MemberMap.con2(MemberMap memberMap) {
-    _initArrays(memberMap._size + 5);
-    for (int i = 0; i < memberMap._size; i++) {
-      _keys[i] = memberMap._keys[i];
-      _values[i] = memberMap._values[i];
-    }
-    _size = memberMap._size;
-  }
-
-  /**
    * Initialize a newly created member map to contain the same members as the
    * given [memberMap].
    */
@@ -9990,10 +7546,9 @@
    */
   PartialResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
-      {Scope nameScope,
-      InheritanceManager inheritanceManager,
-      StaticTypeAnalyzerFactory typeAnalyzerFactory})
-      : super(definingLibrary, source, typeProvider, errorListener);
+      {Scope nameScope})
+      : super(definingLibrary, source, typeProvider, errorListener,
+            nameScope: nameScope);
 
   @override
   Object visitBlockFunctionBody(BlockFunctionBody node) {
@@ -10295,273 +7850,6 @@
 }
 
 /**
- * A `ResolvableLibrary` represents a single library during the resolution of
- * some (possibly different) library. They are not intended to be used except
- * during the resolution process.
- */
-class ResolvableLibrary {
-  /**
-   * An empty array that can be used to initialize lists of libraries.
-   */
-  static List<ResolvableLibrary> _EMPTY_ARRAY = new List<ResolvableLibrary>(0);
-
-  /**
-   * The next artificial hash code.
-   */
-  static int _NEXT_HASH_CODE = 0;
-
-  /**
-   * The artifitial hash code for this object.
-   */
-  final int _hashCode = _nextHashCode();
-
-  /**
-   * The source specifying the defining compilation unit of this library.
-   */
-  final Source librarySource;
-
-  /**
-   * A list containing all of the libraries that are imported into this library.
-   */
-  List<ResolvableLibrary> _importedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * A flag indicating whether this library explicitly imports core.
-   */
-  bool explicitlyImportsCore = false;
-
-  /**
-   * An array containing all of the libraries that are exported from this library.
-   */
-  List<ResolvableLibrary> _exportedLibraries = _EMPTY_ARRAY;
-
-  /**
-   * An array containing the compilation units that comprise this library. The
-   * defining compilation unit is always first.
-   */
-  List<ResolvableCompilationUnit> _compilationUnits;
-
-  /**
-   * The library element representing this library.
-   */
-  LibraryElementImpl _libraryElement;
-
-  /**
-   * The listener to which analysis errors will be reported.
-   */
-  AnalysisErrorListener _errorListener;
-
-  /**
-   * The inheritance manager which is used for member lookups in this library.
-   */
-  InheritanceManager _inheritanceManager;
-
-  /**
-   * The library scope used when resolving elements within this library's compilation units.
-   */
-  LibraryScope _libraryScope;
-
-  /**
-   * Initialize a newly created data holder that can maintain the data associated with a library.
-   *
-   * @param librarySource the source specifying the defining compilation unit of this library
-   * @param errorListener the listener to which analysis errors will be reported
-   */
-  ResolvableLibrary(this.librarySource);
-
-  /**
-   * Return an array of the [CompilationUnit]s that make up the library. The first unit is
-   * always the defining unit.
-   *
-   * @return an array of the [CompilationUnit]s that make up the library. The first unit is
-   *         always the defining unit
-   */
-  List<CompilationUnit> get compilationUnits {
-    int count = _compilationUnits.length;
-    List<CompilationUnit> units = new List<CompilationUnit>(count);
-    for (int i = 0; i < count; i++) {
-      units[i] = _compilationUnits[i].compilationUnit;
-    }
-    return units;
-  }
-
-  /**
-   * Return an array containing the sources for the compilation units in this library, including the
-   * defining compilation unit.
-   *
-   * @return the sources for the compilation units in this library
-   */
-  List<Source> get compilationUnitSources {
-    int count = _compilationUnits.length;
-    List<Source> sources = new List<Source>(count);
-    for (int i = 0; i < count; i++) {
-      sources[i] = _compilationUnits[i].source;
-    }
-    return sources;
-  }
-
-  /**
-   * Return the AST structure associated with the defining compilation unit for this library.
-   *
-   * @return the AST structure associated with the defining compilation unit for this library
-   * @throws AnalysisException if an AST structure could not be created for the defining compilation
-   *           unit
-   */
-  CompilationUnit get definingCompilationUnit =>
-      _compilationUnits[0].compilationUnit;
-
-  /**
-   * Set the listener to which analysis errors will be reported to be the given listener.
-   *
-   * @param errorListener the listener to which analysis errors will be reported
-   */
-  void set errorListener(AnalysisErrorListener errorListener) {
-    this._errorListener = errorListener;
-  }
-
-  /**
-   * Set the libraries that are exported by this library to be those in the given array.
-   *
-   * @param exportedLibraries the libraries that are exported by this library
-   */
-  void set exportedLibraries(List<ResolvableLibrary> exportedLibraries) {
-    this._exportedLibraries = exportedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are exported from this library.
-   *
-   * @return an array containing the libraries that are exported from this library
-   */
-  List<ResolvableLibrary> get exports => _exportedLibraries;
-
-  @override
-  int get hashCode => _hashCode;
-
-  /**
-   * Set the libraries that are imported into this library to be those in the given array.
-   *
-   * @param importedLibraries the libraries that are imported into this library
-   */
-  void set importedLibraries(List<ResolvableLibrary> importedLibraries) {
-    this._importedLibraries = importedLibraries;
-  }
-
-  /**
-   * Return an array containing the libraries that are imported into this library.
-   *
-   * @return an array containing the libraries that are imported into this library
-   */
-  List<ResolvableLibrary> get imports => _importedLibraries;
-
-  /**
-   * Return an array containing the libraries that are either imported or exported from this
-   * library.
-   *
-   * @return the libraries that are either imported or exported from this library
-   */
-  List<ResolvableLibrary> get importsAndExports {
-    HashSet<ResolvableLibrary> libraries = new HashSet<ResolvableLibrary>();
-    for (ResolvableLibrary library in _importedLibraries) {
-      libraries.add(library);
-    }
-    for (ResolvableLibrary library in _exportedLibraries) {
-      libraries.add(library);
-    }
-    return new List.from(libraries);
-  }
-
-  /**
-   * Return the inheritance manager for this library.
-   *
-   * @return the inheritance manager for this library
-   */
-  InheritanceManager get inheritanceManager {
-    if (_inheritanceManager == null) {
-      return _inheritanceManager = new InheritanceManager(_libraryElement);
-    }
-    return _inheritanceManager;
-  }
-
-  /**
-   * Return the library element representing this library, creating it if necessary.
-   *
-   * @return the library element representing this library
-   */
-  LibraryElementImpl get libraryElement => _libraryElement;
-
-  /**
-   * Set the library element representing this library to the given library element.
-   *
-   * @param libraryElement the library element representing this library
-   */
-  void set libraryElement(LibraryElementImpl libraryElement) {
-    this._libraryElement = libraryElement;
-    if (_inheritanceManager != null) {
-      _inheritanceManager.libraryElement = libraryElement;
-    }
-  }
-
-  /**
-   * Return the library scope used when resolving elements within this library's compilation units.
-   *
-   * @return the library scope used when resolving elements within this library's compilation units
-   */
-  LibraryScope get libraryScope {
-    if (_libraryScope == null) {
-      _libraryScope = new LibraryScope(_libraryElement, _errorListener);
-    }
-    return _libraryScope;
-  }
-
-  /**
-   * Return an array containing the compilation units that comprise this library. The defining
-   * compilation unit is always first.
-   *
-   * @return the compilation units that comprise this library
-   */
-  List<ResolvableCompilationUnit> get resolvableCompilationUnits =>
-      _compilationUnits;
-
-  /**
-   * Set the compilation unit in this library to the given compilation units. The defining
-   * compilation unit must be the first element of the array.
-   *
-   * @param units the compilation units in this library
-   */
-  void set resolvableCompilationUnits(List<ResolvableCompilationUnit> units) {
-    _compilationUnits = units;
-  }
-
-  /**
-   * Return the AST structure associated with the given source, or `null` if the source does
-   * not represent a compilation unit that is included in this library.
-   *
-   * @param source the source representing the compilation unit whose AST is to be returned
-   * @return the AST structure associated with the given source
-   * @throws AnalysisException if an AST structure could not be created for the compilation unit
-   */
-  CompilationUnit getAST(Source source) {
-    int count = _compilationUnits.length;
-    for (int i = 0; i < count; i++) {
-      if (_compilationUnits[i].source == source) {
-        return _compilationUnits[i].compilationUnit;
-      }
-    }
-    return null;
-  }
-
-  @override
-  String toString() => librarySource.shortName;
-
-  static int _nextHashCode() {
-    int next = (_NEXT_HASH_CODE + 1) & 0xFFFFFF;
-    _NEXT_HASH_CODE = next;
-    return next;
-  }
-}
-
-/**
  * The enumeration `ResolverErrorCode` defines the error codes used for errors
  * detected by the resolver. The convention for this class is for the name of
  * the error code to indicate the problem that caused the error to be generated
@@ -10603,11 +7891,6 @@
  */
 class ResolverVisitor extends ScopedVisitor {
   /**
-   * The manager for the inheritance mappings.
-   */
-  InheritanceManager _inheritanceManager;
-
-  /**
    * The object used to resolve the element associated with the current node.
    */
   ElementResolver elementResolver;
@@ -10693,16 +7976,9 @@
    */
   ResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
-      {Scope nameScope,
-      InheritanceManager inheritanceManager,
-      StaticTypeAnalyzerFactory typeAnalyzerFactory})
+      {Scope nameScope})
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
-    if (inheritanceManager == null) {
-      this._inheritanceManager = new InheritanceManager(definingLibrary);
-    } else {
-      this._inheritanceManager = inheritanceManager;
-    }
     this.elementResolver = new ElementResolver(this);
     this.typeSystem = definingLibrary.context.typeSystem;
     bool strongModeHints = false;
@@ -10712,33 +7988,10 @@
     }
     this.inferenceContext = new InferenceContext._(
         errorListener, typeProvider, typeSystem, strongModeHints);
-    if (typeAnalyzerFactory == null) {
-      this.typeAnalyzer = new StaticTypeAnalyzer(this);
-    } else {
-      this.typeAnalyzer = typeAnalyzerFactory(this);
-    }
+    this.typeAnalyzer = new StaticTypeAnalyzer(this);
   }
 
   /**
-   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
-   *
-   * @param library the library containing the compilation unit being resolved
-   * @param source the source representing the compilation unit being visited
-   * @param typeProvider the object used to access the types from the core library
-   *
-   * Deprecated.  Please use unnamed constructor instead.
-   */
-  @deprecated
-  ResolverVisitor.con1(
-      Library library, Source source, TypeProvider typeProvider,
-      {StaticTypeAnalyzerFactory typeAnalyzerFactory})
-      : this(
-            library.libraryElement, source, typeProvider, library.errorListener,
-            nameScope: library.libraryScope,
-            inheritanceManager: library.inheritanceManager,
-            typeAnalyzerFactory: typeAnalyzerFactory);
-
-  /**
    * Return the element representing the function containing the current node, or `null` if
    * the current node is not contained in a function.
    *
@@ -11061,9 +8314,9 @@
   @override
   Object visitAssignmentExpression(AssignmentExpression node) {
     safelyVisit(node.leftHandSide);
-    sc.TokenType operator = node.operator.type;
-    if (operator == sc.TokenType.EQ ||
-        operator == sc.TokenType.QUESTION_QUESTION_EQ) {
+    TokenType operator = node.operator.type;
+    if (operator == TokenType.EQ ||
+        operator == TokenType.QUESTION_QUESTION_EQ) {
       InferenceContext.setType(
           node.rightHandSide, node.leftHandSide.staticType);
     }
@@ -11087,10 +8340,10 @@
 
   @override
   Object visitBinaryExpression(BinaryExpression node) {
-    sc.TokenType operatorType = node.operator.type;
+    TokenType operatorType = node.operator.type;
     Expression leftOperand = node.leftOperand;
     Expression rightOperand = node.rightOperand;
-    if (operatorType == sc.TokenType.AMPERSAND_AMPERSAND) {
+    if (operatorType == TokenType.AMPERSAND_AMPERSAND) {
       safelyVisit(leftOperand);
       if (rightOperand != null) {
         _overrideManager.enterScope();
@@ -11113,7 +8366,7 @@
           _overrideManager.exitScope();
         }
       }
-    } else if (operatorType == sc.TokenType.BAR_BAR) {
+    } else if (operatorType == TokenType.BAR_BAR) {
       safelyVisit(leftOperand);
       if (rightOperand != null) {
         _overrideManager.enterScope();
@@ -11754,22 +9007,23 @@
   @override
   Object visitListLiteral(ListLiteral node) {
     DartType contextType = InferenceContext.getType(node);
-    if (node.typeArguments == null && contextType is InterfaceType) {
+    List<DartType> targs = null;
+    if (node.typeArguments != null) {
+      targs = node.typeArguments.arguments.map((t) => t.type).toList();
+    } else if (contextType is InterfaceType) {
       InterfaceType listD =
           typeProvider.listType.substitute4([typeProvider.dynamicType]);
-      List<DartType> targs = inferenceContext.matchTypes(listD, contextType);
-      if (targs != null &&
-          targs.length == 1 &&
-          targs.any((t) => !t.isDynamic)) {
-        DartType eType = targs[0];
-        InterfaceType listT = typeProvider.listType.substitute4([eType]);
-        for (Expression child in node.elements) {
-          InferenceContext.setType(child, eType);
-        }
-        InferenceContext.setType(node, listT);
-      } else {
-        InferenceContext.clearType(node);
+      targs = inferenceContext.matchTypes(listD, contextType);
+    }
+    if (targs != null && targs.length == 1 && !targs[0].isDynamic) {
+      DartType eType = targs[0];
+      InterfaceType listT = typeProvider.listType.substitute4([eType]);
+      for (Expression child in node.elements) {
+        InferenceContext.setType(child, eType);
       }
+      InferenceContext.setType(node, listT);
+    } else {
+      InferenceContext.clearType(node);
     }
     super.visitListLiteral(node);
     return null;
@@ -11778,24 +9032,25 @@
   @override
   Object visitMapLiteral(MapLiteral node) {
     DartType contextType = InferenceContext.getType(node);
-    if (node.typeArguments == null && contextType is InterfaceType) {
+    List<DartType> targs = null;
+    if (node.typeArguments != null) {
+      targs = node.typeArguments.arguments.map((t) => t.type).toList();
+    } else if (contextType is InterfaceType) {
       InterfaceType mapD = typeProvider.mapType
           .substitute4([typeProvider.dynamicType, typeProvider.dynamicType]);
-      List<DartType> targs = inferenceContext.matchTypes(mapD, contextType);
-      if (targs != null &&
-          targs.length == 2 &&
-          targs.any((t) => !t.isDynamic)) {
-        DartType kType = targs[0];
-        DartType vType = targs[1];
-        InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]);
-        for (MapLiteralEntry entry in node.entries) {
-          InferenceContext.setType(entry.key, kType);
-          InferenceContext.setType(entry.value, vType);
-        }
-        InferenceContext.setType(node, mapT);
-      } else {
-        InferenceContext.clearType(node);
+      targs = inferenceContext.matchTypes(mapD, contextType);
+    }
+    if (targs != null && targs.length == 2 && targs.any((t) => !t.isDynamic)) {
+      DartType kType = targs[0];
+      DartType vType = targs[1];
+      InterfaceType mapT = typeProvider.mapType.substitute4([kType, vType]);
+      for (MapLiteralEntry entry in node.entries) {
+        InferenceContext.setType(entry.key, kType);
+        InferenceContext.setType(entry.value, vType);
       }
+      InferenceContext.setType(node, mapT);
+    } else {
+      InferenceContext.clearType(node);
     }
     super.visitMapLiteral(node);
     return null;
@@ -11821,11 +9076,20 @@
     // because it needs to be visited in the context of the invocation.
     //
     safelyVisit(node.target);
+    safelyVisit(node.typeArguments);
     node.accept(elementResolver);
     _inferFunctionExpressionsParametersTypes(node.argumentList);
     Element methodElement = node.methodName.staticElement;
-    if (methodElement is ExecutableElement) {
-      InferenceContext.setType(node.argumentList, methodElement.type);
+    DartType contextType = null;
+    if (methodElement is PropertyAccessorElement && methodElement.isGetter) {
+      contextType = methodElement.returnType;
+    } else if (methodElement is VariableElement) {
+      contextType = methodElement.type;
+    } else if (methodElement is ExecutableElement) {
+      contextType = methodElement.type;
+    }
+    if (contextType is FunctionType) {
+      InferenceContext.setType(node.argumentList, contextType);
     }
     safelyVisit(node.argumentList);
     node.accept(typeAnalyzer);
@@ -12345,7 +9609,7 @@
   void _promoteTypes(Expression condition) {
     if (condition is BinaryExpression) {
       BinaryExpression binary = condition;
-      if (binary.operator.type == sc.TokenType.AMPERSAND_AMPERSAND) {
+      if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) {
         Expression left = binary.leftOperand;
         Expression right = binary.rightOperand;
         _promoteTypes(left);
@@ -12371,7 +9635,7 @@
   void _propagateFalseState(Expression condition) {
     if (condition is BinaryExpression) {
       BinaryExpression binary = condition;
-      if (binary.operator.type == sc.TokenType.BAR_BAR) {
+      if (binary.operator.type == TokenType.BAR_BAR) {
         _propagateFalseState(binary.leftOperand);
         _propagateFalseState(binary.rightOperand);
       }
@@ -12385,7 +9649,7 @@
       }
     } else if (condition is PrefixExpression) {
       PrefixExpression prefix = condition;
-      if (prefix.operator.type == sc.TokenType.BANG) {
+      if (prefix.operator.type == TokenType.BANG) {
         _propagateTrueState(prefix.operand);
       }
     } else if (condition is ParenthesizedExpression) {
@@ -12412,7 +9676,7 @@
   void _propagateTrueState(Expression condition) {
     if (condition is BinaryExpression) {
       BinaryExpression binary = condition;
-      if (binary.operator.type == sc.TokenType.AMPERSAND_AMPERSAND) {
+      if (binary.operator.type == TokenType.AMPERSAND_AMPERSAND) {
         _propagateTrueState(binary.leftOperand);
         _propagateTrueState(binary.rightOperand);
       }
@@ -12426,7 +9690,7 @@
       }
     } else if (condition is PrefixExpression) {
       PrefixExpression prefix = condition;
-      if (prefix.operator.type == sc.TokenType.BANG) {
+      if (prefix.operator.type == TokenType.BANG) {
         _propagateFalseState(prefix.operand);
       }
     } else if (condition is ParenthesizedExpression) {
@@ -12762,7 +10026,7 @@
    * @param token the token specifying the location of the error
    * @param arguments the arguments to the error, used to compose the error message
    */
-  void reportErrorForToken(ErrorCode errorCode, sc.Token token,
+  void reportErrorForToken(ErrorCode errorCode, Token token,
       [List<Object> arguments]) {
     errorListener.onError(new AnalysisError(
         source, token.offset, token.length, errorCode, arguments));
@@ -13505,12 +10769,12 @@
    *
    * @param token the head of the list of tokens being searched
    */
-  void _gatherTodoComments(sc.Token token) {
-    while (token != null && token.type != sc.TokenType.EOF) {
-      sc.Token commentToken = token.precedingComments;
+  void _gatherTodoComments(Token token) {
+    while (token != null && token.type != TokenType.EOF) {
+      Token commentToken = token.precedingComments;
       while (commentToken != null) {
-        if (commentToken.type == sc.TokenType.SINGLE_LINE_COMMENT ||
-            commentToken.type == sc.TokenType.MULTI_LINE_COMMENT) {
+        if (commentToken.type == TokenType.SINGLE_LINE_COMMENT ||
+            commentToken.type == TokenType.MULTI_LINE_COMMENT) {
           _scrapeTodoComment(commentToken);
         }
         commentToken = commentToken.next;
@@ -13524,7 +10788,7 @@
    *
    * @param commentToken the comment token to analyze
    */
-  void _scrapeTodoComment(sc.Token commentToken) {
+  void _scrapeTodoComment(Token commentToken) {
     JavaPatternMatcher matcher =
         new JavaPatternMatcher(TodoCode.TODO_REGEX, commentToken.lexeme);
     if (matcher.find()) {
@@ -14481,6 +11745,8 @@
     super.visitClassDeclaration(node);
     ClassElementImpl classElement = _getClassElement(node.name);
     if (classElement != null) {
+      // Clear this flag, as we just invalidated any inferred member types.
+      classElement.hasBeenInferred = false;
       classElement.hasReferenceToSuper = _hasReferenceToSuper;
     }
     return null;
@@ -15399,7 +12665,7 @@
     // If the type is not an InterfaceType, then visitTypeName() sets the type
     // to be a DynamicTypeImpl
     Identifier name = typeName.name;
-    if (name.name == sc.Keyword.DYNAMIC.syntax) {
+    if (name.name == Keyword.DYNAMIC.syntax) {
       reportErrorForNode(dynamicTypeError, name, [name.name]);
     } else {
       reportErrorForNode(nonTypeError, name, [name.name]);
@@ -15472,8 +12738,8 @@
    * @return `true` if the name of the given [TypeName] is an built-in identifier.
    */
   static bool _isBuiltInIdentifier(TypeName node) {
-    sc.Token token = node.name.beginToken;
-    return token.type == sc.TokenType.KEYWORD;
+    Token token = node.name.beginToken;
+    return token.type == TokenType.KEYWORD;
   }
 
   /**
@@ -15769,22 +13035,6 @@
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope);
 
-  /**
-   * Initialize a newly created visitor to resolve the nodes in a compilation unit.
-   *
-   * @param library the library containing the compilation unit being resolved
-   * @param source the source representing the compilation unit being visited
-   * @param typeProvider the object used to access the types from the core library
-   *
-   * Deprecated.  Please use unnamed constructor instead.
-   */
-  @deprecated
-  VariableResolverVisitor.con1(
-      Library library, Source source, TypeProvider typeProvider)
-      : this(
-            library.libraryElement, source, typeProvider, library.errorListener,
-            nameScope: library.libraryScope);
-
   @override
   Object visitExportDirective(ExportDirective node) => null;
 
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index a99997a..49ea3ba 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -2,13 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.scanner;
+library analyzer.src.generated.scanner;
 
 import 'dart:collection';
 
-import 'error.dart';
-import 'java_engine.dart';
-import 'source.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/source.dart';
 
 /**
  * The opening half of a grouping pair of tokens. This is used for curly
@@ -246,7 +246,6 @@
   CommentToken copy() => new CommentToken(type, _value, offset);
 }
 
-
 /**
  * A documentation comment token.
  */
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index c4f034f..4c756e2 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.sdk;
+library analyzer.src.generated.sdk;
 
 import 'dart:collection';
 
-import 'ast.dart';
-import 'engine.dart' show AnalysisContext;
-import 'source.dart' show ContentCache, Source, UriKind;
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/source.dart'
+    show ContentCache, Source, UriKind;
 
 /**
  * A Dart SDK installed in a specified location.
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index b155b9a..1f98ba3 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -2,23 +2,22 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.sdk.io;
+library analyzer.src.generated.sdk_io;
 
 import 'dart:io';
 
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
-
-import 'ast.dart';
-import 'engine.dart';
-import 'error.dart';
-import 'java_core.dart';
-import 'java_engine_io.dart';
-import 'java_io.dart';
-import 'parser.dart';
-import 'scanner.dart';
-import 'sdk.dart';
-import 'source_io.dart';
+import 'package:analyzer/src/generated/java_engine_io.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source_io.dart';
 
 /**
  * A Dart SDK installed in a specified directory. Typical Dart SDK layout is
@@ -242,11 +241,7 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      if (AnalysisEngine.instance.useTaskModel) {
-        _analysisContext = new newContext.SdkAnalysisContext();
-      } else {
-        _analysisContext = new SdkAnalysisContext();
-      }
+      _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
       List<String> uris = this.uris;
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 79cd48f..3c25f11 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.source;
+library analyzer.src.generated.source;
 
 import 'dart:collection';
 import "dart:math" as math;
@@ -10,18 +10,17 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
+import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
+import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
 import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
 import 'package:analyzer/task/model.dart';
 import 'package:package_config/packages.dart';
 import 'package:path/path.dart' as pathos;
 
-import 'engine.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'java_io.dart' show JavaFile;
-import 'sdk.dart' show DartSdk;
-import 'source_io.dart' show FileBasedSource;
-
 /**
  * A function that is used to visit [ContentCache] entries.
  */
@@ -411,12 +410,6 @@
   /**
    * An empty list of sources.
    */
-  @deprecated // Use Source.EMPTY_LIST
-  static const List<Source> EMPTY_ARRAY = EMPTY_LIST;
-
-  /**
-   * An empty list of sources.
-   */
   static const List<Source> EMPTY_LIST = const <Source>[];
 
   /**
@@ -668,6 +661,17 @@
   }
 
   /**
+   * Return a source factory that will resolve URI's in the same way that this
+   * source factory does.
+   */
+  SourceFactory clone() {
+    SourceFactory factory =
+        new SourceFactory(_resolvers, _packages, _resourceProvider);
+    factory.localSourcePredicate = _localSourcePredicate;
+    return factory;
+  }
+
+  /**
    * Return a source object representing the given absolute URI, or `null` if the URI is not a
    * valid URI or if it is not an absolute URI.
    *
@@ -734,14 +738,11 @@
   bool isLocalSource(Source source) => _localSourcePredicate.isLocal(source);
 
   /**
-   * Return a source object representing the URI that results from resolving the given (possibly
-   * relative) contained URI against the URI associated with an existing source object, whether or
-   * not the resulting source exists, or `null` if either the contained URI is invalid or if
-   * it cannot be resolved against the source object's URI.
-   *
-   * @param containingSource the source containing the given URI
-   * @param containedUri the (possibly relative) URI to be resolved against the containing source
-   * @return the source representing the contained URI
+   * Return a source representing the URI that results from resolving the given
+   * (possibly relative) [containedUri] against the URI associated with the
+   * [containingSource], whether or not the resulting source exists, or `null`
+   * if either the [containedUri] is invalid or if it cannot be resolved against
+   * the [containingSource]'s URI.
    */
   Source resolveUri(Source containingSource, String containedUri) {
     if (containedUri == null || containedUri.isEmpty) {
@@ -751,6 +752,8 @@
       // Force the creation of an escaped URI to deal with spaces, etc.
       return _internalResolveUri(
           containingSource, parseUriWithException(containedUri));
+    } on URISyntaxException {
+      return null;
     } catch (exception, stackTrace) {
       String containingFullName =
           containingSource != null ? containingSource.fullName : '<null>';
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 0c5d9e8..4847d9a 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -2,17 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.source.io;
+library analyzer.src.generated.source_io;
 
 import 'dart:collection';
 
-import 'engine.dart';
-import 'java_core.dart';
-import 'java_engine.dart';
-import 'java_io.dart';
-import 'source.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
+import 'package:analyzer/src/generated/source.dart';
 
-export 'source.dart';
+export 'package:analyzer/src/generated/source.dart';
 
 /**
  * Instances of the class [DirectoryBasedSourceContainer] represent a source container that
@@ -136,27 +136,6 @@
             '${uri == null ? file.toURI() : uri}@${file.getPath()}',
             () => _idTable.length);
 
-  /**
-   * Initialize a newly created source object.
-   *
-   * @param file the file represented by this source
-   */
-  @deprecated // Use new FileBasedSource(file)
-  FileBasedSource.con1(JavaFile file) : this(file);
-
-  /**
-   * Initialize a newly created source object.
-   *
-   * @param file the file represented by this source
-   * @param uri the URI from which this source was originally derived
-   */
-  @deprecated // Use new FileBasedSource(file, uri)
-  FileBasedSource.con2(Uri uri, JavaFile file)
-      : uri = uri,
-        file = file,
-        id = _idTable.putIfAbsent(
-            '$uri@${file.getPath()}', () => _idTable.length);
-
   @override
   TimestampedData<String> get contents {
     return PerformanceStatistics.io.makeCurrentWhile(() {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index a746a1e..96971cb 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -2,18 +2,17 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver.static_type_analyzer;
+library analyzer.src.generated.static_type_analyzer;
 
 import 'dart:collection';
 
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
-
-import 'ast.dart';
-import 'element.dart';
-import 'java_engine.dart';
-import 'resolver.dart';
-import 'scanner.dart' as sc;
-import 'utilities_dart.dart';
+import 'package:analyzer/src/generated/scanner.dart' as sc;
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
  * Instances of the class `StaticTypeAnalyzer` perform two type-related tasks. First, they
@@ -1823,31 +1822,51 @@
     Element element = node.methodName.staticElement;
     DartType fnType = node.methodName.staticType;
     TypeSystem ts = _typeSystem;
-    // TODO(jmesserly): once we allow explicitly passed typeArguments, we need
-    // to only do this if node.typeArguments == null.
-    if (element is ExecutableElement &&
+    if (node.typeArguments == null &&
+        element is ExecutableElement &&
         fnType is FunctionTypeImpl &&
         ts is StrongTypeSystemImpl) {
-      // We may have too many (or too few) arguments.  Only use arguments
-      // which have been matched up with a static parameter.
-      Iterable<Expression> arguments = node.argumentList.arguments
-          .where((e) => e.staticParameterElement != null);
-      List<DartType> argTypes = arguments.map((e) => e.staticType).toList();
-      List<DartType> paramTypes =
-          arguments.map((e) => e.staticParameterElement.type).toList();
+      FunctionTypeImpl genericFunction = fnType.originalFunction;
+      if (element is PropertyAccessorElement) {
+        genericFunction = element.type.returnType;
+      }
+      if (genericFunction.boundTypeParameters.isEmpty) {
+        return false;
+      }
+      for (DartType typeArg in fnType.instantiatedTypeArguments) {
+        if (!typeArg.isDynamic) {
+          return false;
+        }
+      }
+
+      List<ParameterElement> genericParameters = genericFunction.parameters;
+      List<DartType> argTypes = new List<DartType>();
+      List<DartType> paramTypes = new List<DartType>();
+      for (Expression arg in node.argumentList.arguments) {
+        // We may have too many (or too few) arguments.  Only use arguments
+        // which have been matched up with a static parameter.
+        ParameterElement p = arg.staticParameterElement;
+        if (p != null) {
+          int i = element.parameters.indexOf(p);
+          argTypes.add(arg.staticType);
+          paramTypes.add(genericParameters[i].type);
+        }
+      }
 
       FunctionType inferred = ts.inferCallFromArguments(
-          _typeProvider, fnType, paramTypes, argTypes);
+          _typeProvider, genericFunction, paramTypes, argTypes);
       if (inferred != fnType) {
-        // TODO(jmesserly): inference should be happening earlier, which would
-        // allow these parameters to be correct from the get-go.
-
+        // TODO(jmesserly): we need to fix up the parameter elements based on
+        // inferred method.
         List<ParameterElement> inferredParameters = inferred.parameters;
         List<ParameterElement> correspondingParams =
             new List<ParameterElement>();
-        for (Expression arg in arguments) {
-          int i = element.parameters.indexOf(arg.staticParameterElement);
-          correspondingParams.add(inferredParameters[i]);
+        for (Expression arg in node.argumentList.arguments) {
+          ParameterElement p = arg.staticParameterElement;
+          if (p != null) {
+            int i = element.parameters.indexOf(p);
+            correspondingParams.add(inferredParameters[i]);
+          }
         }
         node.argumentList.correspondingStaticParameters = correspondingParams;
         _recordStaticType(node.methodName, inferred);
@@ -1956,7 +1975,8 @@
    * Return `true` if the given [Type] is the `Future` form the 'dart:async'
    * library.
    */
-  bool _isAsyncFutureType(DartType type) => type is InterfaceType &&
+  bool _isAsyncFutureType(DartType type) =>
+      type is InterfaceType &&
       type.name == "Future" &&
       _isAsyncLibrary(type.element.library);
 
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index bb758b3..bfb87b6 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.ast_factory;
+library analyzer.src.generated.testing.ast_factory;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -46,11 +46,14 @@
       new AsExpression(
           expression, TokenFactory.tokenFromKeyword(Keyword.AS), type);
 
-  static AssertStatement assertStatement(Expression condition) =>
+  static AssertStatement assertStatement(Expression condition,
+          [Expression message]) =>
       new AssertStatement(
           TokenFactory.tokenFromKeyword(Keyword.ASSERT),
           TokenFactory.tokenFromType(TokenType.OPEN_PAREN),
           condition,
+          message == null ? null : TokenFactory.tokenFromType(TokenType.COMMA),
+          message,
           TokenFactory.tokenFromType(TokenType.CLOSE_PAREN),
           TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
@@ -431,6 +434,7 @@
           metadata,
           TokenFactory.tokenFromKeyword(Keyword.EXPORT),
           string2(uri),
+          null,
           combinators,
           TokenFactory.tokenFromType(TokenType.SEMICOLON));
 
@@ -657,6 +661,7 @@
           metadata,
           TokenFactory.tokenFromKeyword(Keyword.IMPORT),
           string2(uri),
+          null,
           !isDeferred ? null : TokenFactory.tokenFromKeyword(Keyword.DEFERRED),
           prefix == null ? null : TokenFactory.tokenFromKeyword(Keyword.AS),
           prefix == null ? null : identifier3(prefix),
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 4414103..4932e92 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.element_factory;
+library analyzer.src.generated.testing.element_factory;
 
 import 'dart:collection';
 
@@ -409,15 +409,6 @@
     return getter;
   }
 
-  @deprecated
-  static HtmlElementImpl htmlUnit(AnalysisContext context, String fileName) {
-    Source source =
-        new NonExistingSource(fileName, toUri(fileName), UriKind.FILE_URI);
-    HtmlElementImpl unit = new HtmlElementImpl(context, fileName);
-    unit.source = source;
-    return unit;
-  }
-
   static ImportElementImpl importFor(
       LibraryElement importedLibrary, PrefixElement prefix,
       [List<NamespaceCombinator> combinators =
diff --git a/pkg/analyzer/lib/src/generated/testing/html_factory.dart b/pkg/analyzer/lib/src/generated/testing/html_factory.dart
deleted file mode 100644
index a9ac412..0000000
--- a/pkg/analyzer/lib/src/generated/testing/html_factory.dart
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library engine.testing.html_factory;
-
-import 'package:analyzer/src/generated/html.dart';
-
-/**
- * Utility methods to create HTML nodes.
- */
-@deprecated
-class HtmlFactory {
-  static XmlAttributeNode attribute(String name, String value) {
-    Token nameToken = stringToken(name);
-    Token equalsToken = new Token.con1(TokenType.EQ, 0);
-    Token valueToken = stringToken(value);
-    return new XmlAttributeNode(nameToken, equalsToken, valueToken);
-  }
-
-  static Token gtToken() {
-    return new Token.con1(TokenType.GT, 0);
-  }
-
-  static Token ltsToken() {
-    return new Token.con1(TokenType.LT_SLASH, 0);
-  }
-
-  static Token ltToken() {
-    return new Token.con1(TokenType.LT, 0);
-  }
-
-  static HtmlScriptTagNode scriptTag(
-      [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
-    return new HtmlScriptTagNode(ltToken(), stringToken("script"), attributes,
-        sgtToken(), null, null, null, null);
-  }
-
-  static HtmlScriptTagNode scriptTagWithContent(String contents,
-      [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
-    Token attributeEnd = gtToken();
-    Token contentToken = stringToken(contents);
-    attributeEnd.setNext(contentToken);
-    Token contentEnd = ltsToken();
-    contentToken.setNext(contentEnd);
-    return new HtmlScriptTagNode(ltToken(), stringToken("script"), attributes,
-        attributeEnd, null, contentEnd, stringToken("script"), gtToken());
-  }
-
-  static Token sgtToken() {
-    return new Token.con1(TokenType.SLASH_GT, 0);
-  }
-
-  static Token stringToken(String value) {
-    return new Token.con2(TokenType.STRING, 0, value);
-  }
-
-  static XmlTagNode tagNode(String name,
-      [List<XmlAttributeNode> attributes = XmlAttributeNode.EMPTY_LIST]) {
-    return new XmlTagNode(ltToken(), stringToken(name), attributes, sgtToken(),
-        null, null, null, null);
-  }
-}
diff --git a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
index a183a6f..e44e2a3 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.test_type_provider;
+library analyzer.src.generated.testing.test_type_provider;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
diff --git a/pkg/analyzer/lib/src/generated/testing/token_factory.dart b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
index 1b9a828..a293842 100644
--- a/pkg/analyzer/lib/src/generated/testing/token_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/token_factory.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.testing.token_factory;
+library analyzer.src.generated.testing.token_factory;
 
 import 'package:analyzer/src/generated/scanner.dart';
 
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index f731360..e520222 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -6,9 +6,9 @@
 
 import 'dart:collection';
 
-import 'element.dart';
-import 'engine.dart' show AnalysisContext;
-import 'resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 
 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
 typedef bool _SubtypeChecker<T>(T t1, T t2);
@@ -22,6 +22,22 @@
 
   StrongTypeSystemImpl();
 
+  bool anyParameterType(FunctionType ft, bool predicate(DartType t)) {
+    return ft.parameters.any((p) => predicate(p.type));
+  }
+
+  /**
+   * Given a type t, if t is an interface type with a call method
+   * defined, return the function type for the call method, otherwise
+   * return null.
+   */
+  FunctionType getCallMethodType(DartType t) {
+    if (t is InterfaceType) {
+      return t.lookUpInheritedMethod("call")?.type;
+    }
+    return null;
+  }
+
   @override
   DartType getLeastUpperBound(
       TypeProvider typeProvider, DartType type1, DartType type2) {
@@ -128,9 +144,45 @@
     return fnType.instantiate(inferredTypes);
   }
 
-  // TODO(leafp): Document the rules in play here
+  /**
+   * Given a [FunctionType] [function], of the form
+   * <T0 extends B0, ... Tn extends Bn>.F (where Bi is implicitly
+   * dynamic if absent, and F is a non-generic function type)
+   * compute {I0/T0, ..., In/Tn}F
+   * where I_(i+1) = {I0/T0, ..., Ii/Ti, dynamic/T_(i+1)}B_(i+1).
+   * That is, we instantiate the generic with its bounds, replacing
+   * each Ti in Bi with dynamic to get Ii, and then replacing Ti with
+   * Ii in all of the remaining bounds.
+   */
+  DartType instantiateToBounds(FunctionType function) {
+    int count = function.boundTypeParameters.length;
+    if (count == 0) {
+      return function;
+    }
+    // We build up a substitution replacing bound parameters with
+    // their instantiated bounds, {substituted/variables}
+    List<DartType> substituted = new List<DartType>();
+    List<DartType> variables = new List<DartType>();
+    for (int i = 0; i < count; i++) {
+      TypeParameterElement param = function.boundTypeParameters[i];
+      DartType bound = param.bound ?? DynamicTypeImpl.instance;
+      DartType variable = param.type;
+      // For each Ti extends Bi, first compute Ii by replacing
+      // Ti in Bi with dynamic (simultaneously replacing all
+      // of the previous Tj (j < i) with their instantiated bounds.
+      substituted.add(DynamicTypeImpl.instance);
+      variables.add(variable);
+      // Now update the substitution to replace Ti with Ii instead
+      // of dynamic in subsequent rounds.
+      substituted[i] = bound.substitute2(substituted, variables);
+    }
+    return function.instantiate(substituted);
+  }
+
   @override
   bool isAssignableTo(DartType fromType, DartType toType) {
+    // TODO(leafp): Document the rules in play here
+
     // An actual subtype
     if (isSubtypeOf(fromType, toType)) {
       return true;
@@ -138,8 +190,8 @@
 
     // Don't allow implicit downcasts between function types
     // and call method objects, as these will almost always fail.
-    if ((fromType is FunctionType && _getCallMethodType(toType) != null) ||
-        (toType is FunctionType && _getCallMethodType(fromType) != null)) {
+    if ((fromType is FunctionType && getCallMethodType(toType) != null) ||
+        (toType is FunctionType && getCallMethodType(fromType) != null)) {
       return false;
     }
 
@@ -160,21 +212,40 @@
     return false;
   }
 
+  bool isGroundType(DartType t) {
+    // TODO(leafp): Revisit this.
+    if (t is TypeParameterType) return false;
+    if (_isTop(t)) return true;
+
+    if (t is FunctionType) {
+      if (!_isTop(t.returnType) ||
+          anyParameterType(t, (pt) => !_isBottom(pt, dynamicIsBottom: true))) {
+        return false;
+      } else {
+        return true;
+      }
+    }
+
+    if (t is InterfaceType) {
+      var typeArguments = t.typeArguments;
+      for (var typeArgument in typeArguments) {
+        if (!_isTop(typeArgument)) return false;
+      }
+      return true;
+    }
+
+    // We should not see any other type aside from malformed code.
+    return false;
+  }
+
   @override
   bool isSubtypeOf(DartType leftType, DartType rightType) {
     return _isSubtypeOf(leftType, rightType, null);
   }
 
-  // Given a type t, if t is an interface type with a call method
-  // defined, return the function type for the call method, otherwise
-  // return null.
-  FunctionType _getCallMethodType(DartType t) {
-    if (t is InterfaceType) {
-      return t.lookUpInheritedMethod("call")?.type;
-    }
-    return null;
-  }
-
+  /**
+   * Guard against loops in the class hierarchy
+   */
   _GuardedSubtypeChecker<DartType> _guard(
       _GuardedSubtypeChecker<DartType> check) {
     return (DartType t1, DartType t2, Set<Element> visited) {
@@ -205,7 +276,6 @@
     return (t.isDynamic && dynamicIsBottom) || t.isBottom;
   }
 
-  // Guard against loops in the class hierarchy
   /**
    * Check that [f1] is a subtype of [f2].
    * [fuzzyArrows] indicates whether or not the f1 and f2 should be
@@ -214,14 +284,22 @@
    */
   bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
       {bool fuzzyArrows: true}) {
-    final r1s = f1.normalParameterTypes;
-    final o1s = f1.optionalParameterTypes;
-    final n1s = f1.namedParameterTypes;
-    final r2s = f2.normalParameterTypes;
-    final o2s = f2.optionalParameterTypes;
-    final n2s = f2.namedParameterTypes;
-    final ret1 = f1.returnType;
-    final ret2 = f2.returnType;
+    if (!f1.boundTypeParameters.isEmpty) {
+      if (f2.boundTypeParameters.isEmpty) {
+        f1 = instantiateToBounds(f1);
+        return _isFunctionSubtypeOf(f1, f2);
+      } else {
+        return _isGenericFunctionSubtypeOf(f1, f2, fuzzyArrows: fuzzyArrows);
+      }
+    }
+    final List<DartType> r1s = f1.normalParameterTypes;
+    final List<DartType> r2s = f2.normalParameterTypes;
+    final List<DartType> o1s = f1.optionalParameterTypes;
+    final List<DartType> o2s = f2.optionalParameterTypes;
+    final Map<String, DartType> n1s = f1.namedParameterTypes;
+    final Map<String, DartType> n2s = f2.namedParameterTypes;
+    final DartType ret1 = f1.returnType;
+    final DartType ret2 = f2.returnType;
 
     // A -> B <: C -> D if C <: A and
     // either D is void or B <: D
@@ -293,6 +371,54 @@
     return true;
   }
 
+  /**
+   * Check that [f1] is a subtype of [f2] where f1 and f2 are known
+   * to be generic function types (both have type parameters)
+   * [fuzzyArrows] indicates whether or not the f1 and f2 should be
+   * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
+   * as bottom).
+   */
+  bool _isGenericFunctionSubtypeOf(FunctionType f1, FunctionType f2,
+      {bool fuzzyArrows: true}) {
+    List<TypeParameterElement> params1 = f1.boundTypeParameters;
+    List<TypeParameterElement> params2 = f2.boundTypeParameters;
+    int count = params1.length;
+    if (params2.length != count) {
+      return false;
+    }
+    // We build up a substitution matching up the type parameters
+    // from the two types, {variablesFresh/variables1} and
+    // {variablesFresh/variables2}
+    List<DartType> variables1 = new List<DartType>();
+    List<DartType> variables2 = new List<DartType>();
+    List<DartType> variablesFresh = new List<DartType>();
+    for (int i = 0; i < count; i++) {
+      TypeParameterElement p1 = params1[i];
+      TypeParameterElement p2 = params2[i];
+      TypeParameterElementImpl pFresh =
+          new TypeParameterElementImpl(p2.name, -1);
+
+      DartType variable1 = p1.type;
+      DartType variable2 = p2.type;
+      DartType variableFresh = new TypeParameterTypeImpl(pFresh);
+
+      variables1.add(variable1);
+      variables2.add(variable2);
+      variablesFresh.add(variableFresh);
+      DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
+      DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
+      bound1 = bound1.substitute2(variablesFresh, variables1);
+      bound2 = bound2.substitute2(variablesFresh, variables2);
+      pFresh.bound = bound2;
+      if (!isSubtypeOf(bound2, bound1)) {
+        return false;
+      }
+    }
+    return _isFunctionSubtypeOf(
+        f1.instantiate(variablesFresh), f2.instantiate(variablesFresh),
+        fuzzyArrows: fuzzyArrows);
+  }
+
   bool _isInterfaceSubtypeOf(
       InterfaceType i1, InterfaceType i2, Set<Element> visited) {
     // Guard recursive calls
@@ -407,7 +533,7 @@
     // the interface type declares a call method with a type
     // which is a super type of the function type.
     if (t1 is InterfaceType && t2 is FunctionType) {
-      var callType = _getCallMethodType(t1);
+      var callType = getCallMethodType(t1);
       return (callType != null) && _isFunctionSubtypeOf(callType, t2);
     }
 
@@ -440,6 +566,15 @@
       TypeProvider typeProvider, DartType type1, DartType type2);
 
   /**
+   * Given a [function] type, instantiate it with its bounds.
+   *
+   * The behavior of this method depends on the type system, for example, in
+   * classic Dart `dynamic` will be used for all type arguments, whereas
+   * strong mode prefers the actual bound type if it was specified.
+   */
+  FunctionType instantiateToBounds(FunctionType function);
+
+  /**
    * Return `true` if the [leftType] is assignable to the [rightType] (that is,
    * if leftType <==> rightType).
    */
@@ -547,6 +682,18 @@
     }
   }
 
+  /**
+   * Instantiate the function type using `dynamic` for all generic parameters.
+   */
+  FunctionType instantiateToBounds(FunctionType function) {
+    int count = function.boundTypeParameters.length;
+    if (count == 0) {
+      return function;
+    }
+    return function.instantiate(
+        new List<DartType>.filled(count, DynamicTypeImpl.instance));
+  }
+
   @override
   bool isAssignableTo(DartType leftType, DartType rightType) {
     return leftType.isAssignableTo(rightType);
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index 0d2afe8..6a71b97 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -2,13 +2,13 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.collection;
+library analyzer.src.generated.utilities_collection;
 
-import "dart:math" as math;
 import 'dart:collection';
+import "dart:math" as math;
 
-import 'java_core.dart';
-import 'scanner.dart' show Token;
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/scanner.dart' show Token;
 
 /**
  * The class `BooleanArray` defines methods for operating on integers as if they were arrays
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index 882d182..5fe5e72 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -2,9 +2,9 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.dart;
+library analyzer.src.generated.utilities_dart;
 
-import 'java_core.dart';
+import 'package:analyzer/src/generated/java_core.dart';
 
 /**
  * Check whether [uri1] starts with (or 'is prefixed by') [uri2] by checking
diff --git a/pkg/analyzer/lib/src/generated/utilities_general.dart b/pkg/analyzer/lib/src/generated/utilities_general.dart
index c1a3446..004433c 100644
--- a/pkg/analyzer/lib/src/generated/utilities_general.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_general.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.general;
+library analyzer.src.generated.utilities_general;
 
 import 'dart:collection';
 import 'dart:developer' show UserTag;
diff --git a/pkg/analyzer/lib/src/generated/visitors.dart b/pkg/analyzer/lib/src/generated/visitors.dart
index 59e644f..46e2a41 100644
--- a/pkg/analyzer/lib/src/generated/visitors.dart
+++ b/pkg/analyzer/lib/src/generated/visitors.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.ast.visitors;
+library analyzer.src.generated.visitors;
 
 import 'package:analyzer/src/generated/ast.dart';
 
@@ -153,6 +153,13 @@
   }
 
   @override
+  T visitConfiguration(Configuration node) {
+    _delegates.forEach((delegate) => delegate.visitConfiguration(node));
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   T visitConstructorDeclaration(ConstructorDeclaration node) {
     _delegates
         .forEach((delegate) => delegate.visitConstructorDeclaration(node));
@@ -205,6 +212,13 @@
   }
 
   @override
+  T visitDottedName(DottedName node) {
+    _delegates.forEach((delegate) => delegate.visitDottedName(node));
+    node.visitChildren(this);
+    return null;
+  }
+
+  @override
   T visitDoubleLiteral(DoubleLiteral node) {
     _delegates.forEach((delegate) => delegate.visitDoubleLiteral(node));
     node.visitChildren(this);
@@ -291,15 +305,15 @@
   }
 
   @override
-  T visitForStatement(ForStatement node) {
-    _delegates.forEach((delegate) => delegate.visitForStatement(node));
+  T visitFormalParameterList(FormalParameterList node) {
+    _delegates.forEach((delegate) => delegate.visitFormalParameterList(node));
     node.visitChildren(this);
     return null;
   }
 
   @override
-  T visitFormalParameterList(FormalParameterList node) {
-    _delegates.forEach((delegate) => delegate.visitFormalParameterList(node));
+  T visitForStatement(ForStatement node) {
+    _delegates.forEach((delegate) => delegate.visitForStatement(node));
     node.visitChildren(this);
     return null;
   }
@@ -542,15 +556,15 @@
   }
 
   @override
-  T visitPrefixExpression(PrefixExpression node) {
-    _delegates.forEach((delegate) => delegate.visitPrefixExpression(node));
+  T visitPrefixedIdentifier(PrefixedIdentifier node) {
+    _delegates.forEach((delegate) => delegate.visitPrefixedIdentifier(node));
     node.visitChildren(this);
     return null;
   }
 
   @override
-  T visitPrefixedIdentifier(PrefixedIdentifier node) {
-    _delegates.forEach((delegate) => delegate.visitPrefixedIdentifier(node));
+  T visitPrefixExpression(PrefixExpression node) {
+    _delegates.forEach((delegate) => delegate.visitPrefixExpression(node));
     node.visitChildren(this);
     return null;
   }
diff --git a/pkg/analyzer/lib/src/plugin/options_plugin.dart b/pkg/analyzer/lib/src/plugin/options_plugin.dart
index 6e0ebd6..6fba649 100644
--- a/pkg/analyzer/lib/src/plugin/options_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/options_plugin.dart
@@ -2,7 +2,7 @@
 // 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.src.plugin.options;
+library analyzer.src.plugin.options_plugin;
 
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/plugin/task.dart';
diff --git a/pkg/analyzer/lib/src/plugin/plugin_configuration.dart b/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
index 9365a3c..222e376 100644
--- a/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
+++ b/pkg/analyzer/lib/src/plugin/plugin_configuration.dart
@@ -84,10 +84,11 @@
   PluginConfig(this.plugins);
 
   /// Create a plugin configuration from an options map.
-  factory PluginConfig.fromOptions(Map<String, YamlNode> options) {
+  factory PluginConfig.fromOptions(Map<String, Object> options) {
     List<PluginInfo> plugins = [];
     var analyzerOptions = options[_analyzerOptionScope];
     if (analyzerOptions != null) {
+      //TODO(pq): handle "raw" maps (https://github.com/dart-lang/sdk/issues/25126)
       if (analyzerOptions is YamlMap) {
         var pluginConfig = analyzerOptions[_pluginOptionScope];
         if (pluginConfig is YamlMap) {
@@ -143,7 +144,7 @@
 
   @override
   void optionsProcessed(
-      AnalysisContext context, Map<String, YamlNode> options) {
+      AnalysisContext context, Map<String, Object> options) {
     _config = new PluginConfig.fromOptions(options);
   }
 }
diff --git a/pkg/analyzer/lib/src/services/lint.dart b/pkg/analyzer/lib/src/services/lint.dart
index a6b55cc..91d72a2 100644
--- a/pkg/analyzer/lib/src/services/lint.dart
+++ b/pkg/analyzer/lib/src/services/lint.dart
@@ -2,7 +2,7 @@
 // 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 lint;
+library analyzer.src.services.lint;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
index 5ffb332..0c99e69 100644
--- a/pkg/analyzer/lib/src/string_source.dart
+++ b/pkg/analyzer/lib/src/string_source.dart
@@ -2,10 +2,10 @@
 // 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.string_source;
+library analyzer.src.string_source;
 
-import 'generated/engine.dart' show TimestampedData;
-import 'generated/source.dart';
+import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
+import 'package:analyzer/src/generated/source.dart';
 
 /// An implementation of [Source] that's based on an in-memory Dart string.
 class StringSource extends Source {
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 1a5046d..773515c 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -10,8 +10,7 @@
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisCache, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/error_verifier.dart';
 import 'package:analyzer/src/generated/incremental_resolver.dart';
@@ -30,7 +29,6 @@
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
-import 'package:analyzer/src/task/strong/rules.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/general.dart';
@@ -2299,19 +2297,11 @@
       String inputName = result.name + '_input';
       errorLists.add(getRequiredInput(inputName));
     }
-
-    //
-    // Gather error filters.
-    //
-    List<ErrorFilter> filters =
-        context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
     for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) {
       String inputName = result.name + '_input';
       Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName);
       for (List<AnalysisError> errors in errorMap.values) {
-        errorLists.add(errors.where((AnalysisError error) {
-          return !filters.any((ErrorFilter filter) => filter(error));
-        }).toList());
+        errorLists.add(errors);
       }
     }
     //
@@ -3597,11 +3587,8 @@
     //
     // Resolve references and record outputs.
     //
-    InheritanceManager inheritanceManager =
-        new InheritanceManager(libraryElement);
     PartialResolverVisitor visitor = new PartialResolverVisitor(libraryElement,
-        unitElement.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
-        inheritanceManager: inheritanceManager);
+        unitElement.source, typeProvider, AnalysisErrorListener.NULL_LISTENER);
     unit.accept(visitor);
     //
     // Record outputs.
@@ -4387,14 +4374,11 @@
       // the size of the enclosing class, and hence incrementally resolving each
       // field was quadratic.  We may wish to revisit this if we can resolve
       // this performance issue.
-      InheritanceManager inheritanceManager =
-          new InheritanceManager(libraryElement);
       PartialResolverVisitor visitor = new PartialResolverVisitor(
           libraryElement,
           unitElement.source,
           typeProvider,
-          AnalysisErrorListener.NULL_LISTENER,
-          inheritanceManager: inheritanceManager);
+          AnalysisErrorListener.NULL_LISTENER);
       unit.accept(visitor);
     }
     //
@@ -5007,7 +4991,8 @@
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
     if (context.analysisOptions.strongMode) {
-      unit.accept(new CodeChecker(new TypeRules(typeProvider), errorListener));
+      unit.accept(new CodeChecker(
+          typeProvider, new StrongTypeSystemImpl(), errorListener));
     }
 
     //
@@ -5102,7 +5087,8 @@
         libraryElement,
         typeProvider,
         new InheritanceManager(libraryElement),
-        context.analysisOptions.enableSuperMixins);
+        context.analysisOptions.enableSuperMixins,
+        context.analysisOptions.enableAssertMessage);
     unit.accept(errorVerifier);
 
     //
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 793d9ce..a586b3b 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -474,7 +474,7 @@
   }
 
   bool _shouldErrorsBeComputed(Source source) =>
-      context.shouldErrorsBeAnalyzed(source, null);
+      context.shouldErrorsBeAnalyzed(source);
 
   static bool _isDartSource(AnalysisTarget target) {
     return target is Source && AnalysisEngine.isDartFileName(target.fullName);
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index 43565f3..c5bc076 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -8,8 +8,7 @@
 import 'dart:collection';
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisTask, AnalysisContextImpl, WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
diff --git a/pkg/analyzer/lib/src/task/general.dart b/pkg/analyzer/lib/src/task/general.dart
index 72f80fd..38d67df 100644
--- a/pkg/analyzer/lib/src/task/general.dart
+++ b/pkg/analyzer/lib/src/task/general.dart
@@ -4,7 +4,7 @@
 
 library analyzer.src.task.general;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/task/general.dart';
 import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/lib/src/task/html.dart b/pkg/analyzer/lib/src/task/html.dart
index 219e1ee..b6a771a 100644
--- a/pkg/analyzer/lib/src/task/html.dart
+++ b/pkg/analyzer/lib/src/task/html.dart
@@ -7,7 +7,7 @@
 import 'dart:collection';
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+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/scanner.dart';
@@ -313,7 +313,8 @@
       ];
       outputs[LINE_INFO] = new LineInfo(<int>[0]);
     } else {
-      HtmlParser parser = new HtmlParser(content, generateSpans: true);
+      HtmlParser parser = new HtmlParser(content,
+          generateSpans: true, lowercaseAttrName: false);
       parser.compatMode = 'quirks';
       Document document = parser.parse();
       //
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index 2236ca0..1134a58 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -89,26 +89,28 @@
  */
 abstract class ListTaskInputMixin<E> implements ListTaskInput<E> {
   @override
-  ListTaskInput /*<V>*/ toFlattenListOf(
+  ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
       ListResultDescriptor /*<V>*/ subListResult) {
-    return new ListToFlattenListTaskInput<E, dynamic /*V*/ >(
+    return new ListToFlattenListTaskInput<E, dynamic /*=V*/ >(
         this, subListResult.of as dynamic);
   }
 
-  ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper) {
-    return new ListToListTaskInput<E, dynamic /*V*/ >(this, mapper);
+  ListTaskInput /*<V>*/ toList /*<V>*/ (
+      UnaryFunction<E, dynamic /*<=V>*/ > mapper) {
+    return new ListToListTaskInput<E, dynamic /*=V*/ >(this, mapper);
   }
 
-  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
+  ListTaskInput /*<V>*/ toListOf /*<V>*/ (
+      ResultDescriptor /*<V>*/ valueResult) {
     return (this as ListTaskInput<AnalysisTarget>).toList(valueResult.of);
   }
 
-  MapTaskInput<E, dynamic /*V*/ > toMap(
-      UnaryFunction<E, dynamic /*<V>*/ > mapper) {
-    return new ListToMapTaskInput<E, dynamic /*V*/ >(this, mapper);
+  MapTaskInput<E, dynamic /*=V*/ > toMap /*<V>*/ (
+      UnaryFunction<E, dynamic /*<=V>*/ > mapper) {
+    return new ListToMapTaskInput<E, dynamic /*=V*/ >(this, mapper);
   }
 
-  MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+  MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
       ResultDescriptor /*<V>*/ valueResult) {
     return (this as ListTaskInputImpl<AnalysisTarget>).toMap(valueResult.of);
   }
@@ -277,11 +279,10 @@
  * A mixin-ready implementation of [MapTaskInput].
  */
 abstract class MapTaskInputMixin<K, V> implements MapTaskInput<K, V> {
-  TaskInput<List /*<E>*/ > toFlattenList(
-      BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper) {
+  TaskInput<List /*<E>*/ > toFlattenList /*<E>*/ (
+      BinaryFunction<K, dynamic /*element of V*/, dynamic /*<=E>*/ > mapper) {
     return new MapToFlattenListTaskInput<K, dynamic /*element of V*/,
-        dynamic /*E*/ >(
-        this as MapTaskInput<K, List /*<element of V>*/ >, mapper);
+        dynamic /*=E*/ >(this as MapTaskInput<K, List /*<element of V>*/ >, mapper);
   }
 }
 
@@ -440,22 +441,23 @@
       new ObjectToListTaskInputBuilder<E>(this);
 
   @override
-  ListTaskInput /*<V>*/ toFlattenListOf(
+  ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
       ListResultDescriptor /*<V>*/ subListResult) {
-    return new ListToFlattenListTaskInput<E, dynamic /*V*/ >(
+    return new ListToFlattenListTaskInput<E, dynamic /*=V*/ >(
         this, subListResult.of as dynamic);
   }
 
   @override
-  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult) {
-    return new ListToListTaskInput<E, dynamic /*V*/ >(
+  ListTaskInput /*<V>*/ toListOf /*<V>*/ (
+      ResultDescriptor /*<V>*/ valueResult) {
+    return new ListToListTaskInput<E, dynamic /*=V*/ >(
         this, valueResult.of as dynamic);
   }
 
   @override
-  MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+  MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
       ResultDescriptor /*<V>*/ valueResult) {
-    return new ListToMapTaskInput<AnalysisTarget, dynamic /*V*/ >(
+    return new ListToMapTaskInput<AnalysisTarget, dynamic /*=V*/ >(
         this as dynamic, valueResult.of);
   }
 }
@@ -694,7 +696,7 @@
 
 abstract class TaskInputImpl<V> implements TaskInput<V> {
   @override
-  ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value)) {
+  ListTaskInput /*<E>*/ mappedToList /*<E>*/ (List /*<E>*/ mapper(V value)) {
     return new ObjectToListTaskInput(this, mapper);
   }
 }
diff --git a/pkg/analyzer/lib/src/task/model.dart b/pkg/analyzer/lib/src/task/model.dart
index 50c05ee..8eaa838 100644
--- a/pkg/analyzer/lib/src/task/model.dart
+++ b/pkg/analyzer/lib/src/task/model.dart
@@ -4,7 +4,7 @@
 
 library analyzer.src.task.model;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/task/model.dart';
 
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 0596490..5b9acfe 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -4,9 +4,12 @@
 
 library analyzer.src.task.options;
 
+import 'dart:collection';
+
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -28,9 +31,9 @@
 final _OptionsProcessor _processor = new _OptionsProcessor();
 
 /// Configure this [context] based on configuration details specified in
-/// the given [options].
+/// the given [options].  If [options] is `null`, default values are applied.
 void configureContextOptions(
-        AnalysisContext context, Map<String, YamlNode> options) =>
+        AnalysisContext context, Map<String, Object> options) =>
     _processor.configure(context, options);
 
 /// `analyzer` analysis options constants.
@@ -47,6 +50,10 @@
   /// Ways to say `ignore`.
   static const List<String> ignoreSynonyms = const ['ignore', 'false'];
 
+  /// Valid error `severity`s.
+  static final List<String> severities =
+      ErrorSeverity.values.map((s) => s.name).toList();
+
   /// Ways to say `include`.
   static const List<String> includeSynonyms = const ['include', 'true'];
 
@@ -126,9 +133,20 @@
       new List.from(AnalyzerOptions.ignoreSynonyms)
         ..addAll(AnalyzerOptions.includeSynonyms));
 
-  bool recognizedErrorCode(String name) =>
-      ErrorCode.values.any((ErrorCode code) => code.name == name) ||
-          StaticInfo.names.contains(name);
+  /// Lazily populated set of error codes (hashed for speedy lookup).
+  static HashSet<String> _errorCodes;
+
+  /// Legal error code names.
+  static Set<String> get errorCodes {
+    if (_errorCodes == null) {
+      _errorCodes = new HashSet<String>();
+      // Engine codes.
+      _errorCodes.addAll(ErrorCode.values.map((ErrorCode code) => code.name));
+      // Strong-mode codes.
+      _errorCodes.addAll(StaticInfo.names);
+    }
+    return _errorCodes;
+  }
 
   @override
   void validate(ErrorReporter reporter, Map<String, YamlNode> options) {
@@ -143,7 +161,7 @@
       filters.nodes.forEach((k, v) {
         if (k is YamlScalar) {
           value = toUpperCase(k.value);
-          if (!recognizedErrorCode(value)) {
+          if (!errorCodes.contains(value)) {
             reporter.reportErrorForSpan(
                 AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
                 k.span,
@@ -371,9 +389,13 @@
 }
 
 class _OptionsProcessor {
-  void configure(AnalysisContext context, Map<String, YamlNode> options) {
+  static final Map<String, Object> defaults = {'analyzer': {}};
+
+  /// Configure [context] based on the given [options] (which can be `null`
+  /// to restore [defaults]).
+  void configure(AnalysisContext context, Map<String, Object> options) {
     if (options == null) {
-      return;
+      options = defaults;
     }
 
     var analyzer = options[AnalyzerOptions.analyzer];
@@ -387,33 +409,13 @@
 
     // Set filters.
     var filters = analyzer[AnalyzerOptions.errors];
-    setFilters(context, filters);
+    setProcessors(context, filters);
 
     // Process language options.
     var language = analyzer[AnalyzerOptions.language];
     setLanguageOptions(context, language);
   }
 
-  void setFilters(AnalysisContext context, Object codes) {
-    List<ErrorFilter> filters = <ErrorFilter>[];
-    // If codes are enumerated, collect them as filters; else leave filters
-    // empty to overwrite previous value.
-    if (codes is YamlMap) {
-      String value;
-      codes.nodes.forEach((k, v) {
-        if (k is YamlScalar && v is YamlScalar) {
-          value = toLowerCase(v.value);
-          if (AnalyzerOptions.ignoreSynonyms.contains(value)) {
-            // Case-insensitive.
-            String code = toUpperCase(k.value);
-            filters.add((AnalysisError error) => error.errorCode.name == code);
-          }
-        }
-      });
-    }
-    context.setConfigurationData(CONFIGURED_ERROR_FILTERS, filters);
-  }
-
   void setLanguageOption(
       AnalysisContext context, Object feature, Object value) {
     if (feature == AnalyzerOptions.enableSuperMixins) {
@@ -447,6 +449,11 @@
     }
   }
 
+  void setProcessors(AnalysisContext context, Object codes) {
+    ErrorConfig config = new ErrorConfig(codes);
+    context.setConfigurationData(CONFIGURED_ERROR_PROCESSORS, config.processors);
+  }
+
   void setStrongMode(AnalysisContext context, Object strongMode) {
     bool strong = strongMode is bool ? strongMode : false;
     if (context.analysisOptions.strongMode != strong) {
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index d557eb2..5004368 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -9,20 +9,21 @@
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:analyzer/src/generated/scanner.dart' show Token, TokenType;
+import 'package:analyzer/src/generated/type_system.dart';
 
 import 'info.dart';
-import 'rules.dart';
 
 /// Checks for overriding declarations of fields and methods. This is used to
 /// check overrides between classes and superclasses, interfaces, and mixin
 /// applications.
 class _OverrideChecker {
   bool _failure = false;
-  final TypeRules _rules;
+  final StrongTypeSystemImpl rules;
   final AnalysisErrorListener _reporter;
 
-  _OverrideChecker(this._rules, this._reporter);
+  _OverrideChecker(this.rules, this._reporter);
 
   void check(ClassDeclaration node) {
     if (node.element.type.isObject) return;
@@ -299,7 +300,7 @@
       AstNode node, AstNode errorLocation, bool isSubclass) {
     assert(!element.isStatic);
 
-    FunctionType subType = _rules.elementType(element);
+    FunctionType subType = _elementType(element);
     // TODO(vsm): Test for generic
     FunctionType baseType = _getMemberType(type, element);
     if (baseType == null) return false;
@@ -313,8 +314,8 @@
             errorLocation, element, type, subType, baseType));
       }
     }
-    if (!_rules.isAssignable(subType, baseType)) {
-      // See whether non-assignable cases fit one of our common patterns:
+    if (!rules.isSubtypeOf(subType, baseType)) {
+      // See whether non-subtype cases fit one of our common patterns:
       //
       // Common pattern 1: Inferable return type (on getters and methods)
       //   class A {
@@ -341,7 +342,8 @@
 
 /// Checks the body of functions and properties.
 class CodeChecker extends RecursiveAstVisitor {
-  final TypeRules rules;
+  final StrongTypeSystemImpl rules;
+  final TypeProvider typeProvider;
   final AnalysisErrorListener reporter;
   final _OverrideChecker _overrideChecker;
   final bool _hints;
@@ -354,7 +356,7 @@
     _overrideChecker._failure = false;
   }
 
-  CodeChecker(TypeRules rules, AnalysisErrorListener reporter,
+  CodeChecker(this.typeProvider, StrongTypeSystemImpl rules, AnalysisErrorListener reporter,
       {bool hints: false})
       : rules = rules,
         reporter = reporter,
@@ -403,7 +405,7 @@
   void visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
     var field = node.fieldName;
     var element = field.staticElement;
-    DartType staticType = rules.elementType(element);
+    DartType staticType = _elementType(element);
     checkAssignment(node.expression, staticType);
     node.visitChildren(this);
   }
@@ -413,8 +415,8 @@
     // Check that the expression is an Iterable.
     var expr = node.iterable;
     var iterableType = node.awaitKeyword != null
-        ? rules.provider.streamType
-        : rules.provider.iterableType;
+        ? typeProvider.streamType
+        : typeProvider.iterableType;
     var loopVariable = node.identifier != null
         ? node.identifier
         : node.loopVariable?.identifier;
@@ -463,7 +465,7 @@
 
   @override
   void visitListLiteral(ListLiteral node) {
-    var type = rules.provider.dynamicType;
+    var type = DynamicTypeImpl.instance;
     if (node.typeArguments != null) {
       var targs = node.typeArguments.arguments;
       if (targs.length > 0) type = targs[0].type;
@@ -481,8 +483,8 @@
 
   @override
   void visitMapLiteral(MapLiteral node) {
-    var ktype = rules.provider.dynamicType;
-    var vtype = rules.provider.dynamicType;
+    var ktype = DynamicTypeImpl.instance;
+    var vtype = DynamicTypeImpl.instance;
     if (node.typeArguments != null) {
       var targs = node.typeArguments.arguments;
       if (targs.length > 0) ktype = targs[0].type;
@@ -521,8 +523,8 @@
         // TODO(vsm): When can this happen?
         assert(element != null);
       }
-      DartType expectedType = rules.elementType(element);
-      if (expectedType == null) expectedType = rules.provider.dynamicType;
+      DartType expectedType = _elementType(element);
+      if (expectedType == null) expectedType = DynamicTypeImpl.instance;
       checkArgument(arg, expectedType);
     }
   }
@@ -538,19 +540,19 @@
 
   void checkFunctionApplication(
       Expression node, Expression f, ArgumentList list) {
-    if (rules.isDynamicCall(f)) {
+    if (_isDynamicCall(f)) {
       // If f is Function and this is a method invocation, we should have
       // gotten an analyzer error, so no need to issue another error.
       _recordDynamicInvoke(node, f);
     } else {
-      checkArgumentList(list, rules.getTypeAsCaller(f));
+      checkArgumentList(list, _getTypeAsCaller(f));
     }
   }
 
   @override
   visitMethodInvocation(MethodInvocation node) {
     var target = node.realTarget;
-    if (rules.isDynamicTarget(target) &&
+    if (_isDynamicTarget(target) &&
         !_isObjectMethod(node, node.methodName)) {
       _recordDynamicInvoke(node, target);
 
@@ -606,15 +608,15 @@
   void _checkReturnOrYield(Expression expression, AstNode node,
       {bool yieldStar: false}) {
     var body = node.getAncestor((n) => n is FunctionBody);
-    var type = rules.getExpectedReturnType(body, yieldStar: yieldStar);
+    var type = _getExpectedReturnType(body, yieldStar: yieldStar);
     if (type == null) {
       // We have a type mismatch: the async/async*/sync* modifier does
       // not match the return or yield type.  We should have already gotten an
       // analyzer error in this case.
       return;
     }
-    InterfaceType futureType = rules.provider.futureType;
-    DartType actualType = expression.staticType;
+    InterfaceType futureType = typeProvider.futureType;
+    DartType actualType = expression?.staticType;
     if (body.isAsynchronous &&
         !body.isGenerator &&
         actualType is InterfaceType &&
@@ -625,6 +627,59 @@
     if (expression != null) checkAssignment(expression, type);
   }
 
+  /// Gets the expected return type of the given function [body], either from
+  /// a normal return/yield, or from a yield*.
+  DartType _getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
+    FunctionType functionType;
+    var parent = body.parent;
+    if (parent is Declaration) {
+      functionType = _elementType(parent.element);
+    } else {
+      assert(parent is FunctionExpression);
+      functionType = parent.staticType ?? DynamicTypeImpl.instance;
+    }
+
+    var type = functionType.returnType;
+
+    InterfaceType expectedType = null;
+    if (body.isAsynchronous) {
+      if (body.isGenerator) {
+        // Stream<T> -> T
+        expectedType = typeProvider.streamType;
+      } else {
+        // Future<T> -> T
+        // TODO(vsm): Revisit with issue #228.
+        expectedType = typeProvider.futureType;
+      }
+    } else {
+      if (body.isGenerator) {
+        // Iterable<T> -> T
+        expectedType = typeProvider.iterableType;
+      } else {
+        // T -> T
+        return type;
+      }
+    }
+    if (yieldStar) {
+      if (type.isDynamic) {
+        // Ensure it's at least a Stream / Iterable.
+        return expectedType.substitute4([typeProvider.dynamicType]);
+      } else {
+        // Analyzer will provide a separate error if expected type
+        // is not compatible with type.
+        return type;
+      }
+    }
+    if (type.isDynamic) {
+      return type;
+    } else if (type is InterfaceType && type.element == expectedType.element) {
+      return type.typeArguments[0];
+    } else {
+      // Malformed type - fallback on analyzer error.
+      return null;
+    }
+  }
+
   @override
   void visitExpressionFunctionBody(ExpressionFunctionBody node) {
     _checkReturnOrYield(node.expression, node);
@@ -644,7 +699,7 @@
   }
 
   void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
-    if ((rules.isDynamicTarget(target) || field.staticElement == null) &&
+    if ((_isDynamicTarget(target) || field.staticElement == null) &&
         !_isObjectProperty(target, field)) {
       _recordDynamicInvoke(node, target);
     }
@@ -665,7 +720,7 @@
   void visitDefaultFormalParameter(DefaultFormalParameter node) {
     // Check that defaults have the proper subtype.
     var parameter = node.parameter;
-    var parameterType = rules.elementType(parameter.element);
+    var parameterType = _elementType(parameter.element);
     assert(parameterType != null);
     var defaultValue = node.defaultValue;
     if (defaultValue != null) {
@@ -680,11 +735,11 @@
     var element = node.element;
     var typeName = node.type;
     if (typeName != null) {
-      var type = rules.elementType(element);
+      var type = _elementType(element);
       var fieldElement =
           node.identifier.staticElement as FieldFormalParameterElement;
-      var fieldType = rules.elementType(fieldElement.field);
-      if (!rules.isSubTypeOf(type, fieldType)) {
+      var fieldType = _elementType(fieldElement.field);
+      if (!rules.isSubtypeOf(type, fieldType)) {
         var staticInfo =
             new InvalidParameterDeclaration(rules, node, fieldType);
         _recordMessage(staticInfo);
@@ -698,7 +753,7 @@
     var arguments = node.argumentList;
     var element = node.staticElement;
     if (element != null) {
-      var type = rules.elementType(node.staticElement);
+      var type = _elementType(node.staticElement);
       checkArgumentList(arguments, type);
     }
     node.visitChildren(this);
@@ -765,7 +820,7 @@
     if (op.isUserDefinableOperator ||
         op.type == TokenType.PLUS_PLUS ||
         op.type == TokenType.MINUS_MINUS) {
-      if (rules.isDynamicTarget(node.operand)) {
+      if (_isDynamicTarget(node.operand)) {
         _recordDynamicInvoke(node, node.operand);
       }
       // For ++ and --, even if it is not dynamic, we still need to check
@@ -778,7 +833,7 @@
   void visitBinaryExpression(BinaryExpression node) {
     var op = node.operator;
     if (op.isUserDefinableOperator) {
-      if (rules.isDynamicTarget(node.leftOperand)) {
+      if (_isDynamicTarget(node.leftOperand)) {
         // Dynamic invocation
         // TODO(vsm): Move this logic to the resolver?
         if (op.type != TokenType.EQ_EQ && op.type != TokenType.BANG_EQ) {
@@ -826,7 +881,7 @@
   @override
   void visitIndexExpression(IndexExpression node) {
     var target = node.realTarget;
-    if (rules.isDynamicTarget(target)) {
+    if (_isDynamicTarget(target)) {
       _recordDynamicInvoke(node, target);
     } else {
       var element = node.staticElement;
@@ -845,23 +900,94 @@
   }
 
   DartType getType(TypeName name) {
-    return (name == null) ? rules.provider.dynamicType : name.type;
+    return (name == null) ? DynamicTypeImpl.instance : name.type;
   }
 
   /// Analyzer checks boolean conversions, but we need to check too, because
   /// it uses the default assignability rules that allow `dynamic` and `Object`
   /// to be assigned to bool with no message.
   void checkBoolean(Expression expr) =>
-      checkAssignment(expr, rules.provider.boolType);
+      checkAssignment(expr, typeProvider.boolType);
 
   void checkAssignment(Expression expr, DartType type) {
     if (expr is ParenthesizedExpression) {
       checkAssignment(expr.expression, type);
     } else {
-      _recordMessage(rules.checkAssignment(expr, type));
+      _recordMessage(_checkAssignment(expr, type));
     }
   }
 
+  StaticInfo _checkAssignment(Expression expr, DartType toT) {
+    final fromT = expr.staticType ?? DynamicTypeImpl.instance;
+    final Coercion c = _coerceTo(fromT, toT);
+    if (c is Identity) return null;
+    if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
+    var reason = null;
+
+    var errors = <String>[];
+
+    var ok = _inferExpression(expr, toT, errors);
+    if (ok) return InferredType.create(rules, expr, toT);
+    reason = (errors.isNotEmpty) ? errors.first : null;
+
+    if (c is Cast) return DownCast.create(rules, expr, c, reason: reason);
+    assert(false);
+    return null;
+  }
+
+  /// Checks if we can perform downwards inference on [e] tp get type [t].
+  /// If it is not possible, this will add a message to [errors].
+  bool _inferExpression(Expression e, DartType t, List<String> errors) {
+    DartType staticType = e.staticType ?? DynamicTypeImpl.instance;
+    if (rules.isSubtypeOf(staticType, t)) {
+      return true;
+    }
+    errors.add("$e cannot be typed as $t");
+    return false;
+  }
+
+  // Produce a coercion which coerces something of type fromT
+  // to something of type toT.
+  // Returns the error coercion if the types cannot be coerced
+  // according to our current criteria.
+  Coercion _coerceTo(DartType fromT, DartType toT) {
+    // We can use anything as void
+    if (toT.isVoid) return Coercion.identity(toT);
+
+    // fromT <: toT, no coercion needed
+    if (rules.isSubtypeOf(fromT, toT)) return Coercion.identity(toT);
+
+    // TODO(vsm): We can get rid of the second clause if we disallow
+    // all sideways casts - see TODO below.
+    // -------
+    // Note: a function type is never assignable to a class per the Dart
+    // spec - even if it has a compatible call method.  We disallow as
+    // well for consistency.
+    if ((fromT is FunctionType && rules.getCallMethodType(toT) != null) ||
+        (toT is FunctionType && rules.getCallMethodType(fromT) != null)) {
+      return Coercion.error();
+    }
+
+    // Downcast if toT <: fromT
+    if (rules.isSubtypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
+
+    // TODO(vsm): Once we have generic methods, we should delete this
+    // workaround.  These sideways casts are always ones we warn about
+    // - i.e., we think they are likely to fail at runtime.
+    // -------
+    // Downcast if toT <===> fromT
+    // The intention here is to allow casts that are sideways in the restricted
+    // type system, but allowed in the regular dart type system, since these
+    // are likely to succeed.  The canonical example is List<dynamic> and
+    // Iterable<T> for some concrete T (e.g. Object).  These are unrelated
+    // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
+    if (fromT.isAssignableTo(toT)) {
+      return Coercion.cast(fromT, toT);
+    }
+
+    return Coercion.error();
+  }
+
   DartType _specializedBinaryReturnType(
       TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
     // This special cases binary return types as per 16.26 and 16.27 of the
@@ -877,14 +1003,14 @@
       case TokenType.STAR_EQ:
       case TokenType.TILDE_SLASH_EQ:
       case TokenType.PERCENT_EQ:
-        if (t1 == rules.provider.intType &&
-            t2 == rules.provider.intType) return t1;
-        if (t1 == rules.provider.doubleType &&
-            t2 == rules.provider.doubleType) return t1;
+        if (t1 == typeProvider.intType &&
+            t2 == typeProvider.intType) return t1;
+        if (t1 == typeProvider.doubleType &&
+            t2 == typeProvider.doubleType) return t1;
         // This particular combo is not spelled out in the spec, but all
         // implementations and analyzer seem to follow this.
-        if (t1 == rules.provider.doubleType &&
-            t2 == rules.provider.intType) return t1;
+        if (t1 == typeProvider.doubleType &&
+            t2 == typeProvider.intType) return t1;
     }
     return normalReturnType;
   }
@@ -912,11 +1038,11 @@
       var returnType = _specializedBinaryReturnType(
           op, lhsType, rhsType, functionType.returnType);
 
-      if (!rules.isSubTypeOf(returnType, lhsType)) {
-        final numType = rules.provider.numType;
+      if (!rules.isSubtypeOf(returnType, lhsType)) {
+        final numType = typeProvider.numType;
         // Try to fix up the numerical case if possible.
-        if (rules.isSubTypeOf(lhsType, numType) &&
-            rules.isSubTypeOf(lhsType, rhsType)) {
+        if (rules.isSubtypeOf(lhsType, numType) &&
+            rules.isSubtypeOf(lhsType, rhsType)) {
           // This is also slightly different from spec, but allows us to keep
           // compound operators in the int += num and num += dynamic cases.
           staticInfo = DownCast.create(
@@ -932,7 +1058,7 @@
       // Check the rhs type
       if (staticInfo is! CoercionInfo) {
         var paramType = paramTypes.first;
-        staticInfo = rules.checkAssignment(expr.rightHandSide, paramType);
+        staticInfo = _checkAssignment(expr.rightHandSide, paramType);
         _recordMessage(staticInfo);
       }
     }
@@ -940,13 +1066,13 @@
 
   bool _isObjectGetter(Expression target, SimpleIdentifier id) {
     PropertyAccessorElement element =
-        rules.provider.objectType.element.getGetter(id.name);
+        typeProvider.objectType.element.getGetter(id.name);
     return (element != null && !element.isStatic);
   }
 
   bool _isObjectMethod(Expression target, SimpleIdentifier id) {
     MethodElement element =
-        rules.provider.objectType.element.getMethod(id.name);
+        typeProvider.objectType.element.getMethod(id.name);
     return (element != null && !element.isStatic);
   }
 
@@ -955,7 +1081,7 @@
   }
 
   DartType _getStaticType(Expression expr) {
-    return expr.staticType ?? rules.provider.dynamicType;
+    return expr.staticType ?? DynamicTypeImpl.instance;
   }
 
   void _recordDynamicInvoke(AstNode node, AstNode target) {
@@ -986,6 +1112,58 @@
       CoercionInfo.set(info.node, info);
     }
   }
+
+  bool _isLibraryPrefix(Expression node) =>
+      node is SimpleIdentifier && node.staticElement is PrefixElement;
+
+  /// Returns `true` if the target expression is dynamic.
+  bool _isDynamicTarget(Expression node) {
+    if (node == null) return false;
+
+    if (_isLibraryPrefix(node)) return false;
+
+    // Null type happens when we have unknown identifiers, like a dart: import
+    // that doesn't resolve.
+    var type = node.staticType;
+    return type == null || type.isDynamic;
+  }
+
+  /// Returns `true` if the expression is a dynamic function call or method
+  /// invocation.
+  bool _isDynamicCall(Expression call) {
+    var ft = _getTypeAsCaller(call);
+    // TODO(leafp): This will currently return true if t is Function
+    // This is probably the most correct thing to do for now, since
+    // this code is also used by the back end.  Maybe revisit at some
+    // point?
+    if (ft == null) return true;
+    // Dynamic as the parameter type is treated as bottom.  A function with
+    // a dynamic parameter type requires a dynamic call in general.
+    // However, as an optimization, if we have an original definition, we know
+    // dynamic is reified as Object - in this case a regular call is fine.
+    if (call is SimpleIdentifier) {
+      var element = call.staticElement;
+      if (element is FunctionElement || element is MethodElement) {
+        // An original declaration.
+        return false;
+      }
+    }
+
+    return rules.anyParameterType(ft, (pt) => pt.isDynamic);
+  }
+
+  /// Given an expression, return its type assuming it is
+  /// in the caller position of a call (that is, accounting
+  /// for the possibility of a call method).  Returns null
+  /// if expression is not statically callable.
+  FunctionType _getTypeAsCaller(Expression applicand) {
+    var t = applicand.staticType ?? DynamicTypeImpl.instance;
+    if (t is InterfaceType) {
+      return rules.getCallMethodType(t);
+    }
+    if (t is FunctionType) return t;
+    return null;
+  }
 }
 
 // Return the field on type corresponding to member, or null if none
@@ -1054,6 +1232,14 @@
     if (baseMethod == null || baseMethod.isStatic) return null;
     return baseMethod.type;
   }
-  ;
   return f;
 }
+
+
+DartType _elementType(Element e) {
+  if (e == null) {
+    // Malformed code - just return dynamic.
+    return DynamicTypeImpl.instance;
+  }
+  return (e as dynamic).type;
+}
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index dbdc4e0..8b37962 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -11,15 +11,14 @@
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/error.dart';
-
-import 'rules.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 
 // A down cast due to a variable declaration to a ground type.  E.g.,
 //   T x = expr;
 // where T is ground.  We exclude non-ground types as these behave differently
 // compared to standard Dart.
 class AssignmentCast extends DownCast {
-  AssignmentCast(TypeRules rules, Expression expression, Cast cast)
+  AssignmentCast(TypeSystem rules, Expression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
   @override
@@ -56,13 +55,13 @@
 abstract class CoercionInfo extends StaticInfo {
   static const String _propertyName = 'dev_compiler.src.info.CoercionInfo';
 
-  final TypeRules rules;
+  final TypeSystem rules;
 
   final Expression node;
 
   CoercionInfo(this.rules, this.node);
 
-  DartType get baseType => rules.getStaticType(node);
+  DartType get baseType => node.staticType ?? DynamicTypeImpl.instance;
   DartType get convertedType;
 
   String get message;
@@ -84,7 +83,8 @@
 abstract class DownCast extends CoercionInfo {
   Cast _cast;
 
-  DownCast._internal(TypeRules rules, Expression expression, this._cast)
+  DownCast._internal(
+      TypeSystem rules, Expression expression, this._cast)
       : super(rules, expression) {
     assert(_cast.toType != baseType &&
         _cast.fromType == baseType &&
@@ -103,7 +103,8 @@
       'to cast to type {2}';
 
   // Factory to create correct DownCast variant.
-  static StaticInfo create(TypeRules rules, Expression expression, Cast cast,
+  static StaticInfo create(
+      StrongTypeSystemImpl rules, Expression expression, Cast cast,
       {String reason}) {
     final fromT = cast.fromType;
     final toT = cast.toType;
@@ -138,7 +139,7 @@
 
     // TODO(vsm): Change this to an assert when we have generic methods and
     // fix TypeRules._coerceTo to disallow implicit sideways casts.
-    if (!rules.isSubTypeOf(toT, fromT)) {
+    if (!rules.isSubtypeOf(toT, fromT)) {
       assert(toT.isSubtypeOf(fromT) || fromT.isAssignableTo(toT));
       return new DownCastComposite(rules, expression, cast);
     }
@@ -182,7 +183,8 @@
 // A down cast to a non-ground type.  These behave differently from standard
 // Dart and may be more likely to fail at runtime.
 class DownCastComposite extends DownCast {
-  DownCastComposite(TypeRules rules, Expression expression, Cast cast)
+  DownCastComposite(
+      TypeSystem rules, Expression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
   @override
@@ -194,7 +196,7 @@
 // A down cast to a non-ground type.  These behave differently from standard
 // Dart and may be more likely to fail at runtime.
 class DownCastImplicit extends DownCast {
-  DownCastImplicit(TypeRules rules, Expression expression, Cast cast)
+  DownCastImplicit(TypeSystem rules, Expression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
   @override
@@ -205,7 +207,7 @@
 
 // A down cast from dynamic to T.
 class DynamicCast extends DownCast {
-  DynamicCast(TypeRules rules, Expression expression, Cast cast)
+  DynamicCast(TypeSystem rules, Expression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
   @override
@@ -217,9 +219,9 @@
 class DynamicInvoke extends CoercionInfo {
   static const String _propertyName = 'dev_compiler.src.info.DynamicInvoke';
 
-  DynamicInvoke(TypeRules rules, Expression expression)
+  DynamicInvoke(TypeSystem rules, Expression expression)
       : super(rules, expression);
-  DartType get convertedType => rules.provider.dynamicType;
+  DartType get convertedType => DynamicTypeImpl.instance;
   String get message => '{0} requires dynamic invoke';
 
   @override
@@ -249,7 +251,7 @@
 
 // Standard / unspecialized inferred type
 class InferredType extends InferredTypeBase {
-  InferredType(TypeRules rules, Expression expression, DartType type)
+  InferredType(TypeSystem rules, Expression expression, DartType type)
       : super._internal(rules, expression, type);
 
   @override
@@ -257,7 +259,7 @@
 
   // Factory to create correct InferredType variant.
   static InferredTypeBase create(
-      TypeRules rules, Expression expression, DartType type) {
+      TypeSystem rules, Expression expression, DartType type) {
     // Specialized inference:
     if (expression is Literal) {
       return new InferredTypeLiteral(rules, expression, type);
@@ -274,7 +276,8 @@
 
 // An inferred type for a non-literal allocation site.
 class InferredTypeAllocation extends InferredTypeBase {
-  InferredTypeAllocation(TypeRules rules, Expression expression, DartType type)
+  InferredTypeAllocation(
+      TypeSystem rules, Expression expression, DartType type)
       : super._internal(rules, expression, type);
 
   @override
@@ -286,7 +289,8 @@
 abstract class InferredTypeBase extends CoercionInfo {
   final DartType _type;
 
-  InferredTypeBase._internal(TypeRules rules, Expression expression, this._type)
+  InferredTypeBase._internal(
+      TypeSystem rules, Expression expression, this._type)
       : super(rules, expression);
 
   @override List get arguments => [node, type];
@@ -299,7 +303,8 @@
 
 // An inferred type for a closure expression
 class InferredTypeClosure extends InferredTypeBase {
-  InferredTypeClosure(TypeRules rules, Expression expression, DartType type)
+  InferredTypeClosure(
+      TypeSystem rules, Expression expression, DartType type)
       : super._internal(rules, expression, type);
 
   @override
@@ -308,7 +313,8 @@
 
 // An inferred type for a literal expression.
 class InferredTypeLiteral extends InferredTypeBase {
-  InferredTypeLiteral(TypeRules rules, Expression expression, DartType type)
+  InferredTypeLiteral(
+      TypeSystem rules, Expression expression, DartType type)
       : super._internal(rules, expression, type);
 
   @override
@@ -385,8 +391,8 @@
 class InvalidParameterDeclaration extends StaticError {
   final DartType expectedType;
 
-  InvalidParameterDeclaration(
-      TypeRules rules, FormalParameter declaration, this.expectedType)
+  InvalidParameterDeclaration(TypeSystem rules,
+      FormalParameter declaration, this.expectedType)
       : super(declaration);
 
   @override List<Object> get arguments => [node, expectedType];
@@ -438,7 +444,7 @@
   final DartType expectedType;
 
   InvalidVariableDeclaration(
-      TypeRules rules, AstNode declaration, this.expectedType)
+      TypeSystem rules, AstNode declaration, this.expectedType)
       : super(declaration);
 
   @override List<Object> get arguments => [expectedType];
@@ -533,9 +539,10 @@
   final DartType expectedType;
   String reason = null;
 
-  StaticTypeError(TypeRules rules, Expression expression, this.expectedType,
+  StaticTypeError(
+      TypeSystem rules, Expression expression, this.expectedType,
       {this.reason})
-      : baseType = rules.getStaticType(expression),
+      : baseType = expression.staticType ?? DynamicTypeImpl.instance,
         super(expression);
 
   @override List<Object> get arguments => [node, baseType, expectedType];
@@ -558,7 +565,8 @@
 //
 // TODO(vsm,leafp): Remove this.
 class UninferredClosure extends DownCast {
-  UninferredClosure(TypeRules rules, FunctionExpression expression, Cast cast)
+  UninferredClosure(
+      TypeSystem rules, FunctionExpression expression, Cast cast)
       : super._internal(rules, expression, cast);
 
   @override
diff --git a/pkg/analyzer/lib/src/task/strong/rules.dart b/pkg/analyzer/lib/src/task/strong/rules.dart
deleted file mode 100644
index 909a6fb..0000000
--- a/pkg/analyzer/lib/src/task/strong/rules.dart
+++ /dev/null
@@ -1,524 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// TODO(jmesserly): this was ported from package:dev_compiler, and needs to be
-// refactored to fit into analyzer.
-library analyzer.src.task.strong.rules;
-
-import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-
-import 'info.dart';
-
-// TODO(jmesserly): this entire file needs to be removed in favor of TypeSystem.
-
-final _objectMap = new Expando('providerToObjectMap');
-Map<String, DartType> getObjectMemberMap(TypeProvider typeProvider) {
-  var map = _objectMap[typeProvider] as Map<String, DartType>;
-  if (map == null) {
-    map = <String, DartType>{};
-    _objectMap[typeProvider] = map;
-    var objectType = typeProvider.objectType;
-    var element = objectType.element;
-    // Only record methods (including getters) with no parameters.  As parameters are contravariant wrt
-    // type, using Object's version may be too strict.
-    // Add instance methods.
-    element.methods.where((method) => !method.isStatic).forEach((method) {
-      map[method.name] = method.type;
-    });
-    // Add getters.
-    element.accessors
-        .where((member) => !member.isStatic && member.isGetter)
-        .forEach((member) {
-      map[member.name] = member.type.returnType;
-    });
-  }
-  return map;
-}
-
-class TypeRules {
-  final TypeProvider provider;
-
-  /// Map of fields / properties / methods on Object.
-  final Map<String, DartType> objectMembers;
-
-  DownwardsInference inferrer;
-
-  TypeRules(TypeProvider provider)
-      : provider = provider,
-        objectMembers = getObjectMemberMap(provider) {
-    inferrer = new DownwardsInference(this);
-  }
-
-  /// Given a type t, if t is an interface type with a call method
-  /// defined, return the function type for the call method, otherwise
-  /// return null.
-  FunctionType getCallMethodType(DartType t) {
-    if (t is InterfaceType) {
-      return t.lookUpMethod("call", null)?.type;
-    }
-    return null;
-  }
-
-  /// Given an expression, return its type assuming it is
-  /// in the caller position of a call (that is, accounting
-  /// for the possibility of a call method).  Returns null
-  /// if expression is not statically callable.
-  FunctionType getTypeAsCaller(Expression applicand) {
-    var t = getStaticType(applicand);
-    if (t is InterfaceType) {
-      return getCallMethodType(t);
-    }
-    if (t is FunctionType) return t;
-    return null;
-  }
-
-  /// Gets the expected return type of the given function [body], either from
-  /// a normal return/yield, or from a yield*.
-  DartType getExpectedReturnType(FunctionBody body, {bool yieldStar: false}) {
-    FunctionType functionType;
-    var parent = body.parent;
-    if (parent is Declaration) {
-      functionType = elementType(parent.element);
-    } else {
-      assert(parent is FunctionExpression);
-      functionType = getStaticType(parent);
-    }
-
-    var type = functionType.returnType;
-
-    InterfaceType expectedType = null;
-    if (body.isAsynchronous) {
-      if (body.isGenerator) {
-        // Stream<T> -> T
-        expectedType = provider.streamType;
-      } else {
-        // Future<T> -> T
-        // TODO(vsm): Revisit with issue #228.
-        expectedType = provider.futureType;
-      }
-    } else {
-      if (body.isGenerator) {
-        // Iterable<T> -> T
-        expectedType = provider.iterableType;
-      } else {
-        // T -> T
-        return type;
-      }
-    }
-    if (yieldStar) {
-      if (type.isDynamic) {
-        // Ensure it's at least a Stream / Iterable.
-        return expectedType.substitute4([provider.dynamicType]);
-      } else {
-        // Analyzer will provide a separate error if expected type
-        // is not compatible with type.
-        return type;
-      }
-    }
-    if (type.isDynamic) {
-      return type;
-    } else if (type is InterfaceType && type.element == expectedType.element) {
-      return type.typeArguments[0];
-    } else {
-      // Malformed type - fallback on analyzer error.
-      return null;
-    }
-  }
-
-  DartType getStaticType(Expression expr) {
-    return expr.staticType ?? provider.dynamicType;
-  }
-
-  bool _isBottom(DartType t, {bool dynamicIsBottom: false}) {
-    if (t.isDynamic && dynamicIsBottom) return true;
-    // TODO(vsm): We need direct support for non-nullability in DartType.
-    // This should check on "true/nonnullable" Bottom
-    if (t.isBottom) return true;
-    return false;
-  }
-
-  bool _isTop(DartType t, {bool dynamicIsBottom: false}) {
-    if (t.isDynamic && !dynamicIsBottom) return true;
-    if (t.isObject) return true;
-    return false;
-  }
-
-  bool _anyParameterType(FunctionType ft, bool predicate(DartType t)) {
-    return ft.normalParameterTypes.any(predicate) ||
-        ft.optionalParameterTypes.any(predicate) ||
-        ft.namedParameterTypes.values.any(predicate);
-  }
-
-  // TODO(leafp): Revisit this.
-  bool isGroundType(DartType t) {
-    if (t is TypeParameterType) return false;
-    if (_isTop(t)) return true;
-
-    if (t is FunctionType) {
-      if (!_isTop(t.returnType) ||
-          _anyParameterType(t, (pt) => !_isBottom(pt, dynamicIsBottom: true))) {
-        return false;
-      } else {
-        return true;
-      }
-    }
-
-    if (t is InterfaceType) {
-      var typeArguments = t.typeArguments;
-      for (var typeArgument in typeArguments) {
-        if (!_isTop(typeArgument)) return false;
-      }
-      return true;
-    }
-
-    // We should not see any other type aside from malformed code.
-    return false;
-  }
-
-  /// Check that f1 is a subtype of f2. [ignoreReturn] is used in the DDC
-  /// checker to determine whether f1 would be a subtype of f2 if the return
-  /// type of f1 is set to match f2's return type.
-  // [fuzzyArrows] indicates whether or not the f1 and f2 should be
-  // treated as fuzzy arrow types (and hence dynamic parameters to f2 treated as
-  // bottom).
-  bool isFunctionSubTypeOf(FunctionType f1, FunctionType f2,
-      {bool fuzzyArrows: true, bool ignoreReturn: false}) {
-    final r1s = f1.normalParameterTypes;
-    final o1s = f1.optionalParameterTypes;
-    final n1s = f1.namedParameterTypes;
-    final r2s = f2.normalParameterTypes;
-    final o2s = f2.optionalParameterTypes;
-    final n2s = f2.namedParameterTypes;
-    final ret1 = ignoreReturn ? f2.returnType : f1.returnType;
-    final ret2 = f2.returnType;
-
-    // A -> B <: C -> D if C <: A and
-    // either D is void or B <: D
-    if (!ret2.isVoid && !isSubTypeOf(ret1, ret2)) return false;
-
-    // Reject if one has named and the other has optional
-    if (n1s.length > 0 && o2s.length > 0) return false;
-    if (n2s.length > 0 && o1s.length > 0) return false;
-
-    // f2 has named parameters
-    if (n2s.length > 0) {
-      // Check that every named parameter in f2 has a match in f1
-      for (String k2 in n2s.keys) {
-        if (!n1s.containsKey(k2)) return false;
-        if (!isSubTypeOf(n2s[k2], n1s[k2],
-            dynamicIsBottom: fuzzyArrows)) return false;
-      }
-    }
-    // If we get here, we either have no named parameters,
-    // or else the named parameters match and we have no optional
-    // parameters
-
-    // If f1 has more required parameters, reject
-    if (r1s.length > r2s.length) return false;
-
-    // If f2 has more required + optional parameters, reject
-    if (r2s.length + o2s.length > r1s.length + o1s.length) return false;
-
-    // The parameter lists must look like the following at this point
-    // where rrr is a region of required, and ooo is a region of optionals.
-    // f1: rrr ooo ooo ooo
-    // f2: rrr rrr ooo
-    int rr = r1s.length; // required in both
-    int or = r2s.length - r1s.length; // optional in f1, required in f2
-    int oo = o2s.length; // optional in both
-
-    for (int i = 0; i < rr; ++i) {
-      if (!isSubTypeOf(r2s[i], r1s[i],
-          dynamicIsBottom: fuzzyArrows)) return false;
-    }
-    for (int i = 0, j = rr; i < or; ++i, ++j) {
-      if (!isSubTypeOf(r2s[j], o1s[i],
-          dynamicIsBottom: fuzzyArrows)) return false;
-    }
-    for (int i = or, j = 0; i < oo; ++i, ++j) {
-      if (!isSubTypeOf(o2s[j], o1s[i],
-          dynamicIsBottom: fuzzyArrows)) return false;
-    }
-    return true;
-  }
-
-  bool _isInterfaceSubTypeOf(InterfaceType i1, InterfaceType i2) {
-    if (i1 == i2) return true;
-
-    if (i1.element == i2.element) {
-      List<DartType> tArgs1 = i1.typeArguments;
-      List<DartType> tArgs2 = i2.typeArguments;
-
-      // TODO(leafp): Verify that this is always true
-      // Do raw types get filled in?
-      assert(tArgs1.length == tArgs2.length);
-
-      for (int i = 0; i < tArgs1.length; i++) {
-        DartType t1 = tArgs1[i];
-        DartType t2 = tArgs2[i];
-        if (!isSubTypeOf(t1, t2)) return false;
-      }
-      return true;
-    }
-
-    if (i2.isDartCoreFunction) {
-      if (i1.element.getMethod("call") != null) return true;
-    }
-
-    if (i1 == provider.objectType) return false;
-
-    if (_isInterfaceSubTypeOf(i1.superclass, i2)) return true;
-
-    for (final parent in i1.interfaces) {
-      if (_isInterfaceSubTypeOf(parent, i2)) return true;
-    }
-
-    for (final parent in i1.mixins) {
-      if (_isInterfaceSubTypeOf(parent, i2)) return true;
-    }
-
-    return false;
-  }
-
-  bool isSubTypeOf(DartType t1, DartType t2, {bool dynamicIsBottom: false}) {
-    if (t1 == t2) return true;
-
-    // Trivially true.
-    if (_isTop(t2, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t1, dynamicIsBottom: dynamicIsBottom)) {
-      return true;
-    }
-
-    // Trivially false.
-    if (_isTop(t1, dynamicIsBottom: dynamicIsBottom) ||
-        _isBottom(t2, dynamicIsBottom: dynamicIsBottom)) {
-      return false;
-    }
-
-    // The null type is a subtype of any nullable type, which is all Dart types.
-    // TODO(vsm): Note, t1.isBottom still allows for null confusingly.
-    // _isBottom(t1) does not necessarily imply t1.isBottom if there are
-    // nonnullable types in the system.
-    if (t1.isBottom) {
-      return true;
-    }
-
-    // S <: T where S is a type variable
-    //  T is not dynamic or object (handled above)
-    //  S != T (handled above)
-    //  So only true if bound of S is S' and
-    //  S' <: T
-    if (t1 is TypeParameterType) {
-      DartType bound = t1.element.bound;
-      if (bound == null) return false;
-      return isSubTypeOf(bound, t2);
-    }
-
-    if (t2 is TypeParameterType) {
-      return false;
-    }
-
-    if (t1.isVoid || t2.isVoid) {
-      return false;
-    }
-
-    if (t2.isDartCoreFunction) {
-      if (t1 is FunctionType) return true;
-      if (t1.element is ClassElement) {
-        if ((t1.element as ClassElement).getMethod("call") != null) return true;
-      }
-    }
-
-    // "Traditional" name-based subtype check.
-    if (t1 is InterfaceType && t2 is InterfaceType) {
-      return _isInterfaceSubTypeOf(t1, t2);
-    }
-
-    if (t1 is! FunctionType && t2 is! FunctionType) return false;
-
-    if (t1 is InterfaceType && t2 is FunctionType) {
-      var callType = getCallMethodType(t1);
-      if (callType == null) return false;
-      return isFunctionSubTypeOf(callType, t2);
-    }
-
-    if (t1 is FunctionType && t2 is InterfaceType) {
-      return false;
-    }
-
-    // Functions
-    // Note: it appears under the hood all Dart functions map to a class /
-    // hidden type that:
-    //  (a) subtypes Object (an internal _FunctionImpl in the VM)
-    //  (b) implements Function
-    //  (c) provides standard Object members (hashCode, toString)
-    //  (d) contains private members (corresponding to _FunctionImpl?)
-    //  (e) provides a call method to handle the actual function invocation
-    //
-    // The standard Dart subtyping rules are structural in nature.  I.e.,
-    // bivariant on arguments and return type.
-    //
-    // The below tries for a more traditional subtyping rule:
-    // - covariant on return type
-    // - contravariant on parameters
-    // - 'sensible' (?) rules on optional and/or named params
-    // but doesn't properly mix with class subtyping.  I suspect Java 8 lambdas
-    // essentially map to dynamic (and rely on invokedynamic) due to similar
-    // issues.
-    return isFunctionSubTypeOf(t1 as FunctionType, t2 as FunctionType);
-  }
-
-  bool isAssignable(DartType t1, DartType t2) {
-    return isSubTypeOf(t1, t2);
-  }
-
-  // Produce a coercion which coerces something of type fromT
-  // to something of type toT.
-  // Returns the error coercion if the types cannot be coerced
-  // according to our current criteria.
-  Coercion _coerceTo(DartType fromT, DartType toT) {
-    // We can use anything as void
-    if (toT.isVoid) return Coercion.identity(toT);
-
-    // fromT <: toT, no coercion needed
-    if (isSubTypeOf(fromT, toT)) return Coercion.identity(toT);
-
-    // TODO(vsm): We can get rid of the second clause if we disallow
-    // all sideways casts - see TODO below.
-    // -------
-    // Note: a function type is never assignable to a class per the Dart
-    // spec - even if it has a compatible call method.  We disallow as
-    // well for consistency.
-    if ((fromT is FunctionType && getCallMethodType(toT) != null) ||
-        (toT is FunctionType && getCallMethodType(fromT) != null)) {
-      return Coercion.error();
-    }
-
-    // Downcast if toT <: fromT
-    if (isSubTypeOf(toT, fromT)) return Coercion.cast(fromT, toT);
-
-    // TODO(vsm): Once we have generic methods, we should delete this
-    // workaround.  These sideways casts are always ones we warn about
-    // - i.e., we think they are likely to fail at runtime.
-    // -------
-    // Downcast if toT <===> fromT
-    // The intention here is to allow casts that are sideways in the restricted
-    // type system, but allowed in the regular dart type system, since these
-    // are likely to succeed.  The canonical example is List<dynamic> and
-    // Iterable<T> for some concrete T (e.g. Object).  These are unrelated
-    // in the restricted system, but List<dynamic> <: Iterable<T> in dart.
-    if (fromT.isAssignableTo(toT)) {
-      return Coercion.cast(fromT, toT);
-    }
-
-    return Coercion.error();
-  }
-
-  StaticInfo checkAssignment(Expression expr, DartType toT) {
-    final fromT = getStaticType(expr);
-    final Coercion c = _coerceTo(fromT, toT);
-    if (c is Identity) return null;
-    if (c is CoercionError) return new StaticTypeError(this, expr, toT);
-    var reason = null;
-
-    var errors = <String>[];
-
-    var ok = inferrer.inferExpression(expr, toT, errors);
-    if (ok) return InferredType.create(this, expr, toT);
-    reason = (errors.isNotEmpty) ? errors.first : null;
-
-    if (c is Cast) return DownCast.create(this, expr, c, reason: reason);
-    assert(false);
-    return null;
-  }
-
-  DartType elementType(Element e) {
-    if (e == null) {
-      // Malformed code - just return dynamic.
-      return provider.dynamicType;
-    }
-    return (e as dynamic).type;
-  }
-
-  bool _isLibraryPrefix(Expression node) =>
-      node is SimpleIdentifier && node.staticElement is PrefixElement;
-
-  /// Returns `true` if the target expression is dynamic.
-  bool isDynamicTarget(Expression node) {
-    if (node == null) return false;
-
-    if (_isLibraryPrefix(node)) return false;
-
-    // Null type happens when we have unknown identifiers, like a dart: import
-    // that doesn't resolve.
-    var type = node.staticType;
-    return type == null || type.isDynamic;
-  }
-
-  /// Returns `true` if the expression is a dynamic function call or method
-  /// invocation.
-  bool isDynamicCall(Expression call) {
-    var ft = getTypeAsCaller(call);
-    // TODO(leafp): This will currently return true if t is Function
-    // This is probably the most correct thing to do for now, since
-    // this code is also used by the back end.  Maybe revisit at some
-    // point?
-    if (ft == null) return true;
-    // Dynamic as the parameter type is treated as bottom.  A function with
-    // a dynamic parameter type requires a dynamic call in general.
-    // However, as an optimization, if we have an original definition, we know
-    // dynamic is reified as Object - in this case a regular call is fine.
-    if (call is SimpleIdentifier) {
-      var element = call.staticElement;
-      if (element is FunctionElement || element is MethodElement) {
-        // An original declaration.
-        return false;
-      }
-    }
-
-    return _anyParameterType(ft, (pt) => pt.isDynamic);
-  }
-}
-
-class DownwardsInference {
-  final TypeRules rules;
-
-  DownwardsInference(this.rules);
-
-  /// Called for each list literal which gets inferred
-  void annotateListLiteral(ListLiteral e, List<DartType> targs) {}
-
-  /// Called for each map literal which gets inferred
-  void annotateMapLiteral(MapLiteral e, List<DartType> targs) {}
-
-  /// Called for each new/const which gets inferred
-  void annotateInstanceCreationExpression(
-      InstanceCreationExpression e, List<DartType> targs) {}
-
-  /// Called for cast from dynamic required for inference to succeed
-  void annotateCastFromDynamic(Expression e, DartType t) {}
-
-  /// Called for each function expression return type inferred
-  void annotateFunctionExpression(FunctionExpression e, DartType returnType) {}
-
-  /// Downward inference
-  bool inferExpression(Expression e, DartType t, List<String> errors) {
-    // Don't cast top level expressions, only sub-expressions
-    return _inferExpression(e, t, errors, cast: false);
-  }
-
-  /// Downward inference
-  bool _inferExpression(Expression e, DartType t, List<String> errors,
-      {cast: true}) {
-    if (rules.isSubTypeOf(rules.getStaticType(e), t)) return true;
-    if (cast && rules.getStaticType(e).isDynamic) {
-      annotateCastFromDynamic(e, t);
-      return true;
-    }
-    errors.add("$e cannot be typed as $t");
-    return false;
-  }
-}
diff --git a/pkg/analyzer/lib/src/util/absolute_path.dart b/pkg/analyzer/lib/src/util/absolute_path.dart
index f31935d..28f5732 100644
--- a/pkg/analyzer/lib/src/util/absolute_path.dart
+++ b/pkg/analyzer/lib/src/util/absolute_path.dart
@@ -4,18 +4,29 @@
 
 library analyzer.src.util.absolute_path;
 
-/// The class for manipulating absolute paths.
+/// The class for manipulating absolute, normalized paths.
 class AbsolutePathContext {
-  final String separator;
+  static const int _COLON = 0x3A;
+  static const int _LOWER_A = 0x61;
+  static const int _LOWER_Z = 0x7A;
+  static const int _UPPER_A = 0x41;
+  static const int _UPPER_Z = 0x5A;
 
+  final bool _isWindows;
+  String separator;
   int _separatorChar;
+  String _singlePeriodComponent;
+  String _doublePeriodComponent;
+  String _singlePeriodEnding;
+  String _doublePeriodEnding;
 
-  AbsolutePathContext(this.separator) {
-    if (separator.length != 1) {
-      throw new ArgumentError.value(
-          separator, 'separator', 'must be exactly one character long');
-    }
+  AbsolutePathContext(this._isWindows) {
+    separator = _isWindows ? r'\' : '/';
     _separatorChar = separator.codeUnitAt(0);
+    _singlePeriodComponent = separator + '.' + separator;
+    _doublePeriodComponent = separator + '..' + separator;
+    _singlePeriodEnding = separator + '.';
+    _doublePeriodEnding = separator + '..';
   }
 
   /// Append the given relative [suffix] to the given absolute [parent].
@@ -55,6 +66,14 @@
         : path.substring(0, lastIndex);
   }
 
+  /// Return `true` if the given [path] is valid.
+  ///
+  ///     context.isNormalized('/foo/bar');        // -> true
+  ///     context.isNormalized('/foo/bar/../baz'); // -> false
+  bool isValid(String path) {
+    return _isAbsolute(path) && _isNormalized(path);
+  }
+
   /// Return `true` if [child] is a path beneath [parent], and `false`
   /// otherwise. Both the [child] and [parent] paths must be absolute paths.
   ///
@@ -94,6 +113,47 @@
     return null;
   }
 
+  /// Return `true` if the given [path] is absolute.
+  ///
+  ///     _isAbsolute('/foo/bar');   // -> true
+  ///     _isAbsolute('/');          // -> true
+  ///     _isAbsolute('foo/bar');    // -> false
+  ///     _isAbsolute('C:\foo\bar'); // -> true
+  ///     _isAbsolute('C:\');        // -> true
+  ///     _isAbsolute('foo\bar');    // -> false
+  bool _isAbsolute(String path) {
+    if (_isWindows) {
+      return path.length >= 3 &&
+          _isAlphabetic(path.codeUnitAt(0)) &&
+          path.codeUnitAt(1) == _COLON &&
+          path.codeUnitAt(2) == _separatorChar;
+    } else {
+      return path.isNotEmpty && path.codeUnitAt(0) == _separatorChar;
+    }
+  }
+
+  /// Return `true` if the given absolute [path] is normalized.
+  ///
+  ///     _isNormalized('/foo/bar');        // -> true
+  ///     _isNormalized('/foo/..bar');      // -> true
+  ///     _isNormalized('/foo/bar..');      // -> true
+  ///     _isNormalized('/');               // -> true
+  ///     _isNormalized('/foo/bar/../baz'); // -> false
+  ///     _isNormalized('/foo/bar/..');     // -> false
+  bool _isNormalized(String path) {
+    return !path.contains(_singlePeriodComponent) &&
+        !path.contains(_doublePeriodComponent) &&
+        !path.endsWith(_singlePeriodEnding) &&
+        !path.endsWith(_doublePeriodEnding);
+  }
+
+  /// Returns whether [char] is the code for an ASCII letter (uppercase or
+  /// lowercase).
+  static bool _isAlphabetic(int char) {
+    return char >= _UPPER_A && char <= _UPPER_Z ||
+        char >= _LOWER_A && char <= _LOWER_Z;
+  }
+
   /// Return `true` if [str] starts with the given [prefix].
   ///
   /// The check is done from the end of [prefix], because absolute paths
diff --git a/pkg/analyzer/lib/src/util/asserts.dart b/pkg/analyzer/lib/src/util/asserts.dart
index a53e7e6..402f3bc 100644
--- a/pkg/analyzer/lib/src/util/asserts.dart
+++ b/pkg/analyzer/lib/src/util/asserts.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.asserts;
+library analyzer.src.util.asserts;
 
 /**
  * Ensures that the given [value] is not null.
diff --git a/pkg/analyzer/lib/src/util/lru_map.dart b/pkg/analyzer/lib/src/util/lru_map.dart
index 38ef8ff..716f7ab 100644
--- a/pkg/analyzer/lib/src/util/lru_map.dart
+++ b/pkg/analyzer/lib/src/util/lru_map.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.lru_cache;
+library analyzer.src.util.lru_cache;
 
 import 'dart:collection';
 
diff --git a/pkg/analyzer/lib/src/util/utilities_timing.dart b/pkg/analyzer/lib/src/util/utilities_timing.dart
index 7b8e122..ebc42b7 100644
--- a/pkg/analyzer/lib/src/util/utilities_timing.dart
+++ b/pkg/analyzer/lib/src/util/utilities_timing.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities.timing;
+library analyzer.src.util.utilities_timing;
 
 /**
  * A `CountedStopwatch` is a [Stopwatch] that counts the number of times the
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index c7d0c57..d0ec89d 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -337,8 +337,8 @@
    * values associated with this result will remain in the cache.
    */
   factory ListResultDescriptor(String name, List<E> defaultValue,
-      {ResultCachingPolicy<List<E>> cachingPolicy}) = ListResultDescriptorImpl<
-      E>;
+          {ResultCachingPolicy<List<E>> cachingPolicy}) =
+      ListResultDescriptorImpl<E>;
 
   @override
   ListTaskInput<E> of(AnalysisTarget target, {bool flushOnAccess: false});
@@ -355,35 +355,36 @@
    * Return a task input that can be used to compute a flatten list whose
    * elements are combined [subListResult]'s associated with those elements.
    */
-  ListTaskInput /*<V>*/ toFlattenListOf(
+  ListTaskInput /*<V>*/ toFlattenListOf /*<V>*/ (
       ListResultDescriptor /*<V>*/ subListResult);
 
   /**
    * Return a task input that can be used to compute a list whose elements are
    * the result of passing the elements of this input to the [mapper] function.
    */
-  ListTaskInput /*<V>*/ toList(UnaryFunction<E, dynamic /*<V>*/ > mapper);
+  ListTaskInput /*<V>*/ toList /*<V>*/ (
+      UnaryFunction<E, dynamic /*<=V>*/ > mapper);
 
   /**
    * Return a task input that can be used to compute a list whose elements are
    * [valueResult]'s associated with those elements.
    */
-  ListTaskInput /*<V>*/ toListOf(ResultDescriptor /*<V>*/ valueResult);
+  ListTaskInput /*<V>*/ toListOf /*<V>*/ (ResultDescriptor /*<V>*/ valueResult);
 
   /**
    * Return a task input that can be used to compute a map whose keys are the
    * elements of this input and whose values are the result of passing the
    * corresponding key to the [mapper] function.
    */
-  MapTaskInput<E, dynamic /*V*/ > toMap(
-      UnaryFunction<E, dynamic /*<V>*/ > mapper);
+  MapTaskInput<E, dynamic /*=V*/ > toMap /*<V>*/ (
+      UnaryFunction<E, dynamic /*=V*/ > mapper);
 
   /**
    * Return a task input that can be used to compute a map whose keys are the
    * elements of this input and whose values are the [valueResult]'s associated
    * with those elements.
    */
-  MapTaskInput<AnalysisTarget, dynamic /*V*/ > toMapOf(
+  MapTaskInput<AnalysisTarget, dynamic /*=V*/ > toMapOf /*<V>*/ (
       ResultDescriptor /*<V>*/ valueResult);
 }
 
@@ -399,8 +400,8 @@
    * the result of passing keys [K] and the corresponding elements of [V] to
    * the [mapper] function.
    */
-  TaskInput<List /*<E>*/ > toFlattenList(
-      BinaryFunction<K, dynamic /*element of V*/, dynamic /*<E>*/ > mapper);
+  TaskInput<List /*<E>*/ > toFlattenList /*<E>*/ (
+      BinaryFunction<K, dynamic /*element of V*/, dynamic /*=E*/ > mapper);
 }
 
 /**
@@ -570,7 +571,7 @@
    * Return a task input that can be used to compute a list whose elements are
    * the result of passing the result of this input to the [mapper] function.
    */
-  ListTaskInput /*<E>*/ mappedToList(List /*<E>*/ mapper(V value));
+  ListTaskInput /*<E>*/ mappedToList /*<E>*/ (List /*<E>*/ mapper(V value));
 }
 
 /**
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index a3c4b51..fab059e 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.26.3
+version: 0.27.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/cancelable_future_test.dart b/pkg/analyzer/test/cancelable_future_test.dart
index b28c0f9..24c84ae 100644
--- a/pkg/analyzer/test/cancelable_future_test.dart
+++ b/pkg/analyzer/test/cancelable_future_test.dart
@@ -2,7 +2,7 @@
 // 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 test.cancelable_future;
+library analyzer.test.cancelable_future_test;
 
 import 'dart:async';
 
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
index 706737f..16d8f45 100644
--- a/pkg/analyzer/test/enum_test.dart
+++ b/pkg/analyzer/test/enum_test.dart
@@ -2,14 +2,13 @@
 // 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 test.enums;
+library analyzer.test.enum_test;
 
 import 'dart:mirrors';
 
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as html;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -69,12 +68,6 @@
       ..check_explicit_values();
   }
 
-  void test_html_TokenType() {
-    new EnumTester<html.TokenType>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
-
   void test_INIT_STATE() {
     new EnumTester<INIT_STATE>()
       ..check_getters()
@@ -99,24 +92,12 @@
       ..check_explicit_values();
   }
 
-  void test_RetentionPriority() {
-    new EnumTester<RetentionPriority>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
-
   void test_SourceKind() {
     new EnumTester<SourceKind>()
       ..check_getters()
       ..check_explicit_values();
   }
 
-  void test_SourcePriority() {
-    new EnumTester<SourcePriority>()
-      ..check_getters()
-      ..check_explicit_values();
-  }
-
   void test_UriKind() {
     new EnumTester<UriKind>()
       ..check_getters()
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index d0d3e55..d00d2d4 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -2,7 +2,7 @@
 // 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 test.memory_file_system;
+library analyzer.test.file_system.memory_file_system_test;
 
 import 'dart:async';
 import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 852c7b2c..850bbcf 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -2,7 +2,7 @@
 // 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 test.physical_file_system;
+library analyzer.test.file_system.physical_resource_provider_test;
 
 import 'dart:async';
 import 'dart:core' hide Resource;
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index 8d91d24..53247c1 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -2,7 +2,7 @@
 // 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 test.resource_uri_resolver;
+library analyzer.test.file_system.resource_uri_resolver_test;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/file_system/test_all.dart b/pkg/analyzer/test/file_system/test_all.dart
index 303df09..1714c0b 100644
--- a/pkg/analyzer/test/file_system/test_all.dart
+++ b/pkg/analyzer/test/file_system/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.file_system;
+library analyzer.test.file_system.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index a9a7ab1..767f2c3 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.all_the_rest_test;
+library analyzer.test.generated.all_the_rest_test;
 
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/generated/ast.dart' hide ConstantEvaluator;
@@ -10,9 +10,7 @@
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
 import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -23,7 +21,6 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/testing/html_factory.dart';
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_collection.dart';
@@ -62,388 +59,9 @@
   runReflectiveTests(ExitDetectorTest2);
   runReflectiveTests(FileBasedSourceTest);
   runReflectiveTests(FileUriResolverTest);
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(HtmlParserTest);
-    runReflectiveTests(HtmlTagInfoBuilderTest);
-    runReflectiveTests(HtmlUnitBuilderTest);
-    runReflectiveTests(HtmlWarningCodeTest);
-  }
   runReflectiveTests(ReferenceFinderTest);
   runReflectiveTests(SDKLibrariesReaderTest);
-  runReflectiveTests(ToSourceVisitorTest);
   runReflectiveTests(UriKindTest);
-  runReflectiveTests(StringScannerTest);
-}
-
-abstract class AbstractScannerTest {
-  ht.AbstractScanner newScanner(String input);
-
-  void test_tokenize_attribute() {
-    _tokenize("<html bob=\"one two\">", <Object>[
-      ht.TokenType.LT,
-      "html",
-      "bob",
-      ht.TokenType.EQ,
-      "\"one two\"",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_comment() {
-    _tokenize("<!-- foo -->", <Object>["<!-- foo -->"]);
-  }
-
-  void test_tokenize_comment_incomplete() {
-    _tokenize("<!-- foo", <Object>["<!-- foo"]);
-  }
-
-  void test_tokenize_comment_with_gt() {
-    _tokenize("<!-- foo > -> -->", <Object>["<!-- foo > -> -->"]);
-  }
-
-  void test_tokenize_declaration() {
-    _tokenize("<! foo ><html>",
-        <Object>["<! foo >", ht.TokenType.LT, "html", ht.TokenType.GT]);
-  }
-
-  void test_tokenize_declaration_malformed() {
-    _tokenize("<! foo /><html>",
-        <Object>["<! foo />", ht.TokenType.LT, "html", ht.TokenType.GT]);
-  }
-
-  void test_tokenize_directive_incomplete() {
-    _tokenize2("<? \nfoo", <Object>["<? \nfoo"], <int>[0, 4]);
-  }
-
-  void test_tokenize_directive_xml() {
-    _tokenize("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>",
-        <Object>["<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"]);
-  }
-
-  void test_tokenize_directives_incomplete_with_newline() {
-    _tokenize2("<! \nfoo", <Object>["<! \nfoo"], <int>[0, 4]);
-  }
-
-  void test_tokenize_empty() {
-    _tokenize("", <Object>[]);
-  }
-
-  void test_tokenize_lt() {
-    _tokenize("<", <Object>[ht.TokenType.LT]);
-  }
-
-  void test_tokenize_script_embedded_tags() {
-    _tokenize("<script> <p></p></script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p></p>",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_embedded_tags2() {
-    _tokenize("<script> <p></p><</script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p></p><",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_embedded_tags3() {
-    _tokenize("<script> <p></p></</script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p></p></",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_partial() {
-    _tokenize("<script> <p> ",
-        <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> "]);
-  }
-
-  void test_tokenize_script_partial2() {
-    _tokenize("<script> <p> <",
-        <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> <"]);
-  }
-
-  void test_tokenize_script_partial3() {
-    _tokenize("<script> <p> </",
-        <Object>[ht.TokenType.LT, "script", ht.TokenType.GT, " <p> </"]);
-  }
-
-  void test_tokenize_script_ref() {
-    _tokenize("<script source='some.dart'/> <p>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      "source",
-      ht.TokenType.EQ,
-      "'some.dart'",
-      ht.TokenType.SLASH_GT,
-      " ",
-      ht.TokenType.LT,
-      "p",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_script_with_newline() {
-    _tokenize2("<script> <p>\n </script>", <Object>[
-      ht.TokenType.LT,
-      "script",
-      ht.TokenType.GT,
-      " <p>\n ",
-      ht.TokenType.LT_SLASH,
-      "script",
-      ht.TokenType.GT
-    ], <int>[
-      0,
-      13
-    ]);
-  }
-
-  void test_tokenize_spaces_and_newlines() {
-    ht.Token token = _tokenize2(
-        " < html \n bob = 'joe\n' >\n <\np > one \r\n two <!-- \rfoo --> </ p > </ html > ",
-        <Object>[
-      " ",
-      ht.TokenType.LT,
-      "html",
-      "bob",
-      ht.TokenType.EQ,
-      "'joe\n'",
-      ht.TokenType.GT,
-      "\n ",
-      ht.TokenType.LT,
-      "p",
-      ht.TokenType.GT,
-      " one \r\n two ",
-      "<!-- \rfoo -->",
-      " ",
-      ht.TokenType.LT_SLASH,
-      "p",
-      ht.TokenType.GT,
-      " ",
-      ht.TokenType.LT_SLASH,
-      "html",
-      ht.TokenType.GT,
-      " "
-    ],
-        <int>[
-      0,
-      9,
-      21,
-      25,
-      28,
-      38,
-      49
-    ]);
-    token = token.next;
-    expect(token.offset, 1);
-    token = token.next;
-    expect(token.offset, 3);
-    token = token.next;
-    expect(token.offset, 10);
-  }
-
-  void test_tokenize_string() {
-    _tokenize("<p bob=\"foo\">", <Object>[
-      ht.TokenType.LT,
-      "p",
-      "bob",
-      ht.TokenType.EQ,
-      "\"foo\"",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_string_partial() {
-    _tokenize("<p bob=\"foo",
-        <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "\"foo"]);
-  }
-
-  void test_tokenize_string_single_quote() {
-    _tokenize("<p bob='foo'>", <Object>[
-      ht.TokenType.LT,
-      "p",
-      "bob",
-      ht.TokenType.EQ,
-      "'foo'",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_string_single_quote_partial() {
-    _tokenize("<p bob='foo",
-        <Object>[ht.TokenType.LT, "p", "bob", ht.TokenType.EQ, "'foo"]);
-  }
-
-  void test_tokenize_tag_begin_end() {
-    _tokenize("<html></html>", <Object>[
-      ht.TokenType.LT,
-      "html",
-      ht.TokenType.GT,
-      ht.TokenType.LT_SLASH,
-      "html",
-      ht.TokenType.GT
-    ]);
-  }
-
-  void test_tokenize_tag_begin_only() {
-    ht.Token token =
-        _tokenize("<html>", <Object>[ht.TokenType.LT, "html", ht.TokenType.GT]);
-    token = token.next;
-    expect(token.offset, 1);
-  }
-
-  void test_tokenize_tag_incomplete_with_special_characters() {
-    _tokenize("<br-a_b", <Object>[ht.TokenType.LT, "br-a_b"]);
-  }
-
-  void test_tokenize_tag_self_contained() {
-    _tokenize("<br/>", <Object>[ht.TokenType.LT, "br", ht.TokenType.SLASH_GT]);
-  }
-
-  void test_tokenize_tags_wellformed() {
-    _tokenize("<html><p>one two</p></html>", <Object>[
-      ht.TokenType.LT,
-      "html",
-      ht.TokenType.GT,
-      ht.TokenType.LT,
-      "p",
-      ht.TokenType.GT,
-      "one two",
-      ht.TokenType.LT_SLASH,
-      "p",
-      ht.TokenType.GT,
-      ht.TokenType.LT_SLASH,
-      "html",
-      ht.TokenType.GT
-    ]);
-  }
-
-  /**
-   * Given an object representing an expected token, answer the expected token type.
-   *
-   * @param count the token count for error reporting
-   * @param expected the object representing an expected token
-   * @return the expected token type
-   */
-  ht.TokenType _getExpectedTokenType(int count, Object expected) {
-    if (expected is ht.TokenType) {
-      return expected;
-    }
-    if (expected is String) {
-      String lexeme = expected;
-      if (lexeme.startsWith("\"") || lexeme.startsWith("'")) {
-        return ht.TokenType.STRING;
-      }
-      if (lexeme.startsWith("<!--")) {
-        return ht.TokenType.COMMENT;
-      }
-      if (lexeme.startsWith("<!")) {
-        return ht.TokenType.DECLARATION;
-      }
-      if (lexeme.startsWith("<?")) {
-        return ht.TokenType.DIRECTIVE;
-      }
-      if (_isTag(lexeme)) {
-        return ht.TokenType.TAG;
-      }
-      return ht.TokenType.TEXT;
-    }
-    fail(
-        "Unknown expected token $count: ${expected != null ? expected.runtimeType : "null"}");
-    return null;
-  }
-
-  bool _isTag(String lexeme) {
-    if (lexeme.length == 0 || !Character.isLetter(lexeme.codeUnitAt(0))) {
-      return false;
-    }
-    for (int index = 1; index < lexeme.length; index++) {
-      int ch = lexeme.codeUnitAt(index);
-      if (!Character.isLetterOrDigit(ch) && ch != 0x2D && ch != 0x5F) {
-        return false;
-      }
-    }
-    return true;
-  }
-
-  ht.Token _tokenize(String input, List<Object> expectedTokens) =>
-      _tokenize2(input, expectedTokens, <int>[0]);
-  ht.Token _tokenize2(
-      String input, List<Object> expectedTokens, List<int> expectedLineStarts) {
-    ht.AbstractScanner scanner = newScanner(input);
-    scanner.passThroughElements = <String>["script"];
-    int count = 0;
-    ht.Token firstToken = scanner.tokenize();
-    ht.Token token = firstToken;
-    ht.Token previousToken = token.previous;
-    expect(previousToken.type == ht.TokenType.EOF, isTrue);
-    expect(previousToken.previous, same(previousToken));
-    expect(previousToken.offset, -1);
-    expect(previousToken.next, same(token));
-    expect(token.offset, 0);
-    while (token.type != ht.TokenType.EOF) {
-      if (count == expectedTokens.length) {
-        fail("too many parsed tokens");
-      }
-      Object expected = expectedTokens[count];
-      ht.TokenType expectedTokenType = _getExpectedTokenType(count, expected);
-      expect(token.type, same(expectedTokenType), reason: "token $count");
-      if (expectedTokenType.lexeme != null) {
-        expect(token.lexeme, expectedTokenType.lexeme, reason: "token $count");
-      } else {
-        expect(token.lexeme, expected, reason: "token $count");
-      }
-      count++;
-      previousToken = token;
-      token = token.next;
-      expect(token.previous, same(previousToken));
-    }
-    expect(token.next, same(token));
-    expect(token.offset, input.length);
-    if (count != expectedTokens.length) {
-      expect(false, isTrue, reason: "not enough parsed tokens");
-    }
-    List<int> lineStarts = scanner.lineStarts;
-    bool success = expectedLineStarts.length == lineStarts.length;
-    if (success) {
-      for (int i = 0; i < lineStarts.length; i++) {
-        if (expectedLineStarts[i] != lineStarts[i]) {
-          success = false;
-          break;
-        }
-      }
-    }
-    if (!success) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("Expected line starts ");
-      for (int start in expectedLineStarts) {
-        buffer.write(start);
-        buffer.write(", ");
-      }
-      buffer.write(" but found ");
-      for (int start in lineStarts) {
-        buffer.write(start);
-        buffer.write(", ");
-      }
-      fail(buffer.toString());
-    }
-    return firstToken;
-  }
 }
 
 /**
@@ -877,14 +495,13 @@
 }
 
 @reflectiveTest
-class ConstantFinderTest extends EngineTestCase {
+class ConstantFinderTest {
   AstNode _node;
   TypeProvider _typeProvider;
   AnalysisContext _context;
   Source _source;
 
   void setUp() {
-    super.setUp();
     _typeProvider = new TestTypeProvider();
     _context = new TestAnalysisContext_ConstantFinderTest();
     _source = new TestSource();
@@ -2039,7 +1656,7 @@
     expect(evaluationResult.value, isNotNull);
     DartObjectImpl value = evaluationResult.value;
     expect(value.type, typeProvider.symbolType);
-    expect(value.value, "a");
+    expect(value.toSymbolValue(), "a");
   }
 
   void test_instanceCreationExpression_withSupertypeParams_explicit() {
@@ -2150,7 +1767,7 @@
         (voidSymbol.element as VariableElementImpl).evaluationResult;
     DartObjectImpl value = voidSymbolResult.value;
     expect(value.type, typeProvider.symbolType);
-    expect(value.value, "void");
+    expect(value.toSymbolValue(), "void");
   }
 
   Map<String, DartObjectImpl> _assertFieldType(
@@ -2221,7 +1838,7 @@
     expect(result.value, isNotNull);
     DartObjectImpl value = result.value;
     expect(value.type, typeProvider.stringType);
-    return value.stringValue;
+    return value.toStringValue();
   }
 
   void _assertValidUnknown(EvaluationResultImpl result) {
@@ -2483,8 +2100,7 @@
 ''');
     DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
     expect(result.type, typeProvider.typeType);
-    ClassElement element = result.value;
-    expect(element.name, 'C');
+    expect(result.toTypeValue().name, 'C');
   }
 
   void test_visitSimpleIdentifier_dynamic() {
@@ -2493,7 +2109,7 @@
 ''');
     DartObjectImpl result = _evaluateConstant(compilationUnit, 'a', null);
     expect(result.type, typeProvider.typeType);
-    expect(result.value, typeProvider.dynamicType.element);
+    expect(result.toTypeValue(), typeProvider.dynamicType);
   }
 
   void test_visitSimpleIdentifier_inEnvironment() {
@@ -2932,51 +2548,51 @@
   }
 
   void test_getValue_bool_false() {
-    expect(_boolValue(false).value, false);
+    expect(_boolValue(false).toBoolValue(), false);
   }
 
   void test_getValue_bool_true() {
-    expect(_boolValue(true).value, true);
+    expect(_boolValue(true).toBoolValue(), true);
   }
 
   void test_getValue_bool_unknown() {
-    expect(_boolValue(null).value, isNull);
+    expect(_boolValue(null).toBoolValue(), isNull);
   }
 
   void test_getValue_double_known() {
     double value = 2.3;
-    expect(_doubleValue(value).value, value);
+    expect(_doubleValue(value).toDoubleValue(), value);
   }
 
   void test_getValue_double_unknown() {
-    expect(_doubleValue(null).value, isNull);
+    expect(_doubleValue(null).toDoubleValue(), isNull);
   }
 
   void test_getValue_int_known() {
     int value = 23;
-    expect(_intValue(value).value, value);
+    expect(_intValue(value).toIntValue(), value);
   }
 
   void test_getValue_int_unknown() {
-    expect(_intValue(null).value, isNull);
+    expect(_intValue(null).toIntValue(), isNull);
   }
 
   void test_getValue_list_empty() {
-    Object result = _listValue().value;
+    Object result = _listValue().toListValue();
     _assertInstanceOfObjectArray(result);
     List<Object> array = result as List<Object>;
     expect(array, hasLength(0));
   }
 
   void test_getValue_list_valid() {
-    Object result = _listValue([_intValue(23)]).value;
+    Object result = _listValue([_intValue(23)]).toListValue();
     _assertInstanceOfObjectArray(result);
     List<Object> array = result as List<Object>;
     expect(array, hasLength(1));
   }
 
   void test_getValue_map_empty() {
-    Object result = _mapValue().value;
+    Object result = _mapValue().toMapValue();
     EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
     Map map = result as Map;
     expect(map, hasLength(0));
@@ -2984,23 +2600,23 @@
 
   void test_getValue_map_valid() {
     Object result =
-        _mapValue([_stringValue("key"), _stringValue("value")]).value;
+        _mapValue([_stringValue("key"), _stringValue("value")]).toMapValue();
     EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
     Map map = result as Map;
     expect(map, hasLength(1));
   }
 
   void test_getValue_null() {
-    expect(_nullValue().value, isNull);
+    expect(_nullValue().isNull, isTrue);
   }
 
   void test_getValue_string_known() {
     String value = "twenty-three";
-    expect(_stringValue(value).value, value);
+    expect(_stringValue(value).toStringValue(), value);
   }
 
   void test_getValue_string_unknown() {
-    expect(_stringValue(null).value, isNull);
+    expect(_stringValue(null).toStringValue(), isNull);
   }
 
   void test_greaterThan_knownDouble_knownDouble_false() {
@@ -8402,473 +8018,6 @@
   }
 }
 
-@reflectiveTest
-class HtmlParserTest extends EngineTestCase {
-  /**
-   * The name of the 'script' tag in an HTML file.
-   */
-  static String _TAG_SCRIPT = "script";
-  void fail_parse_scriptWithComment() {
-    String scriptBody = r'''
-      /**
-       *     <editable-label bind-value="dartAsignableValue">
-       *     </editable-label>
-       */
-      class Foo {}''';
-    ht.HtmlUnit htmlUnit = parse("""
-<html>
-  <body>
-    <script type='application/dart'>
-$scriptBody
-    </script>
-  </body>
-</html>""");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t4("body", [
-          _t("script", _a(["type", "'application/dart'"]), scriptBody)
-        ])
-      ])
-    ]);
-  }
-
-  ht.HtmlUnit parse(String contents) {
-//    TestSource source =
-//        new TestSource.con1(FileUtilities2.createFile("/test.dart"), contents);
-    ht.AbstractScanner scanner = new ht.StringScanner(null, contents);
-    scanner.passThroughElements = <String>[_TAG_SCRIPT];
-    ht.Token token = scanner.tokenize();
-    LineInfo lineInfo = new LineInfo(scanner.lineStarts);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    ht.HtmlUnit unit =
-        new ht.HtmlParser(null, errorListener, options).parse(token, lineInfo);
-    errorListener.assertNoErrors();
-    return unit;
-  }
-
-  void test_parse_attribute() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsdf\""]), "")
-      ])
-    ]);
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.attributes[0].text, "sdfsdf");
-  }
-
-  void test_parse_attribute_EOF() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsdf\""]), "")
-      ])
-    ]);
-  }
-
-  void test_parse_attribute_EOF_missing_quote() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsd");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsd"]), "")
-      ])
-    ]);
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.attributes[0].text, "sdfsd");
-  }
-
-  void test_parse_attribute_extra_quote() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"\"></body></html>");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "\"sdfsdf\""]), "")
-      ])
-    ]);
-  }
-
-  void test_parse_attribute_single_quote() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo='sdfsdf'></body></html>");
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t("body", _a(["foo", "'sdfsdf'"]), "")
-      ])
-    ]);
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.attributes[0].text, "sdfsdf");
-  }
-
-  void test_parse_comment_embedded() {
-    ht.HtmlUnit htmlUnit = parse("<html <!-- comment -->></html>");
-    _validate(htmlUnit, [_t3("html", "")]);
-  }
-
-  void test_parse_comment_first() {
-    ht.HtmlUnit htmlUnit = parse("<!-- comment --><html></html>");
-    _validate(htmlUnit, [_t3("html", "")]);
-  }
-
-  void test_parse_comment_in_content() {
-    ht.HtmlUnit htmlUnit = parse("<html><!-- comment --></html>");
-    _validate(htmlUnit, [_t3("html", "<!-- comment -->")]);
-  }
-
-  void test_parse_content() {
-    ht.HtmlUnit htmlUnit = parse("<html>\n<p a=\"b\">blat \n </p>\n</html>");
-    // ht.XmlTagNode.getContent() does not include whitespace
-    // between '<' and '>' at this time
-    _validate(htmlUnit, [
-      _t3("html", "\n<pa=\"b\">blat \n </p>\n", [
-        _t("p", _a(["a", "\"b\""]), "blat \n ")
-      ])
-    ]);
-  }
-
-  void test_parse_content_none() {
-    ht.HtmlUnit htmlUnit = parse("<html><p/>blat<p/></html>");
-    _validate(htmlUnit, [
-      _t3("html", "<p/>blat<p/>", [_t3("p", ""), _t3("p", "")])
-    ]);
-  }
-
-  void test_parse_declaration() {
-    ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html>\n\n<html><p></p></html>");
-    _validate(htmlUnit, [
-      _t4("html", [_t3("p", "")])
-    ]);
-  }
-
-  void test_parse_directive() {
-    ht.HtmlUnit htmlUnit = parse("<?xml ?>\n\n<html><p></p></html>");
-    _validate(htmlUnit, [
-      _t4("html", [_t3("p", "")])
-    ]);
-  }
-
-  void test_parse_getAttribute() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.getAttribute("foo").text, "sdfsdf");
-    expect(bodyNode.getAttribute("bar"), null);
-    expect(bodyNode.getAttribute(null), null);
-  }
-
-  void test_parse_getAttributeText() {
-    ht.HtmlUnit htmlUnit = parse("<html><body foo=\"sdfsdf\"></body></html>");
-    ht.XmlTagNode htmlNode = htmlUnit.tagNodes[0];
-    ht.XmlTagNode bodyNode = htmlNode.tagNodes[0];
-    expect(bodyNode.getAttributeText("foo"), "sdfsdf");
-    expect(bodyNode.getAttributeText("bar"), null);
-    expect(bodyNode.getAttributeText(null), null);
-  }
-
-  void test_parse_headers() {
-    String code = r'''
-<html>
-  <body>
-    <h2>000</h2>
-    <div>
-      111
-    </div>
-  </body>
-</html>''';
-    ht.HtmlUnit htmlUnit = parse(code);
-    _validate(htmlUnit, [
-      _t4("html", [
-        _t4("body", [_t3("h2", "000"), _t4("div")])
-      ])
-    ]);
-  }
-
-  void test_parse_script() {
-    ht.HtmlUnit htmlUnit =
-        parse("<html><script >here is <p> some</script></html>");
-    _validate(htmlUnit, [
-      _t4("html", [_t3("script", "here is <p> some")])
-    ]);
-  }
-
-  void test_parse_self_closing() {
-    ht.HtmlUnit htmlUnit = parse("<html>foo<br>bar</html>");
-    _validate(htmlUnit, [
-      _t3("html", "foo<br>bar", [_t3("br", "")])
-    ]);
-  }
-
-  void test_parse_self_closing_declaration() {
-    ht.HtmlUnit htmlUnit = parse("<!DOCTYPE html><html>foo</html>");
-    _validate(htmlUnit, [_t3("html", "foo")]);
-  }
-
-  XmlValidator_Attributes _a(List<String> keyValuePairs) =>
-      new XmlValidator_Attributes(keyValuePairs);
-  XmlValidator_Tag _t(
-          String tag, XmlValidator_Attributes attributes, String content,
-          [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
-      new XmlValidator_Tag(tag, attributes, content, children);
-  XmlValidator_Tag _t3(String tag, String content,
-          [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
-      new XmlValidator_Tag(
-          tag, new XmlValidator_Attributes(), content, children);
-  XmlValidator_Tag _t4(String tag,
-          [List<XmlValidator_Tag> children = XmlValidator_Tag.EMPTY_LIST]) =>
-      new XmlValidator_Tag(tag, new XmlValidator_Attributes(), null, children);
-  void _validate(ht.HtmlUnit htmlUnit, List<XmlValidator_Tag> expectedTags) {
-    XmlValidator validator = new XmlValidator();
-    validator.expectTags(expectedTags);
-    htmlUnit.accept(validator);
-    validator.assertValid();
-  }
-}
-
-@reflectiveTest
-class HtmlTagInfoBuilderTest extends HtmlParserTest {
-  void test_builder() {
-    HtmlTagInfoBuilder builder = new HtmlTagInfoBuilder();
-    ht.HtmlUnit unit = parse(r'''
-<html>
-  <body>
-    <div id="x"></div>
-    <p class='c'></p>
-    <div class='c'></div>
-  </body>
-</html>''');
-    unit.accept(builder);
-    HtmlTagInfo info = builder.getTagInfo();
-    expect(info, isNotNull);
-    List<String> allTags = info.allTags;
-    expect(allTags, hasLength(4));
-    expect(info.getTagWithId("x"), "div");
-    List<String> tagsWithClass = info.getTagsWithClass("c");
-    expect(tagsWithClass, hasLength(2));
-  }
-}
-
-@reflectiveTest
-class HtmlUnitBuilderTest extends EngineTestCase {
-  InternalAnalysisContext _context;
-  @override
-  void setUp() {
-    _context = AnalysisContextFactory.contextWithCore();
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    super.tearDown();
-  }
-
-  void test_embedded_script() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart">foo=2;</script>
-</html>''');
-    _validate(element, [
-      _s(_l([_v("foo")]))
-    ]);
-  }
-
-  void test_embedded_script_no_content() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart"></script>
-</html>''');
-    _validate(element, [_s(_l())]);
-  }
-
-  void test_external_script() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart" src="other.dart"/>
-</html>''');
-    _validate(element, [_s2("other.dart")]);
-  }
-
-  void test_external_script_no_source() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart"/>
-</html>''');
-    _validate(element, [_s2(null)]);
-  }
-
-  void test_external_script_with_content() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart" src="other.dart">blat=2;</script>
-</html>''');
-    _validate(element, [_s2("other.dart")]);
-  }
-
-  void test_no_scripts() {
-    HtmlElementImpl element = _build(r'''
-<!DOCTYPE html>
-<html><p></p></html>''');
-    _validate(element, []);
-  }
-
-  void test_two_dart_scripts() {
-    HtmlElementImpl element = _build(r'''
-<html>
-<script type="application/dart">bar=2;</script>
-<script type="application/dart" src="other.dart"/>
-<script src="dart.js"/>
-</html>''');
-    _validate(element, [
-      _s(_l([_v("bar")])),
-      _s2("other.dart")
-    ]);
-  }
-
-  HtmlElementImpl _build(String contents) {
-    TestSource source = new TestSource(
-        FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
-    return builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
-  }
-
-  HtmlUnitBuilderTest_ExpectedLibrary _l(
-          [List<HtmlUnitBuilderTest_ExpectedVariable> expectedVariables =
-              HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]) =>
-      new HtmlUnitBuilderTest_ExpectedLibrary(this, expectedVariables);
-  _ExpectedScript _s(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) =>
-      new _ExpectedScript.con1(expectedLibrary);
-  _ExpectedScript _s2(String scriptSourcePath) =>
-      new _ExpectedScript.con2(scriptSourcePath);
-  HtmlUnitBuilderTest_ExpectedVariable _v(String varName) =>
-      new HtmlUnitBuilderTest_ExpectedVariable(varName);
-  void _validate(
-      HtmlElementImpl element, List<_ExpectedScript> expectedScripts) {
-    expect(element.context, same(_context));
-    List<HtmlScriptElement> scripts = element.scripts;
-    expect(scripts, isNotNull);
-    expect(scripts, hasLength(expectedScripts.length));
-    for (int scriptIndex = 0; scriptIndex < scripts.length; scriptIndex++) {
-      expectedScripts[scriptIndex]._validate(scriptIndex, scripts[scriptIndex]);
-    }
-  }
-}
-
-class HtmlUnitBuilderTest_ExpectedLibrary {
-  final HtmlUnitBuilderTest HtmlUnitBuilderTest_this;
-  final List<HtmlUnitBuilderTest_ExpectedVariable> _expectedVariables;
-  HtmlUnitBuilderTest_ExpectedLibrary(this.HtmlUnitBuilderTest_this,
-      [this._expectedVariables =
-          HtmlUnitBuilderTest_ExpectedVariable.EMPTY_LIST]);
-  void _validate(int scriptIndex, EmbeddedHtmlScriptElementImpl script) {
-    LibraryElement library = script.scriptLibrary;
-    expect(library, isNotNull, reason: "script $scriptIndex");
-    expect(script.context, same(HtmlUnitBuilderTest_this._context),
-        reason: "script $scriptIndex");
-    CompilationUnitElement unit = library.definingCompilationUnit;
-    expect(unit, isNotNull, reason: "script $scriptIndex");
-    List<TopLevelVariableElement> variables = unit.topLevelVariables;
-    expect(variables, hasLength(_expectedVariables.length));
-    for (int index = 0; index < variables.length; index++) {
-      _expectedVariables[index].validate(scriptIndex, variables[index]);
-    }
-    expect(library.enclosingElement, same(script),
-        reason: "script $scriptIndex");
-  }
-}
-
-class HtmlUnitBuilderTest_ExpectedVariable {
-  static const List<HtmlUnitBuilderTest_ExpectedVariable> EMPTY_LIST =
-      const <HtmlUnitBuilderTest_ExpectedVariable>[];
-  final String _expectedName;
-  HtmlUnitBuilderTest_ExpectedVariable(this._expectedName);
-  void validate(int scriptIndex, TopLevelVariableElement variable) {
-    expect(variable, isNotNull, reason: "script $scriptIndex");
-    expect(variable.name, _expectedName, reason: "script $scriptIndex");
-  }
-}
-
-/**
- * Instances of the class `HtmlWarningCodeTest` test the generation of HTML warning codes.
- */
-@reflectiveTest
-class HtmlWarningCodeTest extends EngineTestCase {
-  /**
-   * The analysis context used to resolve the HTML files.
-   */
-  InternalAnalysisContext _context;
-
-  /**
-   * The contents of the 'test.html' file.
-   */
-  String _contents;
-
-  /**
-   * The list of reported errors.
-   */
-  List<AnalysisError> _errors;
-  @override
-  void setUp() {
-    _context = AnalysisContextFactory.contextWithCore();
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    _contents = null;
-    _errors = null;
-    super.tearDown();
-  }
-
-  void test_invalidUri() {
-    _verify(
-        r'''
-<html>
-<script type='application/dart' src='ht:'/>
-</html>''',
-        [HtmlWarningCode.INVALID_URI]);
-    _assertErrorLocation2(_errors[0], "ht:");
-  }
-
-  void test_uriDoesNotExist() {
-    _verify(
-        r'''
-<html>
-<script type='application/dart' src='other.dart'/>
-</html>''',
-        [HtmlWarningCode.URI_DOES_NOT_EXIST]);
-    _assertErrorLocation2(_errors[0], "other.dart");
-  }
-
-  void _assertErrorLocation(
-      AnalysisError error, int expectedOffset, int expectedLength) {
-    expect(error.offset, expectedOffset, reason: error.toString());
-    expect(error.length, expectedLength, reason: error.toString());
-  }
-
-  void _assertErrorLocation2(AnalysisError error, String expectedString) {
-    _assertErrorLocation(
-        error, _contents.indexOf(expectedString), expectedString.length);
-  }
-
-  void _verify(String contents, List<ErrorCode> expectedErrorCodes) {
-    this._contents = contents;
-    TestSource source = new TestSource(
-        FileUtilities2.createFile("/test.html").getAbsolutePath(), contents);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    HtmlUnitBuilder builder = new HtmlUnitBuilder(_context);
-    builder.buildHtmlElement(source, _context.parseHtmlUnit(source));
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    errorListener.addAll2(builder.errorListener);
-    errorListener.assertErrorsWithCodes(expectedErrorCodes);
-    _errors = errorListener.errors;
-  }
-}
-
 /**
  * Instances of the class `MockDartSdk` implement a [DartSdk].
  */
@@ -8896,11 +8045,11 @@
 }
 
 @reflectiveTest
-class ReferenceFinderTest extends EngineTestCase {
+class ReferenceFinderTest {
   DirectedGraph<ConstantEvaluationTarget> _referenceGraph;
   VariableElement _head;
   Element _tail;
-  @override
+
   void setUp() {
     _referenceGraph = new DirectedGraph<ConstantEvaluationTarget>();
     _head = ElementFactory.topLevelVariableElement2("v1");
@@ -9062,14 +8211,6 @@
   }
 }
 
-@reflectiveTest
-class StringScannerTest extends AbstractScannerTest {
-  @override
-  ht.AbstractScanner newScanner(String input) {
-    return new ht.StringScanner(null, input);
-  }
-}
-
 class TestAnalysisContext_ConstantFinderTest extends TestAnalysisContext {
   bool invoked = false;
   TestAnalysisContext_ConstantFinderTest();
@@ -9080,61 +8221,6 @@
   }
 }
 
-/**
- * Instances of the class `ToSourceVisitorTest`
- */
-@reflectiveTest
-class ToSourceVisitorTest extends EngineTestCase {
-  void fail_visitHtmlScriptTagNode_attributes_content() {
-    _assertSource(
-        "<script type='application/dart'>f() {}</script>",
-        HtmlFactory.scriptTagWithContent(
-            "f() {}", [HtmlFactory.attribute("type", "'application/dart'")]));
-  }
-
-  void fail_visitHtmlScriptTagNode_noAttributes_content() {
-    _assertSource(
-        "<script>f() {}</script>", HtmlFactory.scriptTagWithContent("f() {}"));
-  }
-
-  void test_visitHtmlScriptTagNode_attributes_noContent() {
-    _assertSource(
-        "<script type='application/dart'/>",
-        HtmlFactory
-            .scriptTag([HtmlFactory.attribute("type", "'application/dart'")]));
-  }
-
-  void test_visitHtmlScriptTagNode_noAttributes_noContent() {
-    _assertSource("<script/>", HtmlFactory.scriptTag());
-  }
-
-  void test_visitHtmlUnit_empty() {
-    _assertSource("", new ht.HtmlUnit(null, new List<ht.XmlTagNode>(), null));
-  }
-
-  void test_visitHtmlUnit_nonEmpty() {
-    _assertSource(
-        "<html/>", new ht.HtmlUnit(null, [HtmlFactory.tagNode("html")], null));
-  }
-
-  void test_visitXmlAttributeNode() {
-    _assertSource("x=y", HtmlFactory.attribute("x", "y"));
-  }
-
-  /**
-   * Assert that a `ToSourceVisitor` will produce the expected source when visiting the given
-   * node.
-   *
-   * @param expectedSource the source string that the visitor is expected to produce
-   * @param node the AST node being visited to produce the actual source
-   */
-  void _assertSource(String expectedSource, ht.XmlNode node) {
-    PrintStringWriter writer = new PrintStringWriter();
-    node.accept(new ht.ToSourceVisitor(writer));
-    expect(writer.toString(), expectedSource);
-  }
-}
-
 @reflectiveTest
 class UriKindTest {
   void test_fromEncoding() {
@@ -9150,285 +8236,3 @@
     expect(UriKind.PACKAGE_URI.encoding, 0x70);
   }
 }
-
-/**
- * Instances of `XmlValidator` traverse an [XmlNode] structure and validate the node
- * hierarchy.
- */
-class XmlValidator extends ht.RecursiveXmlVisitor<Object> {
-  /**
-   * A list containing the errors found while traversing the AST structure.
-   */
-  List<String> _errors = new List<String>();
-  /**
-   * The tags to expect when visiting or `null` if tags should not be checked.
-   */
-  List<XmlValidator_Tag> _expectedTagsInOrderVisited;
-  /**
-   * The current index into the [expectedTagsInOrderVisited] array.
-   */
-  int _expectedTagsIndex = 0;
-  /**
-   * The key/value pairs to expect when visiting or `null` if attributes should not be
-   * checked.
-   */
-  List<String> _expectedAttributeKeyValuePairs;
-  /**
-   * The current index into the [expectedAttributeKeyValuePairs].
-   */
-  int _expectedAttributeIndex = 0;
-  /**
-   * Assert that no errors were found while traversing any of the AST structures that have been
-   * visited.
-   */
-  void assertValid() {
-    while (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
-      String expectedTag =
-          _expectedTagsInOrderVisited[_expectedTagsIndex++]._tag;
-      _errors.add("Expected to visit node with tag: $expectedTag");
-    }
-    if (!_errors.isEmpty) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write("Invalid XML structure:");
-      for (String message in _errors) {
-        buffer.writeln();
-        buffer.write("   ");
-        buffer.write(message);
-      }
-      fail(buffer.toString());
-    }
-  }
-
-  /**
-   * Set the tags to be expected when visiting
-   *
-   * @param expectedTags the expected tags
-   */
-  void expectTags(List<XmlValidator_Tag> expectedTags) {
-    // Flatten the hierarchy into expected order in which the tags are visited
-    List<XmlValidator_Tag> expected = new List<XmlValidator_Tag>();
-    _expectTags(expected, expectedTags);
-    this._expectedTagsInOrderVisited = expected;
-  }
-
-  @override
-  Object visitHtmlUnit(ht.HtmlUnit node) {
-    if (node.parent != null) {
-      _errors.add("HtmlUnit should not have a parent");
-    }
-    if (node.endToken.type != ht.TokenType.EOF) {
-      _errors.add("HtmlUnit end token should be of type EOF");
-    }
-    _validateNode(node);
-    return super.visitHtmlUnit(node);
-  }
-
-  @override
-  Object visitXmlAttributeNode(ht.XmlAttributeNode actual) {
-    if (actual.parent is! ht.XmlTagNode) {
-      _errors.add(
-          "Expected ${actual.runtimeType} to have parent of type XmlTagNode");
-    }
-    String actualName = actual.name;
-    String actualValue = actual.valueToken.lexeme;
-    if (_expectedAttributeIndex < _expectedAttributeKeyValuePairs.length) {
-      String expectedName =
-          _expectedAttributeKeyValuePairs[_expectedAttributeIndex];
-      if (expectedName != actualName) {
-        _errors.add(
-            "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have name: $expectedName but found: $actualName");
-      }
-      String expectedValue =
-          _expectedAttributeKeyValuePairs[_expectedAttributeIndex + 1];
-      if (expectedValue != actualValue) {
-        _errors.add(
-            "Expected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} to have value: $expectedValue but found: $actualValue");
-      }
-    } else {
-      _errors.add(
-          "Unexpected ${_expectedTagsIndex - 1} tag: ${_expectedTagsInOrderVisited[_expectedTagsIndex - 1]._tag} attribute ${_expectedAttributeIndex ~/ 2} name: $actualName value: $actualValue");
-    }
-    _expectedAttributeIndex += 2;
-    _validateNode(actual);
-    return super.visitXmlAttributeNode(actual);
-  }
-
-  @override
-  Object visitXmlTagNode(ht.XmlTagNode actual) {
-    if (!(actual.parent is ht.HtmlUnit || actual.parent is ht.XmlTagNode)) {
-      _errors.add(
-          "Expected ${actual.runtimeType} to have parent of type HtmlUnit or XmlTagNode");
-    }
-    if (_expectedTagsInOrderVisited != null) {
-      String actualTag = actual.tag;
-      if (_expectedTagsIndex < _expectedTagsInOrderVisited.length) {
-        XmlValidator_Tag expected =
-            _expectedTagsInOrderVisited[_expectedTagsIndex];
-        if (expected._tag != actualTag) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} but found: $actualTag");
-        }
-        _expectedAttributeKeyValuePairs = expected._attributes._keyValuePairs;
-        int expectedAttributeCount =
-            _expectedAttributeKeyValuePairs.length ~/ 2;
-        int actualAttributeCount = actual.attributes.length;
-        if (expectedAttributeCount != actualAttributeCount) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} to have $expectedAttributeCount attributes but found $actualAttributeCount");
-        }
-        _expectedAttributeIndex = 0;
-        _expectedTagsIndex++;
-        expect(actual.attributeEnd, isNotNull);
-        expect(actual.contentEnd, isNotNull);
-        int count = 0;
-        ht.Token token = actual.attributeEnd.next;
-        ht.Token lastToken = actual.contentEnd;
-        while (!identical(token, lastToken)) {
-          token = token.next;
-          if (++count > 1000) {
-            fail(
-                "Expected $_expectedTagsIndex tag: ${expected._tag} to have a sequence of tokens from getAttributeEnd() to getContentEnd()");
-            break;
-          }
-        }
-        if (actual.attributeEnd.type == ht.TokenType.GT) {
-          if (ht.HtmlParser.SELF_CLOSING.contains(actual.tag)) {
-            expect(actual.closingTag, isNull);
-          } else {
-            expect(actual.closingTag, isNotNull);
-          }
-        } else if (actual.attributeEnd.type == ht.TokenType.SLASH_GT) {
-          expect(actual.closingTag, isNull);
-        } else {
-          fail("Unexpected attribute end token: ${actual.attributeEnd.lexeme}");
-        }
-        if (expected._content != null && expected._content != actual.content) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} to have content '${expected._content}' but found '${actual.content}'");
-        }
-        if (expected._children.length != actual.tagNodes.length) {
-          _errors.add(
-              "Expected $_expectedTagsIndex tag: ${expected._tag} to have ${expected._children.length} children but found ${actual.tagNodes.length}");
-        } else {
-          for (int index = 0; index < expected._children.length; index++) {
-            String expectedChildTag = expected._children[index]._tag;
-            String actualChildTag = actual.tagNodes[index].tag;
-            if (expectedChildTag != actualChildTag) {
-              _errors.add(
-                  "Expected $_expectedTagsIndex tag: ${expected._tag} child $index to have tag: $expectedChildTag but found: $actualChildTag");
-            }
-          }
-        }
-      } else {
-        _errors.add("Visited unexpected tag: $actualTag");
-      }
-    }
-    _validateNode(actual);
-    return super.visitXmlTagNode(actual);
-  }
-
-  /**
-   * Append the specified tags to the array in depth first order
-   *
-   * @param expected the array to which the tags are added (not `null`)
-   * @param expectedTags the expected tags to be added (not `null`, contains no `null`s)
-   */
-  void _expectTags(
-      List<XmlValidator_Tag> expected, List<XmlValidator_Tag> expectedTags) {
-    for (XmlValidator_Tag tag in expectedTags) {
-      expected.add(tag);
-      _expectTags(expected, tag._children);
-    }
-  }
-
-  void _validateNode(ht.XmlNode node) {
-    if (node.beginToken == null) {
-      _errors.add("No begin token for ${node.runtimeType}");
-    }
-    if (node.endToken == null) {
-      _errors.add("No end token for ${node.runtimeType}");
-    }
-    int nodeStart = node.offset;
-    int nodeLength = node.length;
-    if (nodeStart < 0 || nodeLength < 0) {
-      _errors.add("No source info for ${node.runtimeType}");
-    }
-    ht.XmlNode parent = node.parent;
-    if (parent != null) {
-      int nodeEnd = nodeStart + nodeLength;
-      int parentStart = parent.offset;
-      int parentEnd = parentStart + parent.length;
-      if (nodeStart < parentStart) {
-        _errors.add(
-            "Invalid source start ($nodeStart) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
-      }
-      if (nodeEnd > parentEnd) {
-        _errors.add(
-            "Invalid source end ($nodeEnd) for ${node.runtimeType} inside ${parent.runtimeType} ($parentStart)");
-      }
-    }
-  }
-}
-
-class XmlValidator_Attributes {
-  final List<String> _keyValuePairs;
-  XmlValidator_Attributes([this._keyValuePairs = StringUtilities.EMPTY_ARRAY]);
-}
-
-class XmlValidator_Tag {
-  static const List<XmlValidator_Tag> EMPTY_LIST = const <XmlValidator_Tag>[];
-  final String _tag;
-  final XmlValidator_Attributes _attributes;
-  final String _content;
-  final List<XmlValidator_Tag> _children;
-  XmlValidator_Tag(this._tag, this._attributes, this._content,
-      [this._children = EMPTY_LIST]);
-}
-
-class _ExpectedScript {
-  String _expectedExternalScriptName;
-  HtmlUnitBuilderTest_ExpectedLibrary _expectedLibrary;
-  _ExpectedScript.con1(HtmlUnitBuilderTest_ExpectedLibrary expectedLibrary) {
-    this._expectedExternalScriptName = null;
-    this._expectedLibrary = expectedLibrary;
-  }
-  _ExpectedScript.con2(String expectedExternalScriptPath) {
-    this._expectedExternalScriptName = expectedExternalScriptPath;
-    this._expectedLibrary = null;
-  }
-  void _validate(int scriptIndex, HtmlScriptElement script) {
-    if (_expectedLibrary != null) {
-      _validateEmbedded(scriptIndex, script);
-    } else {
-      _validateExternal(scriptIndex, script);
-    }
-  }
-
-  void _validateEmbedded(int scriptIndex, HtmlScriptElement script) {
-    if (script is! EmbeddedHtmlScriptElementImpl) {
-      fail(
-          "Expected script $scriptIndex to be embedded, but found ${script != null ? script.runtimeType : "null"}");
-    }
-    EmbeddedHtmlScriptElementImpl embeddedScript =
-        script as EmbeddedHtmlScriptElementImpl;
-    _expectedLibrary._validate(scriptIndex, embeddedScript);
-  }
-
-  void _validateExternal(int scriptIndex, HtmlScriptElement script) {
-    if (script is! ExternalHtmlScriptElementImpl) {
-      fail(
-          "Expected script $scriptIndex to be external with src=$_expectedExternalScriptName but found ${script != null ? script.runtimeType : "null"}");
-    }
-    ExternalHtmlScriptElementImpl externalScript =
-        script as ExternalHtmlScriptElementImpl;
-    Source scriptSource = externalScript.scriptSource;
-    if (_expectedExternalScriptName == null) {
-      expect(scriptSource, isNull, reason: "script $scriptIndex");
-    } else {
-      expect(scriptSource, isNotNull, reason: "script $scriptIndex");
-      String actualExternalScriptName = scriptSource.shortName;
-      expect(actualExternalScriptName, _expectedExternalScriptName,
-          reason: "script $scriptIndex");
-    }
-  }
-}
diff --git a/pkg/analyzer/test/generated/ast_test.dart b/pkg/analyzer/test/generated/ast_test.dart
index 947ca7f..bff9b8b 100644
--- a/pkg/analyzer/test/generated/ast_test.dart
+++ b/pkg/analyzer/test/generated/ast_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.ast_test;
+library analyzer.test.generated.ast_test;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -1733,6 +1733,13 @@
         "assert (a);", AstFactory.assertStatement(AstFactory.identifier3("a")));
   }
 
+  void test_visitAssertStatement_withMessage() {
+    _assertSource(
+        "assert (a, b);",
+        AstFactory.assertStatement(
+            AstFactory.identifier3("a"), AstFactory.identifier3('b')));
+  }
+
   void test_visitAssignmentExpression() {
     _assertSource(
         "a = b",
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 154d448..a30a2cb 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.compile_time_error_code_test;
+library analyzer.test.generated.compile_time_error_code_test;
 
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
@@ -262,6 +262,19 @@
     verify([source]);
   }
 
+  void test_assertWithExtraArgument() {
+    // TODO(paulberry): once DEP 37 is turned on by default, this test should
+    // be removed.
+    Source source = addSource('''
+f(bool x) {
+  assert(x, 'foo');
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.EXTRA_ARGUMENT_TO_ASSERT]);
+    verify([source]);
+  }
+
   void test_async_used_as_identifier_in_annotation() {
     Source source = addSource('''
 const int async = 0;
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
index 4487fcb..9285b5f 100644
--- a/pkg/analyzer/test/generated/element_test.dart
+++ b/pkg/analyzer/test/generated/element_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.element_test;
+library analyzer.test.generated.element_test;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -32,7 +32,6 @@
   runReflectiveTests(CompilationUnitElementImplTest);
   runReflectiveTests(ElementLocationImplTest);
   runReflectiveTests(ElementImplTest);
-  runReflectiveTests(HtmlElementImplTest);
   runReflectiveTests(LibraryElementImplTest);
   runReflectiveTests(MethodElementImplTest);
   runReflectiveTests(MultiplyDefinedElementImplTest);
@@ -1889,18 +1888,6 @@
     expect(paramType.prunedTypedefs[0], same(f));
   }
 
-  void test_withTypeArguments() {
-    ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
-    MethodElementImpl methodElement =
-        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
-    enclosingClass.methods = <MethodElement>[methodElement];
-    FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
-    DartType expectedType = enclosingClass.typeParameters[0].type;
-    List<DartType> arguments = type.typeArguments;
-    expect(arguments, hasLength(1));
-    expect(arguments[0], expectedType);
-  }
-
   void test_substitute2_equal() {
     ClassElementImpl definingClass = ElementFactory.classElement2("C", ["E"]);
     TypeParameterType parameterType = definingClass.typeParameters[0].type;
@@ -1985,34 +1972,17 @@
     f.returnType = c.type.substitute4([f.type]);
     expect(f.type.toString(), '() \u2192 C<...>');
   }
-}
 
-@reflectiveTest
-class HtmlElementImplTest extends EngineTestCase {
-  void test_equals_differentSource() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "indexA.html");
-    HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "indexB.html");
-    expect(elementA == elementB, isFalse);
-  }
-
-  void test_equals_null() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
-    expect(element == null, isFalse);
-  }
-
-  void test_equals_sameSource() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl elementA = ElementFactory.htmlUnit(context, "index.html");
-    HtmlElementImpl elementB = ElementFactory.htmlUnit(context, "index.html");
-    expect(elementA == elementB, isTrue);
-  }
-
-  void test_equals_self() {
-    AnalysisContext context = createAnalysisContext();
-    HtmlElementImpl element = ElementFactory.htmlUnit(context, "index.html");
-    expect(element == element, isTrue);
+  void test_withTypeArguments() {
+    ClassElementImpl enclosingClass = ElementFactory.classElement2("C", ["E"]);
+    MethodElementImpl methodElement =
+        new MethodElementImpl.forNode(AstFactory.identifier3("m"));
+    enclosingClass.methods = <MethodElement>[methodElement];
+    FunctionTypeImpl type = new FunctionTypeImpl(methodElement);
+    DartType expectedType = enclosingClass.typeParameters[0].type;
+    List<DartType> arguments = type.typeArguments;
+    expect(arguments, hasLength(1));
+    expect(arguments[0], expectedType);
   }
 }
 
@@ -2025,6 +1995,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     _typeProvider = new TestTypeProvider();
   }
 
@@ -2493,241 +2464,6 @@
     expect(result.typeArguments[0], same(typeI));
   }
 
-  void test_getLeastUpperBound_directInterfaceCase() {
-    //
-    // class A
-    // class B implements A
-    // class C implements B
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeB];
-    expect(typeB.getLeastUpperBound(typeC), typeB);
-    expect(typeC.getLeastUpperBound(typeB), typeB);
-  }
-
-  void test_getLeastUpperBound_directSubclassCase() {
-    //
-    // class A
-    // class B extends A
-    // class C extends B
-    //
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    expect(typeB.getLeastUpperBound(typeC), typeB);
-    expect(typeC.getLeastUpperBound(typeB), typeB);
-  }
-
-  void test_getLeastUpperBound_functionType() {
-    DartType interfaceType = ElementFactory.classElement2("A").type;
-    FunctionTypeImpl functionType = new FunctionTypeImpl(
-        new FunctionElementImpl.forNode(AstFactory.identifier3("f")));
-    expect(interfaceType.getLeastUpperBound(functionType), isNull);
-  }
-
-  void test_getLeastUpperBound_mixinCase() {
-    //
-    // class A
-    // class B extends A
-    // class C extends A
-    // class D extends B with M, N, O, P
-    //
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classB = ElementFactory.classElement("B", classA.type);
-    ClassElement classC = ElementFactory.classElement("C", classA.type);
-    ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    classD.mixins = <InterfaceType>[
-      ElementFactory.classElement2("M").type,
-      ElementFactory.classElement2("N").type,
-      ElementFactory.classElement2("O").type,
-      ElementFactory.classElement2("P").type
-    ];
-    expect(typeD.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeD), typeA);
-  }
-
-  void test_getLeastUpperBound_null() {
-    DartType interfaceType = ElementFactory.classElement2("A").type;
-    expect(interfaceType.getLeastUpperBound(null), isNull);
-  }
-
-  void test_getLeastUpperBound_object() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    DartType typeObject = typeA.element.supertype;
-    // assert that object does not have a super type
-    expect((typeObject.element as ClassElement).supertype, isNull);
-    // assert that both A and B have the same super type of Object
-    expect(typeB.element.supertype, typeObject);
-    // finally, assert that the only least upper bound of A and B is Object
-    expect(typeA.getLeastUpperBound(typeB), typeObject);
-  }
-
-  void test_getLeastUpperBound_self() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    InterfaceType typeA = classA.type;
-    expect(typeA.getLeastUpperBound(typeA), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass1() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass2() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
-    ClassElementImpl classD = ElementFactory.classElement("D", classC.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeD = classD.type;
-    expect(typeB.getLeastUpperBound(typeD), typeA);
-    expect(typeD.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass3() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
-    ClassElementImpl classD = ElementFactory.classElement("D", classB.type);
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    expect(typeC.getLeastUpperBound(typeD), typeB);
-    expect(typeD.getLeastUpperBound(typeC), typeB);
-  }
-
-  void test_getLeastUpperBound_sharedSuperclass4() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classA2 = ElementFactory.classElement2("A2");
-    ClassElement classA3 = ElementFactory.classElement2("A3");
-    ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
-    ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
-    InterfaceType typeA = classA.type;
-    InterfaceType typeA2 = classA2.type;
-    InterfaceType typeA3 = classA3.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA2];
-    classC.interfaces = <InterfaceType>[typeA3];
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface1() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeA];
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface2() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    ClassElementImpl classD = ElementFactory.classElement2("D");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeA];
-    classD.interfaces = <InterfaceType>[typeC];
-    expect(typeB.getLeastUpperBound(typeD), typeA);
-    expect(typeD.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface3() {
-    ClassElementImpl classA = ElementFactory.classElement2("A");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    ClassElementImpl classD = ElementFactory.classElement2("D");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    InterfaceType typeD = classD.type;
-    classB.interfaces = <InterfaceType>[typeA];
-    classC.interfaces = <InterfaceType>[typeB];
-    classD.interfaces = <InterfaceType>[typeB];
-    expect(typeC.getLeastUpperBound(typeD), typeB);
-    expect(typeD.getLeastUpperBound(typeC), typeB);
-  }
-
-  void test_getLeastUpperBound_sharedSuperinterface4() {
-    ClassElement classA = ElementFactory.classElement2("A");
-    ClassElement classA2 = ElementFactory.classElement2("A2");
-    ClassElement classA3 = ElementFactory.classElement2("A3");
-    ClassElementImpl classB = ElementFactory.classElement2("B");
-    ClassElementImpl classC = ElementFactory.classElement2("C");
-    InterfaceType typeA = classA.type;
-    InterfaceType typeA2 = classA2.type;
-    InterfaceType typeA3 = classA3.type;
-    InterfaceType typeB = classB.type;
-    InterfaceType typeC = classC.type;
-    classB.interfaces = <InterfaceType>[typeA, typeA2];
-    classC.interfaces = <InterfaceType>[typeA, typeA3];
-    expect(typeB.getLeastUpperBound(typeC), typeA);
-    expect(typeC.getLeastUpperBound(typeB), typeA);
-  }
-
-  void test_getLeastUpperBound_twoComparables() {
-    InterfaceType string = _typeProvider.stringType;
-    InterfaceType num = _typeProvider.numType;
-    expect(string.getLeastUpperBound(num), _typeProvider.objectType);
-  }
-
-  void test_getLeastUpperBound_typeParameters_different() {
-    //
-    // class List<int>
-    // class List<double>
-    //
-    InterfaceType listType = _typeProvider.listType;
-    InterfaceType intType = _typeProvider.intType;
-    InterfaceType doubleType = _typeProvider.doubleType;
-    InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
-    InterfaceType listOfDoubleType =
-        listType.substitute4(<DartType>[doubleType]);
-    expect(listOfIntType.getLeastUpperBound(listOfDoubleType),
-        _typeProvider.objectType);
-  }
-
-  void test_getLeastUpperBound_typeParameters_same() {
-    //
-    // List<int>
-    // List<int>
-    //
-    InterfaceType listType = _typeProvider.listType;
-    InterfaceType intType = _typeProvider.intType;
-    InterfaceType listOfIntType = listType.substitute4(<DartType>[intType]);
-    expect(listOfIntType.getLeastUpperBound(listOfIntType), listOfIntType);
-  }
-
   void test_getMethod_implemented() {
     //
     // class A { m() {} }
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 42a5bfc..243f273 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -2,2483 +2,32 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.engine_test;
+library analyzer.test.generated.engine_test;
 
 import 'dart:async';
-import 'dart:collection';
 
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/embedder.dart';
-import 'package:analyzer/src/cancelable_future.dart';
-import 'package:analyzer/src/context/cache.dart' show CacheEntry;
+import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/html.dart' as ht;
 import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
-import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/scanner.dart';
-import 'package:analyzer/src/generated/sdk.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source_io.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
-import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:analyzer/src/generated/utilities_collection.dart';
-import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/string_source.dart';
-import 'package:analyzer/task/model.dart' as newContext;
+import 'package:analyzer/task/model.dart';
 import 'package:html/dom.dart' show Document;
-import 'package:path/path.dart' as pathos;
 import 'package:typed_mock/typed_mock.dart';
 import 'package:unittest/unittest.dart';
-import 'package:watcher/src/utils.dart';
 
 import '../reflective_tests.dart';
 import '../utils.dart';
-import 'all_the_rest_test.dart';
-import 'resolver_test.dart';
-import 'test_support.dart';
 
 main() {
   initializeTestEnvironment();
-  // Tests for the classes used in both old and new analysis implementations.
   runReflectiveTests(SourcesChangedEventTest);
-  // Tests for the classes used in the old analysis implementation.
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(AnalysisCacheTest);
-    runReflectiveTests(AnalysisContextImplTest);
-    runReflectiveTests(AnalysisTaskTest);
-    runReflectiveTests(AnalysisOptionsImplTest);
-    runReflectiveTests(DartEntryTest);
-    runReflectiveTests(GenerateDartErrorsTaskTest);
-    runReflectiveTests(GenerateDartHintsTaskTest);
-    runReflectiveTests(GenerateDartLintsTaskTest);
-    runReflectiveTests(GetContentTaskTest);
-    runReflectiveTests(HtmlEntryTest);
-    runReflectiveTests(IncrementalAnalysisCacheTest);
-    runReflectiveTests(IncrementalAnalysisTaskTest);
-    runReflectiveTests(LintGeneratorTest);
-    runReflectiveTests(ParseDartTaskTest);
-    runReflectiveTests(ParseHtmlTaskTest);
-    runReflectiveTests(PartitionManagerTest);
-    runReflectiveTests(ResolveDartLibraryTaskTest);
-    runReflectiveTests(ResolveDartUnitTaskTest);
-    runReflectiveTests(ResolveHtmlTaskTest);
-    runReflectiveTests(ScanDartTaskTest);
-    runReflectiveTests(SdkCachePartitionTest);
-    runReflectiveTests(UniversalCachePartitionTest);
-    runReflectiveTests(WorkManagerTest);
-  }
-}
-
-@reflectiveTest
-class AnalysisCacheTest extends EngineTestCase {
-  void test_creation() {
-    expect(new AnalysisCache(new List<CachePartition>(0)), isNotNull);
-  }
-
-  void test_get() {
-    AnalysisCache cache = new AnalysisCache(new List<CachePartition>(0));
-    TestSource source = new TestSource();
-    expect(cache.get(source), isNull);
-  }
-
-  void test_iterator() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    cache.put(source, entry);
-    MapIterator<Source, SourceEntry> iterator = cache.iterator();
-    expect(iterator.moveNext(), isTrue);
-    expect(iterator.key, same(source));
-    expect(iterator.value, same(entry));
-    expect(iterator.moveNext(), isFalse);
-  }
-
-  /**
-   * Verify that if multiple Source objects refer to the same file via
-   * different URIs, they are treated as separate entries in the cache.
-   */
-  void test_lookup_distinguishes_uris() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    JavaFile file = new JavaFile('baz.dart');
-    Source source1 = new FileBasedSource(file);
-    Source source2 =
-        new FileBasedSource(file, Uri.parse('package:foo/baz.dart'));
-    Source source3 =
-        new FileBasedSource(file, Uri.parse('package:bar/baz.dart'));
-    DartEntry entry1 = new DartEntry();
-    DartEntry entry2 = new DartEntry();
-    DartEntry entry3 = new DartEntry();
-    cache.put(source1, entry1);
-    cache.put(source2, entry2);
-    cache.put(source3, entry3);
-    expect(cache.get(source1), same(entry1));
-    expect(cache.get(source2), same(entry2));
-    expect(cache.get(source3), same(entry3));
-  }
-
-  void test_put_noFlush() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    cache.put(source, entry);
-    expect(cache.get(source), same(entry));
-  }
-
-  void test_setMaxCacheSize() {
-    CachePartition partition = new UniversalCachePartition(
-        null, 8, new _AnalysisCacheTest_test_setMaxCacheSize());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    int size = 6;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      DartEntry entry = new DartEntry();
-      entry.setValue(DartEntry.PARSED_UNIT, null);
-      cache.put(source, entry);
-      cache.accessedAst(source);
-    }
-    _assertNonFlushedCount(size, cache);
-    int newSize = size - 2;
-    partition.maxCacheSize = newSize;
-    _assertNonFlushedCount(newSize, cache);
-  }
-
-  void test_size() {
-    CachePartition partition =
-        new UniversalCachePartition(null, 8, new DefaultRetentionPolicy());
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[partition]);
-    int size = 4;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      cache.put(source, new DartEntry());
-      cache.accessedAst(source);
-    }
-    expect(cache.size(), size);
-  }
-
-  void _assertNonFlushedCount(int expectedCount, AnalysisCache cache) {
-    int nonFlushedCount = 0;
-    MapIterator<Source, SourceEntry> iterator = cache.iterator();
-    while (iterator.moveNext()) {
-      if (iterator.value.getState(DartEntry.PARSED_UNIT) !=
-          CacheState.FLUSHED) {
-        nonFlushedCount++;
-      }
-    }
-    expect(nonFlushedCount, expectedCount);
-  }
-}
-
-@reflectiveTest
-class AnalysisContextImplTest extends EngineTestCase {
-  /**
-   * An analysis context whose source factory is [sourceFactory].
-   */
-  AnalysisContextImpl _context;
-
-  /**
-   * The source factory associated with the analysis [context].
-   */
-  SourceFactory _sourceFactory;
-
-  void fail_performAnalysisTask_importedLibraryDelete_html() {
-    Source htmlSource = _addSource(
-        "/page.html",
-        r'''
-<html><body><script type="application/dart">
-  import 'libB.dart';
-  main() {print('hello dart');}
-</script></body></html>''');
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 1");
-    expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
-        isTrue,
-        reason: "htmlSource doesn't have errors");
-    // remove libB.dart content and analyze
-    _context.setContents(libBSource, null);
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-    expect(_hasAnalysisErrorWithErrorSeverity(errors), isTrue,
-        reason: "htmlSource has an error");
-  }
-
-  void fail_recordLibraryElements() {
-    fail("Implement this");
-  }
-
-  @override
-  void setUp() {
-    _context = new AnalysisContextImpl();
-    _sourceFactory = new SourceFactory([
-      new DartUriResolver(DirectoryBasedDartSdk.defaultSdk),
-      new FileUriResolver()
-    ]);
-    _context.sourceFactory = _sourceFactory;
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    options.cacheSize = 256;
-    _context.analysisOptions = options;
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    _sourceFactory = null;
-    super.tearDown();
-  }
-
-  Future test_applyChanges_add() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    _context.applyChanges(changeSet1);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    Source source2 =
-        new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedSource(source);
-    _context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change_content() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    _context.applyChanges(changeSet1);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    Source source2 =
-        new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedContent(source, 'library test;');
-    _context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_change_flush_element() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-int a = 0;''');
-    expect(_context.computeLibraryElement(librarySource), isNotNull);
-    _context.setContents(
-        librarySource,
-        r'''
-library lib;
-int aa = 0;''');
-    expect(_context.getLibraryElement(librarySource), isNull);
-  }
-
-  Future test_applyChanges_change_multiple() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", libraryContents1);
-    String partContents1 = r'''
-part of lib;
-int b = a;''';
-    Source partSource = _addSource("/part.dart", partContents1);
-    _context.computeLibraryElement(librarySource);
-    String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
-    _context.setContents(librarySource, libraryContents2);
-    String partContents2 = r'''
-part of lib;
-int b = aa;''';
-    _context.setContents(partSource, partContents2);
-    _context.computeLibraryElement(librarySource);
-    CompilationUnit libraryUnit =
-        _context.resolveCompilationUnit2(librarySource, librarySource);
-    CompilationUnit partUnit =
-        _context.resolveCompilationUnit2(partSource, librarySource);
-    TopLevelVariableDeclaration declaration =
-        libraryUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element declarationElement = declaration.variables.variables[0].element;
-    TopLevelVariableDeclaration use =
-        partUnit.declarations[0] as TopLevelVariableDeclaration;
-    Element useElement = (use.variables.variables[0].initializer
-        as SimpleIdentifier).staticElement;
-    expect((useElement as PropertyAccessorElement).variable,
-        same(declarationElement));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  Future test_applyChanges_change_range() {
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet1 = new ChangeSet();
-    changeSet1.addedSource(source);
-    _context.applyChanges(changeSet1);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    Source source2 =
-        new FileBasedSource(FileUtilities2.createFile("/test2.dart"));
-    ChangeSet changeSet2 = new ChangeSet();
-    changeSet2.addedSource(source2);
-    changeSet2.changedRange(source, 'library test;', 0, 0, 13);
-    _context.applyChanges(changeSet2);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(wereSourcesAdded: true, changedSources: [source]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_applyChanges_empty() {
-    _context.applyChanges(new ChangeSet());
-    expect(_context.performAnalysisTask().changeNotices, isNull);
-  }
-
-  void test_applyChanges_overriddenSource() {
-    // Note: addSource adds the source to the contentCache.
-    Source source = _addSource("/test.dart", "library test;");
-    _context.computeErrors(source);
-    while (!_context.sourcesNeedingProcessing.isEmpty) {
-      _context.performAnalysisTask();
-    }
-    // Adding the source as a changedSource should have no effect since
-    // it is already overridden in the content cache.
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(source);
-    _context.applyChanges(changeSet);
-    expect(_context.sourcesNeedingProcessing, hasLength(0));
-  }
-
-  Future test_applyChanges_remove() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libAContents = r'''
-library libA;
-import 'libB.dart';''';
-    Source libA = _addSource("/libA.dart", libAContents);
-    String libBContents = "library libB;";
-    Source libB = _addSource("/libB.dart", libBContents);
-    LibraryElement libAElement = _context.computeLibraryElement(libA);
-    List<LibraryElement> importedLibraries = libAElement.importedLibraries;
-    expect(importedLibraries, hasLength(2));
-    _context.computeErrors(libA);
-    _context.computeErrors(libB);
-    expect(_context.sourcesNeedingProcessing, hasLength(0));
-    _context.setContents(libB, null);
-    _removeSource(libB);
-    List<Source> sources = _context.sourcesNeedingProcessing;
-    expect(sources, hasLength(1));
-    expect(sources[0], same(libA));
-    libAElement = _context.computeLibraryElement(libA);
-    importedLibraries = libAElement.importedLibraries;
-    expect(importedLibraries, hasLength(1));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libA]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libB]);
-      listener.assertEvent(changedSources: [libB]);
-      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  /**
-   * IDEA uses the following scenario:
-   * 1. Add overlay.
-   * 2. Change overlay.
-   * 3. If the contents of the document buffer is the same as the contents
-   *    of the file, remove overlay.
-   * So, we need to try to use incremental resolution for removing overlays too.
-   */
-  void test_applyChanges_remove_incremental() {
-    MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
-    Source source = resourceProvider
-        .newFile(
-            '/test.dart',
-            r'''
-main() {
-  print(1);
-}
-''')
-        .createSource();
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _context.analysisOptions = new AnalysisOptionsImpl()..incremental = true;
-    _context.applyChanges(new ChangeSet()..addedSource(source));
-    // remember compilation unit
-    _analyzeAll_assertFinished();
-    CompilationUnit unit = _context.getResolvedCompilationUnit2(source, source);
-    // add overlay
-    _context.setContents(
-        source,
-        r'''
-main() {
-  print(12);
-}
-''');
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedCompilationUnit2(source, source), unit);
-    // remove overlay
-    _context.setContents(source, null);
-    _context.validateCacheConsistency();
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedCompilationUnit2(source, source), unit);
-  }
-
-  Future test_applyChanges_removeContainer() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libAContents = r'''
-library libA;
-import 'libB.dart';''';
-    Source libA = _addSource("/libA.dart", libAContents);
-    String libBContents = "library libB;";
-    Source libB = _addSource("/libB.dart", libBContents);
-    _context.computeLibraryElement(libA);
-    _context.computeErrors(libA);
-    _context.computeErrors(libB);
-    expect(_context.sourcesNeedingProcessing, hasLength(0));
-    ChangeSet changeSet = new ChangeSet();
-    SourceContainer removedContainer =
-        new _AnalysisContextImplTest_test_applyChanges_removeContainer(libB);
-    changeSet.removedContainer(removedContainer);
-    _context.applyChanges(changeSet);
-    List<Source> sources = _context.sourcesNeedingProcessing;
-    expect(sources, hasLength(1));
-    expect(sources[0], same(libA));
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libA]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [libB]);
-      listener.assertEvent(wereSourcesRemovedOrDeleted: true);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_computeDocumentationComment_block() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    String comment = "/** Comment */";
-    Source source = _addSource(
-        "/test.dart",
-        """
-$comment
-class A {}""");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    expect(_context.computeDocumentationComment(classElement), comment);
-  }
-
-  void test_computeDocumentationComment_none() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "class A {}");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    expect(_context.computeDocumentationComment(classElement), isNull);
-  }
-
-  void test_computeDocumentationComment_null() {
-    expect(_context.computeDocumentationComment(null), isNull);
-  }
-
-  void test_computeDocumentationComment_singleLine_multiple_EOL_n() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    String comment = "/// line 1\n/// line 2\n/// line 3\n";
-    Source source = _addSource("/test.dart", "${comment}class A {}");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    String actual = _context.computeDocumentationComment(classElement);
-    expect(actual, "/// line 1\n/// line 2\n/// line 3");
-  }
-
-  void test_computeDocumentationComment_singleLine_multiple_EOL_rn() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    String comment = "/// line 1\r\n/// line 2\r\n/// line 3\r\n";
-    Source source = _addSource("/test.dart", "${comment}class A {}");
-    LibraryElement libraryElement = _context.computeLibraryElement(source);
-    expect(libraryElement, isNotNull);
-    ClassElement classElement = libraryElement.definingCompilationUnit.types[0];
-    expect(libraryElement, isNotNull);
-    String actual = _context.computeDocumentationComment(classElement);
-    expect(actual, "/// line 1\n/// line 2\n/// line 3");
-  }
-
-  void test_computeErrors_dart_none() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    List<AnalysisError> errors = _context.computeErrors(source);
-    expect(errors, hasLength(0));
-  }
-
-  void test_computeErrors_dart_part() {
-    Source librarySource =
-        _addSource("/lib.dart", "library lib; part 'part.dart';");
-    Source partSource = _addSource("/part.dart", "part of 'lib';");
-    _context.parseCompilationUnit(librarySource);
-    List<AnalysisError> errors = _context.computeErrors(partSource);
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_computeErrors_dart_some() {
-    Source source = _addSource("/lib.dart", "library 'lib';");
-    List<AnalysisError> errors = _context.computeErrors(source);
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_computeErrors_html_none() {
-    Source source = _addSource("/test.html", "<html></html>");
-    List<AnalysisError> errors = _context.computeErrors(source);
-    expect(errors, hasLength(0));
-  }
-
-  void test_computeExportedLibraries_none() {
-    Source source = _addSource("/test.dart", "library test;");
-    expect(_context.computeExportedLibraries(source), hasLength(0));
-  }
-
-  void test_computeExportedLibraries_some() {
-    //    addSource("/lib1.dart", "library lib1;");
-    //    addSource("/lib2.dart", "library lib2;");
-    Source source = _addSource(
-        "/test.dart", "library test; export 'lib1.dart'; export 'lib2.dart';");
-    expect(_context.computeExportedLibraries(source), hasLength(2));
-  }
-
-  void test_computeHtmlElement_nonHtml() {
-    Source source = _addSource("/test.dart", "library test;");
-    expect(_context.computeHtmlElement(source), isNull);
-  }
-
-  void test_computeHtmlElement_valid() {
-    Source source = _addSource("/test.html", "<html></html>");
-    HtmlElement element = _context.computeHtmlElement(source);
-    expect(element, isNotNull);
-    expect(_context.computeHtmlElement(source), same(element));
-  }
-
-  void test_computeImportedLibraries_none() {
-    Source source = _addSource("/test.dart", "library test;");
-    expect(_context.computeImportedLibraries(source), hasLength(0));
-  }
-
-  void test_computeImportedLibraries_some() {
-    //    addSource("/lib1.dart", "library lib1;");
-    //    addSource("/lib2.dart", "library lib2;");
-    Source source = _addSource(
-        "/test.dart", "library test; import 'lib1.dart'; import 'lib2.dart';");
-    expect(_context.computeImportedLibraries(source), hasLength(2));
-  }
-
-  void test_computeKindOf_html() {
-    Source source = _addSource("/test.html", "");
-    expect(_context.computeKindOf(source), same(SourceKind.HTML));
-  }
-
-  void test_computeKindOf_library() {
-    Source source = _addSource("/test.dart", "library lib;");
-    expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_computeKindOf_libraryAndPart() {
-    Source source = _addSource("/test.dart", "library lib; part of lib;");
-    expect(_context.computeKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_computeKindOf_part() {
-    Source source = _addSource("/test.dart", "part of lib;");
-    expect(_context.computeKindOf(source), same(SourceKind.PART));
-  }
-
-  void test_computeLibraryElement() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "library lib;");
-    LibraryElement element = _context.computeLibraryElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_computeLineInfo_dart() {
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-library lib;
-
-main() {}''');
-    LineInfo info = _context.computeLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_computeLineInfo_html() {
-    Source source = _addSource(
-        "/test.html",
-        r'''
-<html>
-  <body>
-    <h1>A</h1>
-  </body>
-</html>''');
-    LineInfo info = _context.computeLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_computeResolvableCompilationUnit_dart_exception() {
-    TestSource source = _addSourceWithException("/test.dart");
-    try {
-      _context.computeResolvableCompilationUnit(source);
-      fail("Expected AnalysisException");
-    } on AnalysisException {
-      // Expected
-    }
-  }
-
-  void test_computeResolvableCompilationUnit_html_exception() {
-    Source source = _addSource("/lib.html", "<html></html>");
-    try {
-      _context.computeResolvableCompilationUnit(source);
-      fail("Expected AnalysisException");
-    } on AnalysisException {
-      // Expected
-    }
-  }
-
-  void test_computeResolvableCompilationUnit_valid() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit parsedUnit = _context.parseCompilationUnit(source);
-    expect(parsedUnit, isNotNull);
-    CompilationUnit resolvedUnit =
-        _context.computeResolvableCompilationUnit(source);
-    expect(resolvedUnit, isNotNull);
-    expect(resolvedUnit, same(parsedUnit));
-  }
-
-  Future test_computeResolvedCompilationUnitAsync() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    bool completed = false;
-    _context
-        .computeResolvedCompilationUnitAsync(source, source)
-        .then((CompilationUnit unit) {
-      expect(unit, isNotNull);
-      completed = true;
-    });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_afterDispose() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    // Dispose of the context.
-    _context.dispose();
-    // Any attempt to start an asynchronous computation should return a future
-    // which completes with error.
-    CancelableFuture<CompilationUnit> future =
-        _context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have completed with error');
-    }, onError: (error) {
-      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_cancel() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    CancelableFuture<CompilationUnit> future =
-        _context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have been canceled');
-    }, onError: (error) {
-      expect(error, new isInstanceOf<FutureCanceledError>());
-      completed = true;
-    });
-    expect(completed, isFalse);
-    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
-    future.cancel();
-    expect(_context.pendingFutureSources_forTesting, isEmpty);
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-      expect(_context.pendingFutureSources_forTesting, isEmpty);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_dispose() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    // Complete all pending analysis tasks and flush the AST so that it won't
-    // be available immediately.
-    _performPendingAnalysisTasks();
-    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
-    dartEntry.flushAstStructures();
-    CancelableFuture<CompilationUnit> future =
-        _context.computeResolvedCompilationUnitAsync(source, source);
-    bool completed = false;
-    future.then((CompilationUnit unit) {
-      fail('Future should have completed with error');
-    }, onError: (error) {
-      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    expect(completed, isFalse);
-    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
-    // Disposing of the context should cause all pending futures to complete
-    // with AnalysisNotScheduled, so that no clients are left hanging.
-    _context.dispose();
-    expect(_context.pendingFutureSources_forTesting, isEmpty);
-    return pumpEventQueue().then((_) {
-      expect(completed, isTrue);
-      expect(_context.pendingFutureSources_forTesting, isEmpty);
-    });
-  }
-
-  Future test_computeResolvedCompilationUnitAsync_unrelatedLibrary() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource("/lib.dart", "library lib;");
-    Source partSource = _addSource("/part.dart", "part of foo;");
-    bool completed = false;
-    _context
-        .computeResolvedCompilationUnitAsync(partSource, librarySource)
-        .then((_) {
-      fail('Expected resolution to fail');
-    }, onError: (e) {
-      expect(e, new isInstanceOf<AnalysisNotScheduledError>());
-      completed = true;
-    });
-    return pumpEventQueue().then((_) {
-      expect(completed, isFalse);
-      _performPendingAnalysisTasks();
-    }).then((_) => pumpEventQueue()).then((_) {
-      expect(completed, isTrue);
-    });
-  }
-
-  void test_configurationData() {
-    var key = new newContext.ResultDescriptor('test_key', '');
-    var testData = ['test', 'data'];
-    _context.setConfigurationData(key, testData);
-    expect(_context.getConfigurationData(key), testData);
-    var unusedKey = new newContext.ResultDescriptor('unused_key', '');
-    expect(_context.getConfigurationData(unusedKey), null);
-  }
-
-  void test_dispose() {
-    expect(_context.isDisposed, isFalse);
-    _context.dispose();
-    expect(_context.isDisposed, isTrue);
-  }
-
-  void test_exists_false() {
-    TestSource source = new TestSource();
-    source.exists2 = false;
-    expect(_context.exists(source), isFalse);
-  }
-
-  void test_exists_null() {
-    expect(_context.exists(null), isFalse);
-  }
-
-  void test_exists_overridden() {
-    Source source = new TestSource();
-    _context.setContents(source, "");
-    expect(_context.exists(source), isTrue);
-  }
-
-  void test_exists_true() {
-    expect(_context.exists(new AnalysisContextImplTest_Source_exists_true()),
-        isTrue);
-  }
-
-  void test_getAnalysisOptions() {
-    expect(_context.analysisOptions, isNotNull);
-  }
-
-  void test_getContents_fromSource() {
-    String content = "library lib;";
-    TimestampedData<String> contents =
-        _context.getContents(new TestSource('/test.dart', content));
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getContents_overridden() {
-    String content = "library lib;";
-    Source source = new TestSource();
-    _context.setContents(source, content);
-    TimestampedData<String> contents = _context.getContents(source);
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getContents_unoverridden() {
-    String content = "library lib;";
-    Source source = new TestSource('/test.dart', content);
-    _context.setContents(source, "part of lib;");
-    _context.setContents(source, null);
-    TimestampedData<String> contents = _context.getContents(source);
-    expect(contents.data.toString(), content);
-  }
-
-  void test_getDeclaredVariables() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    expect(_context.declaredVariables, isNotNull);
-  }
-
-  void test_getElement() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    LibraryElement core =
-        _context.computeLibraryElement(_sourceFactory.forUri("dart:core"));
-    expect(core, isNotNull);
-    ClassElement classObject =
-        _findClass(core.definingCompilationUnit, "Object");
-    expect(classObject, isNotNull);
-    ElementLocation location = classObject.location;
-    Element element = _context.getElement(location);
-    expect(element, same(classObject));
-  }
-
-  void test_getElement_constructor_named() {
-    Source source = _addSource(
-        "/lib.dart",
-        r'''
-class A {
-  A.named() {}
-}''');
-    _analyzeAll_assertFinished();
-    LibraryElement library = _context.computeLibraryElement(source);
-    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
-    ConstructorElement constructor = classA.constructors[0];
-    ElementLocation location = constructor.location;
-    Element element = _context.getElement(location);
-    expect(element, same(constructor));
-  }
-
-  void test_getElement_constructor_unnamed() {
-    Source source = _addSource(
-        "/lib.dart",
-        r'''
-class A {
-  A() {}
-}''');
-    _analyzeAll_assertFinished();
-    LibraryElement library = _context.computeLibraryElement(source);
-    ClassElement classA = _findClass(library.definingCompilationUnit, "A");
-    ConstructorElement constructor = classA.constructors[0];
-    ElementLocation location = constructor.location;
-    Element element = _context.getElement(location);
-    expect(element, same(constructor));
-  }
-
-  void test_getElement_enum() {
-    Source source = _addSource('/test.dart', 'enum MyEnum {A, B, C}');
-    _analyzeAll_assertFinished();
-    LibraryElement library = _context.computeLibraryElement(source);
-    ClassElement myEnum = library.definingCompilationUnit.getEnum('MyEnum');
-    ElementLocation location = myEnum.location;
-    Element element = _context.getElement(location);
-    expect(element, same(myEnum));
-  }
-
-  void test_getErrors_dart_none() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-  }
-
-  void test_getErrors_dart_some() {
-    Source source = _addSource("/lib.dart", "library 'lib';");
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(1));
-  }
-
-  void test_getErrors_html_none() {
-    Source source = _addSource("/test.html", "<html></html>");
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-  }
-
-  void test_getErrors_html_some() {
-    Source source = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-</head></html>''');
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(0));
-    _context.computeErrors(source);
-    errors = _context.getErrors(source).errors;
-    expect(errors, hasLength(1));
-  }
-
-  void test_getHtmlElement_dart() {
-    Source source = _addSource("/test.dart", "");
-    expect(_context.getHtmlElement(source), isNull);
-    expect(_context.computeHtmlElement(source), isNull);
-    expect(_context.getHtmlElement(source), isNull);
-  }
-
-  void test_getHtmlElement_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    HtmlElement element = _context.getHtmlElement(source);
-    expect(element, isNull);
-    _context.computeHtmlElement(source);
-    element = _context.getHtmlElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_getHtmlFilesReferencing_html() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = _addSource("/test.dart", "library lib;");
-    Source secondHtmlSource = _addSource("/test.html", "<html></html>");
-    _context.computeLibraryElement(librarySource);
-    List<Source> result = _context.getHtmlFilesReferencing(secondHtmlSource);
-    expect(result, hasLength(0));
-    _context.parseHtmlUnit(htmlSource);
-    result = _context.getHtmlFilesReferencing(secondHtmlSource);
-    expect(result, hasLength(0));
-  }
-
-  void test_getHtmlFilesReferencing_library() {
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = _addSource("/test.dart", "library lib;");
-    List<Source> result = _context.getHtmlFilesReferencing(librarySource);
-    expect(result, hasLength(0));
-    _context.parseHtmlUnit(htmlSource);
-    result = _context.getHtmlFilesReferencing(librarySource);
-    expect(result, hasLength(1));
-    expect(result[0], htmlSource);
-  }
-
-  void test_getHtmlFilesReferencing_part() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource =
-        _addSource("/test.dart", "library lib; part 'part.dart';");
-    Source partSource = _addSource("/part.dart", "part of lib;");
-    _context.computeLibraryElement(librarySource);
-    List<Source> result = _context.getHtmlFilesReferencing(partSource);
-    expect(result, hasLength(0));
-    _context.parseHtmlUnit(htmlSource);
-    result = _context.getHtmlFilesReferencing(partSource);
-    expect(result, hasLength(1));
-    expect(result[0], htmlSource);
-  }
-
-  void test_getHtmlSources() {
-    List<Source> sources = _context.htmlSources;
-    expect(sources, hasLength(0));
-    Source source = _addSource("/test.html", "");
-    _context.computeKindOf(source);
-    sources = _context.htmlSources;
-    expect(sources, hasLength(1));
-    expect(sources[0], source);
-  }
-
-  void test_getKindOf_html() {
-    Source source = _addSource("/test.html", "");
-    expect(_context.getKindOf(source), same(SourceKind.HTML));
-  }
-
-  void test_getKindOf_library() {
-    Source source = _addSource("/test.dart", "library lib;");
-    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
-    _context.computeKindOf(source);
-    expect(_context.getKindOf(source), same(SourceKind.LIBRARY));
-  }
-
-  void test_getKindOf_part() {
-    Source source = _addSource("/test.dart", "part of lib;");
-    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
-    _context.computeKindOf(source);
-    expect(_context.getKindOf(source), same(SourceKind.PART));
-  }
-
-  void test_getKindOf_unknown() {
-    Source source = _addSource("/test.css", "");
-    expect(_context.getKindOf(source), same(SourceKind.UNKNOWN));
-  }
-
-  void test_getLaunchableClientLibrarySources() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    List<Source> sources = _context.launchableClientLibrarySources;
-    expect(sources, hasLength(0));
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-import 'dart:html';
-main() {}''');
-    _context.computeLibraryElement(source);
-    sources = _context.launchableClientLibrarySources;
-    expect(sources, hasLength(1));
-  }
-
-  void test_getLaunchableServerLibrarySources() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    List<Source> sources = _context.launchableServerLibrarySources;
-    expect(sources, hasLength(0));
-    Source source = _addSource("/test.dart", "main() {}");
-    _context.computeLibraryElement(source);
-    sources = _context.launchableServerLibrarySources;
-    expect(sources, hasLength(1));
-  }
-
-  void test_getLibrariesContaining() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';''');
-    Source partSource = _addSource("/part.dart", "part of lib;");
-    _context.computeLibraryElement(librarySource);
-    List<Source> result = _context.getLibrariesContaining(librarySource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-    result = _context.getLibrariesContaining(partSource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-  }
-
-  void test_getLibrariesDependingOn() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source libASource = _addSource("/libA.dart", "library libA;");
-    _addSource("/libB.dart", "library libB;");
-    Source lib1Source = _addSource(
-        "/lib1.dart",
-        r'''
-library lib1;
-import 'libA.dart';
-export 'libB.dart';''');
-    Source lib2Source = _addSource(
-        "/lib2.dart",
-        r'''
-library lib2;
-import 'libB.dart';
-export 'libA.dart';''');
-    _context.computeLibraryElement(lib1Source);
-    _context.computeLibraryElement(lib2Source);
-    List<Source> result = _context.getLibrariesDependingOn(libASource);
-    expect(result, unorderedEquals([lib1Source, lib2Source]));
-  }
-
-  void test_getLibrariesReferencedFromHtml() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.dart'/>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    Source librarySource = _addSource("/test.dart", "library lib;");
-    _context.computeLibraryElement(librarySource);
-    _context.parseHtmlUnit(htmlSource);
-    List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
-    expect(result, hasLength(1));
-    expect(result[0], librarySource);
-  }
-
-  void test_getLibrariesReferencedFromHtml_no() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source htmlSource = _addSource(
-        "/test.html",
-        r'''
-<html><head>
-<script type='application/dart' src='test.js'/>
-</head></html>''');
-    _addSource("/test.dart", "library lib;");
-    _context.parseHtmlUnit(htmlSource);
-    List<Source> result = _context.getLibrariesReferencedFromHtml(htmlSource);
-    expect(result, hasLength(0));
-  }
-
-  void test_getLibraryElement() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "library lib;");
-    LibraryElement element = _context.getLibraryElement(source);
-    expect(element, isNull);
-    _context.computeLibraryElement(source);
-    element = _context.getLibraryElement(source);
-    expect(element, isNotNull);
-  }
-
-  void test_getLibrarySources() {
-    List<Source> sources = _context.librarySources;
-    int originalLength = sources.length;
-    Source source = _addSource("/test.dart", "library lib;");
-    _context.computeKindOf(source);
-    sources = _context.librarySources;
-    expect(sources, hasLength(originalLength + 1));
-    for (Source returnedSource in sources) {
-      if (returnedSource == source) {
-        return;
-      }
-    }
-    fail("The added source was not in the list of library sources");
-  }
-
-  void test_getLineInfo() {
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-library lib;
-
-main() {}''');
-    LineInfo info = _context.getLineInfo(source);
-    expect(info, isNull);
-    _context.parseCompilationUnit(source);
-    info = _context.getLineInfo(source);
-    expect(info, isNotNull);
-  }
-
-  void test_getModificationStamp_fromSource() {
-    int stamp = 42;
-    expect(
-        _context.getModificationStamp(
-            new AnalysisContextImplTest_Source_getModificationStamp_fromSource(
-                stamp)),
-        stamp);
-  }
-
-  void test_getModificationStamp_overridden() {
-    int stamp = 42;
-    Source source =
-        new AnalysisContextImplTest_Source_getModificationStamp_overridden(
-            stamp);
-    _context.setContents(source, "");
-    expect(stamp != _context.getModificationStamp(source), isTrue);
-  }
-
-  void test_getPublicNamespace_element() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.dart", "class A {}");
-    LibraryElement library = _context.computeLibraryElement(source);
-    Namespace namespace = _context.getPublicNamespace(library);
-    expect(namespace, isNotNull);
-    EngineTestCase.assertInstanceOf(
-        (obj) => obj is ClassElement, ClassElement, namespace.get("A"));
-  }
-
-  void test_getResolvedCompilationUnit_library() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library libb;");
-    LibraryElement library = _context.computeLibraryElement(source);
-    expect(_context.getResolvedCompilationUnit(source, library), isNotNull);
-    _context.setContents(source, "library lib;");
-    expect(_context.getResolvedCompilationUnit(source, library), isNull);
-  }
-
-  void test_getResolvedCompilationUnit_library_null() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    expect(_context.getResolvedCompilationUnit(source, null), isNull);
-  }
-
-  void test_getResolvedCompilationUnit_source_dart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
-    _context.resolveCompilationUnit2(source, source);
-    expect(_context.getResolvedCompilationUnit2(source, source), isNotNull);
-  }
-
-  void test_getResolvedCompilationUnit_source_html() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
-    expect(_context.resolveCompilationUnit2(source, source), isNull);
-    expect(_context.getResolvedCompilationUnit2(source, source), isNull);
-  }
-
-  void test_getResolvedHtmlUnit() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.getResolvedHtmlUnit(source), isNull);
-    _context.resolveHtmlUnit(source);
-    expect(_context.getResolvedHtmlUnit(source), isNotNull);
-  }
-
-  void test_getSourceFactory() {
-    expect(_context.sourceFactory, same(_sourceFactory));
-  }
-
-  void test_getSourcesWithFullName() {
-    String filePath = '/foo/lib/file.dart';
-    List<Source> expected = <Source>[];
-    ChangeSet changeSet = new ChangeSet();
-
-    TestSourceWithUri source1 =
-        new TestSourceWithUri(filePath, Uri.parse('file://$filePath'));
-    expected.add(source1);
-    changeSet.addedSource(source1);
-
-    TestSourceWithUri source2 =
-        new TestSourceWithUri(filePath, Uri.parse('package:foo/file.dart'));
-    expected.add(source2);
-    changeSet.addedSource(source2);
-
-    _context.applyChanges(changeSet);
-    expect(
-        _context.getSourcesWithFullName(filePath), unorderedEquals(expected));
-  }
-
-  void test_getStatistics() {
-    AnalysisContextStatistics statistics = _context.statistics;
-    expect(statistics, isNotNull);
-    // The following lines are fragile.
-    // The values depend on the number of libraries in the SDK.
-//    assertLength(0, statistics.getCacheRows());
-//    assertLength(0, statistics.getExceptions());
-//    assertLength(0, statistics.getSources());
-  }
-
-  Future test_implicitAnalysisEvents_added() async {
-    AnalyzedSourcesListener listener = new AnalyzedSourcesListener();
-    _context.implicitAnalysisEvents.listen(listener.onData);
-    //
-    // Create a file that references an file that is not explicitly being
-    // analyzed and fully analyze it. Ensure that the listener is told about
-    // the implicitly analyzed file.
-    //
-    Source sourceA = _addSource('/a.dart', "library a; import 'b.dart';");
-    Source sourceB = _createSource('/b.dart', "library b;");
-    _context.computeErrors(sourceA);
-    await pumpEventQueue();
-    listener.expectAnalyzed(sourceB);
-  }
-
-  void test_isClientLibrary_dart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-import 'dart:html';
-
-main() {}''');
-    expect(_context.isClientLibrary(source), isFalse);
-    expect(_context.isServerLibrary(source), isFalse);
-    _context.computeLibraryElement(source);
-    expect(_context.isClientLibrary(source), isTrue);
-    expect(_context.isServerLibrary(source), isFalse);
-  }
-
-  void test_isClientLibrary_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.isClientLibrary(source), isFalse);
-  }
-
-  void test_isServerLibrary_dart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource(
-        "/test.dart",
-        r'''
-library lib;
-
-main() {}''');
-    expect(_context.isClientLibrary(source), isFalse);
-    expect(_context.isServerLibrary(source), isFalse);
-    _context.computeLibraryElement(source);
-    expect(_context.isClientLibrary(source), isFalse);
-    expect(_context.isServerLibrary(source), isTrue);
-  }
-
-  void test_isServerLibrary_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.isServerLibrary(source), isFalse);
-  }
-
-  void test_parseCompilationUnit_errors() {
-    Source source = _addSource("/lib.dart", "library {");
-    CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
-    expect(compilationUnit, isNotNull);
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    expect(errors, isNotNull);
-    expect(errors.length > 0, isTrue);
-  }
-
-  void test_parseCompilationUnit_exception() {
-    Source source = _addSourceWithException("/test.dart");
-    try {
-      _context.parseCompilationUnit(source);
-      fail("Expected AnalysisException");
-    } on AnalysisException {
-      // Expected
-    }
-  }
-
-  void test_parseCompilationUnit_html() {
-    Source source = _addSource("/test.html", "<html></html>");
-    expect(_context.parseCompilationUnit(source), isNull);
-  }
-
-  void test_parseCompilationUnit_noErrors() {
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit = _context.parseCompilationUnit(source);
-    expect(compilationUnit, isNotNull);
-    expect(_context.getErrors(source).errors, hasLength(0));
-  }
-
-  void test_parseCompilationUnit_nonExistentSource() {
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    try {
-      _context.parseCompilationUnit(source);
-      fail("Expected AnalysisException because file does not exist");
-    } on AnalysisException {
-      // Expected result
-    }
-  }
-
-  void test_parseHtmlUnit_noErrors() {
-    Source source = _addSource("/lib.html", "<html></html>");
-    ht.HtmlUnit unit = _context.parseHtmlUnit(source);
-    expect(unit, isNotNull);
-  }
-
-  void test_parseHtmlUnit_resolveDirectives() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-class ClassA {}''');
-    Source source = _addSource(
-        "/lib.html",
-        r'''
-<html>
-<head>
-  <script type='application/dart'>
-    import 'lib.dart';
-    ClassA v = null;
-  </script>
-</head>
-<body>
-</body>
-</html>''');
-    ht.HtmlUnit unit = _context.parseHtmlUnit(source);
-    // import directive should be resolved
-    ht.XmlTagNode htmlNode = unit.tagNodes[0];
-    ht.XmlTagNode headNode = htmlNode.tagNodes[0];
-    ht.HtmlScriptTagNode scriptNode = headNode.tagNodes[0];
-    CompilationUnit script = scriptNode.script;
-    ImportDirective importNode = script.directives[0] as ImportDirective;
-    expect(importNode.uriContent, isNotNull);
-    expect(importNode.source, libSource);
-  }
-
-  void test_performAnalysisTask_addPart() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';''');
-    // run all tasks without part
-    _analyzeAll_assertFinished();
-    // add part and run all tasks
-    Source partSource = _addSource(
-        "/part.dart",
-        r'''
-part of lib;
-''');
-    _analyzeAll_assertFinished();
-    // "libSource" should be here
-    List<Source> librariesWithPart =
-        _context.getLibrariesContaining(partSource);
-    expect(librariesWithPart, unorderedEquals([libSource]));
-  }
-
-  void test_performAnalysisTask_changeLibraryContents() {
-    Source libSource =
-        _addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = _addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    _context.setContents(libSource, "library lib;");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    _context.setContents(libSource, "library lib; part 'test-part.dart';");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_changeLibraryThenPartContents() {
-    Source libSource =
-        _addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = _addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    _context.setContents(libSource, "library lib;");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    _context.setContents(partSource, "part of lib; // 1");
-    // Assert that changing the part's content does not effect the library
-    // now that it is no longer part of that library
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library changed 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_changePartContents_makeItAPart() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
-    Source partSource = _addSource("/part.dart", "void g() { f(null); }");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze
-    _context.setContents(
-        partSource,
-        r'''
-part of lib;
-void g() { f(null); }''');
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 2");
-    expect(_context.getErrors(libSource).errors, hasLength(0));
-    expect(_context.getErrors(partSource).errors, hasLength(0));
-  }
-
-  /**
-   * https://code.google.com/p/dart/issues/detail?id=12424
-   */
-  void test_performAnalysisTask_changePartContents_makeItNotPart() {
-    Source libSource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'part.dart';
-void f(x) {}''');
-    Source partSource = _addSource(
-        "/part.dart",
-        r'''
-part of lib;
-void g() { f(null); }''');
-    _analyzeAll_assertFinished();
-    expect(_context.getErrors(libSource).errors, hasLength(0));
-    expect(_context.getErrors(partSource).errors, hasLength(0));
-    // Remove 'part' directive, which should make "f(null)" an error.
-    _context.setContents(
-        partSource,
-        r'''
-//part of lib;
-void g() { f(null); }''');
-    _analyzeAll_assertFinished();
-    expect(_context.getErrors(libSource).errors.length != 0, isTrue);
-  }
-
-  void test_performAnalysisTask_changePartContents_noSemanticChanges() {
-    Source libSource =
-        _addSource("/test.dart", "library lib; part 'test-part.dart';");
-    Source partSource = _addSource("/test-part.dart", "part of lib;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 1");
-    // update and analyze #1
-    _context.setContents(partSource, "part of lib; // 1");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 2");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 2");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 2");
-    // update and analyze #2
-    _context.setContents(partSource, "part of lib; // 12");
-    expect(_context.getResolvedCompilationUnit2(libSource, libSource), isNull,
-        reason: "library changed 3");
-    expect(_context.getResolvedCompilationUnit2(partSource, libSource), isNull,
-        reason: "part changed 3");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libSource, libSource), isNotNull,
-        reason: "library resolved 3");
-    expect(
-        _context.getResolvedCompilationUnit2(partSource, libSource), isNotNull,
-        reason: "part resolved 3");
-  }
-
-  void test_performAnalysisTask_getContentException_dart() {
-    // add source that throw an exception on "get content"
-    Source source = new _Source_getContent_throwException('test.dart');
-    {
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.addedSource(source);
-      _context.applyChanges(changeSet);
-    }
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void test_performAnalysisTask_getContentException_html() {
-    // add source that throw an exception on "get content"
-    Source source = new _Source_getContent_throwException('test.html');
-    {
-      ChangeSet changeSet = new ChangeSet();
-      changeSet.addedSource(source);
-      _context.applyChanges(changeSet);
-    }
-    // prepare errors
-    _analyzeAll_assertFinished();
-    List<AnalysisError> errors = _context.getErrors(source).errors;
-    // validate errors
-    expect(errors, hasLength(1));
-    AnalysisError error = errors[0];
-    expect(error.source, same(source));
-    expect(error.errorCode, ScannerErrorCode.UNABLE_GET_CONTENT);
-  }
-
-  void test_performAnalysisTask_importedLibraryAdd() {
-    Source libASource =
-        _addSource("/libA.dart", "library libA; import 'libB.dart';");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 1");
-    expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA has an error");
-    // add libB.dart and analyze
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 2");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 2");
-    expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA doesn't have errors");
-  }
-
-  void test_performAnalysisTask_importedLibraryAdd_html() {
-    Source htmlSource = _addSource(
-        "/page.html",
-        r'''
-<html><body><script type="application/dart">
-  import '/libB.dart';
-  main() {print('hello dart');}
-</script></body></html>''');
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(htmlSource)),
-        isTrue,
-        reason: "htmlSource has an error");
-    // add libB.dart and analyze
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(_context.getResolvedHtmlUnit(htmlSource), isNotNull,
-        reason: "htmlUnit resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 2");
-    // TODO (danrubel) commented out to fix red bots
-//    AnalysisErrorInfo errors = _context.getErrors(htmlSource);
-//    expect(
-//        !_hasAnalysisErrorWithErrorSeverity(errors),
-//        isTrue,
-//        reason: "htmlSource doesn't have errors");
-  }
-
-  void test_performAnalysisTask_importedLibraryDelete() {
-    Source libASource =
-        _addSource("/libA.dart", "library libA; import 'libB.dart';");
-    Source libBSource = _addSource("/libB.dart", "library libB;");
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 1");
-    expect(
-        _context.getResolvedCompilationUnit2(libBSource, libBSource), isNotNull,
-        reason: "libB resolved 1");
-    expect(!_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA doesn't have errors");
-    // remove libB.dart content and analyze
-    _context.setContents(libBSource, null);
-    _analyzeAll_assertFinished();
-    expect(
-        _context.getResolvedCompilationUnit2(libASource, libASource), isNotNull,
-        reason: "libA resolved 2");
-    expect(_hasAnalysisErrorWithErrorSeverity(_context.getErrors(libASource)),
-        isTrue,
-        reason: "libA has an error");
-  }
-
-  void test_performAnalysisTask_IOException() {
-    TestSource source = _addSourceWithException2("/test.dart", "library test;");
-    int oldTimestamp = _context.getModificationStamp(source);
-    source.generateExceptionOnRead = false;
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 1);
-    source.generateExceptionOnRead = true;
-    do {
-      _changeSource(source, "");
-      // Ensure that the timestamp differs,
-      // so that analysis engine notices the change
-    } while (oldTimestamp == _context.getModificationStamp(source));
-    _analyzeAll_assertFinished();
-    expect(source.readCount, 2);
-  }
-
-  void test_performAnalysisTask_missingPart() {
-    Source source =
-        _addSource("/test.dart", "library lib; part 'no-such-file.dart';");
-    _analyzeAll_assertFinished();
-    expect(_context.getLibraryElement(source), isNotNull,
-        reason: "performAnalysisTask failed to compute an element model");
-  }
-
-  void test_performAnalysisTask_modifiedAfterParse() {
-    // TODO(scheglov) no threads in Dart
-//    Source source = _addSource("/test.dart", "library lib;");
-//    int initialTime = _context.getModificationStamp(source);
-//    List<Source> sources = new List<Source>();
-//    sources.add(source);
-//    _context.analysisPriorityOrder = sources;
-//    _context.parseCompilationUnit(source);
-//    while (initialTime == JavaSystem.currentTimeMillis()) {
-//      Thread.sleep(1);
-//      // Force the modification time to be different.
-//    }
-//    _context.setContents(source, "library test;");
-//    JUnitTestCase.assertTrue(initialTime != _context.getModificationStamp(source));
-//    _analyzeAll_assertFinished();
-//    JUnitTestCase.assertNotNullMsg("performAnalysisTask failed to compute an element model", _context.getLibraryElement(source));
-  }
-
-  void test_resolveCompilationUnit_import_relative() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    Source sourceA =
-        _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
-    _addSource("/libB.dart", "library libB; class B{}");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(sourceA, sourceA);
-    LibraryElement library = compilationUnit.element.library;
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-    List<LibraryElement> visibleLibraries = library.visibleLibraries;
-    assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
-  }
-
-  void test_resolveCompilationUnit_import_relative_cyclic() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    Source sourceA =
-        _addSource("/libA.dart", "library libA; import 'libB.dart'; class A{}");
-    _addSource("/libB.dart", "library libB; import 'libA.dart'; class B{}");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(sourceA, sourceA);
-    LibraryElement library = compilationUnit.element.library;
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-    List<LibraryElement> visibleLibraries = library.visibleLibraries;
-    assertNamedElements(visibleLibraries, ["dart.core", "libA", "libB"]);
-  }
-
-  void test_resolveCompilationUnit_library() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    LibraryElement library = _context.computeLibraryElement(source);
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit(source, library);
-    expect(compilationUnit, isNotNull);
-    expect(compilationUnit.element, isNotNull);
-  }
-
-  void test_resolveCompilationUnit_source() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(source, source);
-    expect(compilationUnit, isNotNull);
-  }
-
-  void test_resolveCompilationUnit_sourceChangeDuringResolution() {
-    _context = new _AnalysisContext_sourceChangeDuringResolution();
-    AnalysisContextFactory.initContextWithCore(_context);
-    _sourceFactory = _context.sourceFactory;
-    Source source = _addSource("/lib.dart", "library lib;");
-    CompilationUnit compilationUnit =
-        _context.resolveCompilationUnit2(source, source);
-    expect(compilationUnit, isNotNull);
-    expect(_context.getLineInfo(source), isNotNull);
-  }
-
-  void test_resolveHtmlUnit() {
-    Source source = _addSource("/lib.html", "<html></html>");
-    ht.HtmlUnit unit = _context.resolveHtmlUnit(source);
-    expect(unit, isNotNull);
-  }
-
-  void test_setAnalysisOptions() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.cacheSize = 42;
-    options.dart2jsHint = false;
-    options.hint = false;
-    _context.analysisOptions = options;
-    AnalysisOptions result = _context.analysisOptions;
-    expect(result.cacheSize, options.cacheSize);
-    expect(result.dart2jsHint, options.dart2jsHint);
-    expect(result.hint, options.hint);
-  }
-
-  void test_setAnalysisOptions_reduceAnalysisPriorityOrder() {
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    List<Source> sources = new List<Source>();
-    for (int index = 0; index < options.cacheSize; index++) {
-      sources.add(_addSource("/lib.dart$index", ""));
-    }
-    _context.analysisPriorityOrder = sources;
-    int oldPriorityOrderSize = _getPriorityOrder(_context).length;
-    options.cacheSize = options.cacheSize - 10;
-    _context.analysisOptions = options;
-    expect(oldPriorityOrderSize > _getPriorityOrder(_context).length, isTrue);
-  }
-
-  void test_setAnalysisPriorityOrder_empty() {
-    _context.analysisPriorityOrder = new List<Source>();
-  }
-
-  void test_setAnalysisPriorityOrder_lessThanCacheSize() {
-    AnalysisOptions options = _context.analysisOptions;
-    List<Source> sources = new List<Source>();
-    for (int index = 0; index < options.cacheSize; index++) {
-      sources.add(_addSource("/lib.dart$index", ""));
-    }
-    _context.analysisPriorityOrder = sources;
-    expect(options.cacheSize > _getPriorityOrder(_context).length, isTrue);
-  }
-
-  void test_setAnalysisPriorityOrder_nonEmpty() {
-    List<Source> sources = new List<Source>();
-    sources.add(_addSource("/lib.dart", "library lib;"));
-    _context.analysisPriorityOrder = sources;
-  }
-
-  Future test_setChangedContents_libraryWithPart() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    options.incremental = true;
-    _context = AnalysisContextFactory.oldContextWithCoreAndOptions(options);
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String oldCode = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", oldCode);
-    String partContents = r'''
-part of lib;
-int b = a;''';
-    Source partSource = _addSource("/part.dart", partContents);
-    LibraryElement element = _context.computeLibraryElement(librarySource);
-    CompilationUnit unit =
-        _context.getResolvedCompilationUnit(librarySource, element);
-    expect(unit, isNotNull);
-    int offset = oldCode.indexOf("int a") + 4;
-    String newCode = r'''
-library lib;
-part 'part.dart';
-int ya = 0;''';
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-    _context.setChangedContents(librarySource, newCode, offset, 0, 1);
-    expect(_context.getContents(librarySource).data, newCode);
-    IncrementalAnalysisCache incrementalCache =
-        _getIncrementalAnalysisCache(_context);
-    expect(incrementalCache.librarySource, librarySource);
-    expect(incrementalCache.resolvedUnit, same(unit));
-    expect(_context.getResolvedCompilationUnit2(partSource, librarySource),
-        isNull);
-    expect(incrementalCache.newContents, newCode);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_setChangedContents_notResolved() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    options.incremental = true;
-    _context.analysisOptions = options;
-    _sourceFactory = _context.sourceFactory;
-    String oldCode = r'''
-library lib;
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", oldCode);
-    int offset = oldCode.indexOf("int a") + 4;
-    String newCode = r'''
-library lib;
-int ya = 0;''';
-    _context.setChangedContents(librarySource, newCode, offset, 0, 1);
-    expect(_context.getContents(librarySource).data, newCode);
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-  }
-
-  Future test_setContents_libraryWithPart() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    SourcesChangedListener listener = new SourcesChangedListener();
-    _context.onSourcesChanged.listen(listener.onData);
-    _sourceFactory = _context.sourceFactory;
-    String libraryContents1 = r'''
-library lib;
-part 'part.dart';
-int a = 0;''';
-    Source librarySource = _addSource("/lib.dart", libraryContents1);
-    String partContents1 = r'''
-part of lib;
-int b = a;''';
-    Source partSource = _addSource("/part.dart", partContents1);
-    _context.computeLibraryElement(librarySource);
-    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
-        librarySource, librarySource, null, null, null, 0, 0, 0);
-    _setIncrementalAnalysisCache(_context, incrementalCache);
-    expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
-    String libraryContents2 = r'''
-library lib;
-part 'part.dart';
-int aa = 0;''';
-    _context.setContents(librarySource, libraryContents2);
-    expect(_context.getResolvedCompilationUnit2(partSource, librarySource),
-        isNull);
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-    return pumpEventQueue().then((_) {
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertEvent(wereSourcesAdded: true);
-      listener.assertEvent(changedSources: [partSource]);
-      listener.assertEvent(changedSources: [librarySource]);
-      listener.assertNoMoreEvents();
-    });
-  }
-
-  void test_setContents_null() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source librarySource = _addSource(
-        "/lib.dart",
-        r'''
-library lib;
-int a = 0;''');
-    _context.computeLibraryElement(librarySource);
-    IncrementalAnalysisCache incrementalCache = new IncrementalAnalysisCache(
-        librarySource, librarySource, null, null, null, 0, 0, 0);
-    _setIncrementalAnalysisCache(_context, incrementalCache);
-    expect(_getIncrementalAnalysisCache(_context), same(incrementalCache));
-    _context.setContents(librarySource, null);
-    expect(_context.getResolvedCompilationUnit2(librarySource, librarySource),
-        isNull);
-    expect(_getIncrementalAnalysisCache(_context), isNull);
-  }
-
-  void test_setContents_unchanged_consistentModificationTime() {
-    String contents = "// foo";
-    Source source = _addSource("/test.dart", contents);
-    // do all, no tasks
-    _analyzeAll_assertFinished();
-    {
-      AnalysisResult result = _context.performAnalysisTask();
-      expect(result.changeNotices, isNull);
-    }
-    // set the same contents, still no tasks
-    _context.setContents(source, contents);
-    {
-      AnalysisResult result = _context.performAnalysisTask();
-      expect(result.changeNotices, isNull);
-    }
-  }
-
-  void test_setSourceFactory() {
-    expect(_context.sourceFactory, _sourceFactory);
-    SourceFactory factory = new SourceFactory([]);
-    _context.sourceFactory = factory;
-    expect(_context.sourceFactory, factory);
-  }
-
-  void test_unreadableSource() {
-    _context = AnalysisContextFactory.oldContextWithCore();
-    _sourceFactory = _context.sourceFactory;
-    Source test1 = _addSource(
-        "/test1.dart",
-        r'''
-import 'test2.dart';
-library test1;''');
-    Source test2 = _addSource(
-        "/test2.dart",
-        r'''
-import 'test1.dart';
-import 'test3.dart';
-library test2;''');
-    Source test3 = _addSourceWithException("/test3.dart");
-    _analyzeAll_assertFinished();
-    // test1 and test2 should have been successfully analyzed
-    // despite the fact that test3 couldn't be read.
-    expect(_context.computeLibraryElement(test1), isNotNull);
-    expect(_context.computeLibraryElement(test2), isNotNull);
-    expect(_context.computeLibraryElement(test3), isNull);
-  }
-
-  void test_updateAnalysis() {
-    expect(_context.sourcesNeedingProcessing.isEmpty, isTrue);
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    AnalysisDelta delta = new AnalysisDelta();
-    delta.setAnalysisLevel(source, AnalysisLevel.ALL);
-    _context.applyAnalysisDelta(delta);
-    expect(_context.sourcesNeedingProcessing.contains(source), isTrue);
-    delta = new AnalysisDelta();
-    delta.setAnalysisLevel(source, AnalysisLevel.NONE);
-    _context.applyAnalysisDelta(delta);
-    expect(_context.sourcesNeedingProcessing.contains(source), isFalse);
-  }
-
-  void xtest_performAnalysisTask_stress() {
-    int maxCacheSize = 4;
-    AnalysisOptionsImpl options =
-        new AnalysisOptionsImpl.from(_context.analysisOptions);
-    options.cacheSize = maxCacheSize;
-    _context.analysisOptions = options;
-    int sourceCount = maxCacheSize + 2;
-    List<Source> sources = new List<Source>();
-    ChangeSet changeSet = new ChangeSet();
-    for (int i = 0; i < sourceCount; i++) {
-      Source source = _addSource("/lib$i.dart", "library lib$i;");
-      sources.add(source);
-      changeSet.addedSource(source);
-    }
-    _context.applyChanges(changeSet);
-    _context.analysisPriorityOrder = sources;
-    for (int i = 0; i < 1000; i++) {
-      List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
-      if (notice == null) {
-        //System.out.println("test_performAnalysisTask_stress: " + i);
-        break;
-      }
-    }
-    List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
-    if (notice != null) {
-      fail(
-          "performAnalysisTask failed to terminate after analyzing all sources");
-    }
-  }
-
-  Source _addSource(String fileName, String contents) {
-    Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    _context.setContents(source, contents);
-    return source;
-  }
-
-  TestSource _addSourceWithException(String fileName) {
-    return _addSourceWithException2(fileName, "");
-  }
-
-  TestSource _addSourceWithException2(String fileName, String contents) {
-    TestSource source = new TestSource(fileName, contents);
-    source.generateExceptionOnRead = true;
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    _context.applyChanges(changeSet);
-    return source;
-  }
-
-  /**
-   * Perform analysis tasks up to 512 times and asserts that that was enough.
-   */
-  void _analyzeAll_assertFinished() {
-    _analyzeAll_assertFinished2(512);
-  }
-
-  /**
-   * Perform analysis tasks up to the given number of times and asserts that that was enough.
-   *
-   * @param maxIterations the maximum number of tasks to perform
-   */
-  void _analyzeAll_assertFinished2(int maxIterations) {
-    for (int i = 0; i < maxIterations; i++) {
-      List<ChangeNotice> notice = _context.performAnalysisTask().changeNotices;
-      if (notice == null) {
-        return;
-      }
-    }
-    fail("performAnalysisTask failed to terminate after analyzing all sources");
-  }
-
-  void _changeSource(TestSource source, String contents) {
-    source.setContents(contents);
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(source);
-    _context.applyChanges(changeSet);
-  }
-
-  Source _createSource(String fileName, String contents) {
-    Source source = new FileBasedSource(FileUtilities2.createFile(fileName));
-    _context.setContents(source, contents);
-    return source;
-  }
-
-  /**
-   * Search the given compilation unit for a class with the given name. Return the class with the
-   * given name, or `null` if the class cannot be found.
-   *
-   * @param unit the compilation unit being searched
-   * @param className the name of the class being searched for
-   * @return the class with the given name
-   */
-  ClassElement _findClass(CompilationUnitElement unit, String className) {
-    for (ClassElement classElement in unit.types) {
-      if (classElement.displayName == className) {
-        return classElement;
-      }
-    }
-    return null;
-  }
-
-  IncrementalAnalysisCache _getIncrementalAnalysisCache(
-      AnalysisContextImpl context2) {
-    return context2.test_incrementalAnalysisCache;
-  }
-
-  List<Source> _getPriorityOrder(AnalysisContextImpl context2) {
-    return context2.test_priorityOrder;
-  }
-
-  void _performPendingAnalysisTasks([int maxTasks = 20]) {
-    for (int i = 0; _context.performAnalysisTask().hasMoreWork; i++) {
-      if (i > maxTasks) {
-        fail('Analysis did not terminate.');
-      }
-    }
-  }
-
-  void _removeSource(Source source) {
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.removedSource(source);
-    _context.applyChanges(changeSet);
-  }
-
-  void _setIncrementalAnalysisCache(
-      AnalysisContextImpl context, IncrementalAnalysisCache incrementalCache) {
-    context.test_incrementalAnalysisCache = incrementalCache;
-  }
-
-  /**
-   * Returns `true` if there is an [AnalysisError] with [ErrorSeverity.ERROR] in
-   * the given [AnalysisErrorInfo].
-   */
-  static bool _hasAnalysisErrorWithErrorSeverity(AnalysisErrorInfo errorInfo) {
-    List<AnalysisError> errors = errorInfo.errors;
-    for (AnalysisError analysisError in errors) {
-      if (analysisError.errorCode.errorSeverity == ErrorSeverity.ERROR) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-class AnalysisContextImplTest_Source_exists_true extends TestSource {
-  @override
-  bool exists() => true;
-}
-
-class AnalysisContextImplTest_Source_getModificationStamp_fromSource
-    extends TestSource {
-  int stamp;
-  AnalysisContextImplTest_Source_getModificationStamp_fromSource(this.stamp);
-  @override
-  int get modificationStamp => stamp;
-}
-
-class AnalysisContextImplTest_Source_getModificationStamp_overridden
-    extends TestSource {
-  int stamp;
-  AnalysisContextImplTest_Source_getModificationStamp_overridden(this.stamp);
-  @override
-  int get modificationStamp => stamp;
-}
-
-@reflectiveTest
-class AnalysisOptionsImplTest extends EngineTestCase {
-  void test_AnalysisOptionsImpl_copy() {
-    bool booleanValue = true;
-    for (int i = 0; i < 2; i++, booleanValue = !booleanValue) {
-      AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-      options.analyzeFunctionBodies = booleanValue;
-      options.cacheSize = i;
-      options.dart2jsHint = booleanValue;
-      options.enableGenericMethods = booleanValue;
-      options.enableStrictCallChecks = booleanValue;
-      options.enableSuperMixins = booleanValue;
-      options.generateImplicitErrors = booleanValue;
-      options.generateSdkErrors = booleanValue;
-      options.hint = booleanValue;
-      options.incremental = booleanValue;
-      options.preserveComments = booleanValue;
-      options.strongMode = booleanValue;
-      AnalysisOptionsImpl copy = new AnalysisOptionsImpl.from(options);
-      expect(copy.analyzeFunctionBodies, options.analyzeFunctionBodies);
-      expect(copy.cacheSize, options.cacheSize);
-      expect(copy.dart2jsHint, options.dart2jsHint);
-      expect(copy.enableStrictCallChecks, options.enableStrictCallChecks);
-      expect(copy.enableSuperMixins, options.enableSuperMixins);
-      expect(copy.generateImplicitErrors, options.generateImplicitErrors);
-      expect(copy.generateSdkErrors, options.generateSdkErrors);
-      expect(copy.hint, options.hint);
-      expect(copy.incremental, options.incremental);
-      expect(copy.preserveComments, options.preserveComments);
-      expect(copy.strongMode, options.strongMode);
-    }
-  }
-
-  void test_analyzeFunctionBodies() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.analyzeFunctionBodies;
-    options.analyzeFunctionBodies = value;
-    expect(options.analyzeFunctionBodies, value);
-  }
-
-  void test_cacheSize() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    expect(options.cacheSize, AnalysisOptionsImpl.DEFAULT_CACHE_SIZE);
-    int value = options.cacheSize + 1;
-    options.cacheSize = value;
-    expect(options.cacheSize, value);
-  }
-
-  void test_dart2jsHint() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.dart2jsHint;
-    options.dart2jsHint = value;
-    expect(options.dart2jsHint, value);
-  }
-
-  void test_enableGenericMethods() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.enableGenericMethods;
-    options.enableGenericMethods = value;
-    expect(options.enableGenericMethods, value);
-  }
-
-  void test_enableSuperMixins() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.enableSuperMixins;
-    options.enableSuperMixins = value;
-    expect(options.enableSuperMixins, value);
-  }
-
-  void test_generateImplicitErrors() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.generateImplicitErrors;
-    options.generateImplicitErrors = value;
-    expect(options.generateImplicitErrors, value);
-  }
-
-  void test_generateSdkErrors() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.generateSdkErrors;
-    options.generateSdkErrors = value;
-    expect(options.generateSdkErrors, value);
-  }
-
-  void test_hint() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.hint;
-    options.hint = value;
-    expect(options.hint, value);
-  }
-
-  void test_incremental() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.incremental;
-    options.incremental = value;
-    expect(options.incremental, value);
-  }
-
-  void test_preserveComments() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.preserveComments;
-    options.preserveComments = value;
-    expect(options.preserveComments, value);
-  }
-
-  void test_strongMode() {
-    AnalysisOptionsImpl options = new AnalysisOptionsImpl();
-    bool value = !options.strongMode;
-    options.strongMode = value;
-    expect(options.strongMode, value);
-  }
-}
-
-class AnalysisTask_test_perform_exception extends AnalysisTask {
-  AnalysisTask_test_perform_exception(InternalAnalysisContext arg0)
-      : super(arg0);
-  @override
-  String get taskDescription => null;
-  @override
-  accept(AnalysisTaskVisitor visitor) {
-    expect(exception, isNotNull);
-    return null;
-  }
-
-  @override
-  void internalPerform() {
-    throw new AnalysisException("Forced exception");
-  }
-}
-
-@reflectiveTest
-class AnalysisTaskTest extends EngineTestCase {
-  void test_perform_exception() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    AnalysisTask task = new AnalysisTask_test_perform_exception(context);
-    task.perform(new TestTaskVisitor<Object>());
-  }
 }
 
 /**
@@ -2523,2277 +72,7 @@
   }
 }
 
-class CompilationUnitMock extends TypedMock implements CompilationUnit {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-@reflectiveTest
-class DartEntryTest extends EngineTestCase {
-  void test_allErrors() {
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.allErrors, hasLength(0));
-    entry.setValue(SourceEntry.CONTENT_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, ScannerErrorCode.UNABLE_GET_CONTENT,
-          ['exception details'])
-    ]);
-    entry.setValue(DartEntry.SCAN_ERRORS, <AnalysisError>[
-      new AnalysisError(
-          source, 0, 0, ScannerErrorCode.UNTERMINATED_STRING_LITERAL)
-    ]);
-    entry.setValue(DartEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, ParserErrorCode.ABSTRACT_CLASS_MEMBER)
-    ]);
-    entry.setValueInLibrary(
-        DartEntry.RESOLUTION_ERRORS, source, <AnalysisError>[
-      new AnalysisError(
-          source, 0, 0, CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)
-    ]);
-    entry.setValueInLibrary(
-        DartEntry.VERIFICATION_ERRORS, source, <AnalysisError>[
-      new AnalysisError(
-          source, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
-    ]);
-    entry.setValueInLibrary(DartEntry.HINTS, source,
-        <AnalysisError>[new AnalysisError(source, 0, 0, HintCode.DEAD_CODE)]);
-    expect(entry.allErrors, hasLength(6));
-  }
-
-  void test_creation() {
-    Source librarySource = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.CONTAINING_LIBRARIES),
-        same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_getResolvableCompilationUnit_none() {
-    DartEntry entry = new DartEntry();
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_getResolvableCompilationUnit_parsed_accessed() {
-    Source librarySource = new TestSource("/lib.dart");
-    String importUri = "/f1.dart";
-    Source importSource = new TestSource(importUri);
-    ImportDirective importDirective =
-        AstFactory.importDirective3(importUri, null);
-    importDirective.source = importSource;
-    importDirective.uriContent = importUri;
-    String exportUri = "/f2.dart";
-    Source exportSource = new TestSource(exportUri);
-    ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
-    exportDirective.source = exportSource;
-    exportDirective.uriContent = exportUri;
-    String partUri = "/f3.dart";
-    Source partSource = new TestSource(partUri);
-    PartDirective partDirective = AstFactory.partDirective2(partUri);
-    partDirective.source = partSource;
-    partDirective.uriContent = partUri;
-    CompilationUnit unit = AstFactory
-        .compilationUnit3([importDirective, exportDirective, partDirective]);
-    DartEntry entry = new DartEntry();
-    entry.setValue(DartEntry.PARSED_UNIT, unit);
-    entry.getValue(DartEntry.PARSED_UNIT);
-    CompilationUnit result = entry.resolvableCompilationUnit;
-    expect(result, same(unit));
-    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
-    result = entry.resolvableCompilationUnit;
-    expect(result, isNot(same(unit)));
-    NodeList<Directive> directives = result.directives;
-    ImportDirective resultImportDirective = directives[0] as ImportDirective;
-    expect(resultImportDirective.uriContent, importUri);
-    expect(resultImportDirective.source, same(importSource));
-    ExportDirective resultExportDirective = directives[1] as ExportDirective;
-    expect(resultExportDirective.uriContent, exportUri);
-    expect(resultExportDirective.source, same(exportSource));
-    PartDirective resultPartDirective = directives[2] as PartDirective;
-    expect(resultPartDirective.uriContent, partUri);
-    expect(resultPartDirective.source, same(partSource));
-  }
-
-  void test_getResolvableCompilationUnit_parsed_notAccessed() {
-    CompilationUnit unit = AstFactory.compilationUnit();
-    DartEntry entry = new DartEntry();
-    entry.setValue(DartEntry.PARSED_UNIT, unit);
-    expect(entry.resolvableCompilationUnit, same(unit));
-  }
-
-  void test_getResolvableCompilationUnit_resolved() {
-    String importUri = "f1.dart";
-    Source importSource = new TestSource(importUri);
-    ImportDirective importDirective =
-        AstFactory.importDirective3(importUri, null);
-    importDirective.source = importSource;
-    importDirective.uriContent = importUri;
-    String exportUri = "f2.dart";
-    Source exportSource = new TestSource(exportUri);
-    ExportDirective exportDirective = AstFactory.exportDirective2(exportUri);
-    exportDirective.source = exportSource;
-    exportDirective.uriContent = exportUri;
-    String partUri = "f3.dart";
-    Source partSource = new TestSource(partUri);
-    PartDirective partDirective = AstFactory.partDirective2(partUri);
-    partDirective.source = partSource;
-    partDirective.uriContent = partUri;
-    CompilationUnit unit = AstFactory
-        .compilationUnit3([importDirective, exportDirective, partDirective]);
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, new TestSource("lib.dart"), unit);
-    CompilationUnit result = entry.resolvableCompilationUnit;
-    expect(result, isNot(same(unit)));
-    NodeList<Directive> directives = result.directives;
-    ImportDirective resultImportDirective = directives[0] as ImportDirective;
-    expect(resultImportDirective.uriContent, importUri);
-    expect(resultImportDirective.source, same(importSource));
-    ExportDirective resultExportDirective = directives[1] as ExportDirective;
-    expect(resultExportDirective.uriContent, exportUri);
-    expect(resultExportDirective.source, same(exportSource));
-    PartDirective resultPartDirective = directives[2] as PartDirective;
-    expect(resultPartDirective.uriContent, partUri);
-    expect(resultPartDirective.source, same(partSource));
-  }
-
-  void test_getState_invalid_resolutionErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getState(DartEntry.RESOLUTION_ERRORS);
-      fail("Expected ArgumentError for RESOLUTION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getState_invalid_verificationErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getState(DartEntry.VERIFICATION_ERRORS);
-      fail("Expected ArgumentError for VERIFICATION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getStateInLibrary_invalid_element() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getStateInLibrary(DartEntry.ELEMENT, new TestSource());
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getValue_containingLibraries() {
-    Source testSource = new TestSource();
-    DartEntry entry = new DartEntry();
-    List<Source> value = entry.containingLibraries;
-    expect(value, hasLength(0));
-    entry.addContainingLibrary(testSource);
-    value = entry.containingLibraries;
-    expect(value, hasLength(1));
-    expect(value[0], testSource);
-    entry.removeContainingLibrary(testSource);
-    value = entry.containingLibraries;
-    expect(value, hasLength(0));
-  }
-
-  void test_getValue_invalid_resolutionErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getValue(DartEntry.RESOLUTION_ERRORS);
-      fail("Expected ArgumentError for RESOLUTION_ERRORS");
-    } on ArgumentError {}
-  }
-
-  void test_getValue_invalid_verificationErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getValue(DartEntry.VERIFICATION_ERRORS);
-      fail("Expected ArgumentError for VERIFICATION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getValueInLibrary_invalid_element() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.getValueInLibrary(DartEntry.ELEMENT, new TestSource());
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_getValueInLibrary_invalid_resolutionErrors_multiple() {
-    Source source1 = new TestSource();
-    Source source2 = new TestSource();
-    Source source3 = new TestSource();
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    try {
-      entry.getValueInLibrary(DartEntry.ELEMENT, source3);
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_hasInvalidData_false() {
-    DartEntry entry = new DartEntry();
-    entry.recordScanError(new CaughtException(new AnalysisException(), null));
-    expect(entry.hasInvalidData(DartEntry.ELEMENT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isFalse);
-    expect(entry.hasInvalidData(DartEntry.HINTS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isFalse);
-    expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isFalse);
-    expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isFalse);
-    expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isFalse);
-    expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isFalse);
-    expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isFalse);
-    expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isFalse);
-    expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isFalse);
-  }
-
-  void test_hasInvalidData_true() {
-    DartEntry entry = new DartEntry();
-    expect(entry.hasInvalidData(DartEntry.ELEMENT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.EXPORTED_LIBRARIES), isTrue);
-    expect(entry.hasInvalidData(DartEntry.HINTS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.IMPORTED_LIBRARIES), isTrue);
-    expect(entry.hasInvalidData(DartEntry.INCLUDED_PARTS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.IS_CLIENT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.IS_LAUNCHABLE), isTrue);
-    expect(entry.hasInvalidData(SourceEntry.LINE_INFO), isTrue);
-    expect(entry.hasInvalidData(DartEntry.PARSE_ERRORS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.PARSED_UNIT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.PUBLIC_NAMESPACE), isTrue);
-    expect(entry.hasInvalidData(DartEntry.SOURCE_KIND), isTrue);
-    expect(entry.hasInvalidData(DartEntry.RESOLUTION_ERRORS), isTrue);
-    expect(entry.hasInvalidData(DartEntry.RESOLVED_UNIT), isTrue);
-    expect(entry.hasInvalidData(DartEntry.VERIFICATION_ERRORS), isTrue);
-  }
-
-  void test_invalidateAllInformation() {
-    Source librarySource = new TestSource();
-    DartEntry entry = _entryWithValidState(librarySource);
-    entry.invalidateAllInformation();
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.INVALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_invalidateAllResolutionInformation() {
-    Source librarySource = new TestSource();
-    DartEntry entry = _entryWithValidState(librarySource);
-    entry.invalidateAllResolutionInformation(false);
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_invalidateAllResolutionInformation_includingUris() {
-    Source librarySource = new TestSource();
-    DartEntry entry = _entryWithValidState(librarySource);
-    entry.invalidateAllResolutionInformation(true);
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.INVALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, librarySource),
-        same(CacheState.INVALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, librarySource),
-        same(CacheState.INVALID));
-  }
-
-  void test_isClient() {
-    DartEntry entry = new DartEntry();
-    // true
-    entry.setValue(DartEntry.IS_CLIENT, true);
-    expect(entry.getValue(DartEntry.IS_CLIENT), isTrue);
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    // invalidate
-    entry.setState(DartEntry.IS_CLIENT, CacheState.INVALID);
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.INVALID));
-    // false
-    entry.setValue(DartEntry.IS_CLIENT, false);
-    expect(entry.getValue(DartEntry.IS_CLIENT), isFalse);
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-  }
-
-  void test_isLaunchable() {
-    DartEntry entry = new DartEntry();
-    // true
-    entry.setValue(DartEntry.IS_LAUNCHABLE, true);
-    expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isTrue);
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    // invalidate
-    entry.setState(DartEntry.IS_LAUNCHABLE, CacheState.INVALID);
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.INVALID));
-    // false
-    entry.setValue(DartEntry.IS_LAUNCHABLE, false);
-    expect(entry.getValue(DartEntry.IS_LAUNCHABLE), isFalse);
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-  }
-
-  void test_recordBuildElementError() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordBuildElementErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_recordContentError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry
-        .recordContentError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.ERROR));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordHintErrorInLibrary() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordHintErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_recordParseError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry.recordParseError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordResolutionError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry.recordResolutionError(
-        new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordResolutionErrorInLibrary() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordResolutionErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_recordScanError() {
-    Source firstLibrary = new TestSource('first.dart');
-//    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary);
-    entry.recordScanError(new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.ERROR));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    // The following lines are commented out because we don't currently have
-    // any way of setting the state for data associated with a library we
-    // don't know anything about.
-//    expect(entry.getStateInLibrary(DartEntry.ANGULAR_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary), same(CacheState.ERROR));
-//    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary), same(CacheState.ERROR));
-  }
-
-  void test_recordVerificationErrorInLibrary() {
-    Source firstLibrary = new TestSource('first.dart');
-    Source secondLibrary = new TestSource('second.dart');
-    DartEntry entry = _entryWithValidState(firstLibrary, secondLibrary);
-    entry.recordVerificationErrorInLibrary(
-        firstLibrary, new CaughtException(new AnalysisException(), null));
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-        same(CacheState.ERROR));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-        same(CacheState.ERROR));
-
-    expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-    expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-        same(CacheState.VALID));
-    expect(
-        entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-        same(CacheState.VALID));
-  }
-
-  void test_removeResolution_multiple_first() {
-    Source source1 = new TestSource('first.dart');
-    Source source2 = new TestSource('second.dart');
-    Source source3 = new TestSource('third.dart');
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    entry.removeResolution(source1);
-  }
-
-  void test_removeResolution_multiple_last() {
-    Source source1 = new TestSource('first.dart');
-    Source source2 = new TestSource('second.dart');
-    Source source3 = new TestSource('third.dart');
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    entry.removeResolution(source3);
-  }
-
-  void test_removeResolution_multiple_middle() {
-    Source source1 = new TestSource('first.dart');
-    Source source2 = new TestSource('second.dart');
-    Source source3 = new TestSource('third.dart');
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source2, AstFactory.compilationUnit());
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source3, AstFactory.compilationUnit());
-    entry.removeResolution(source2);
-  }
-
-  void test_removeResolution_single() {
-    Source source1 = new TestSource();
-    DartEntry entry = new DartEntry();
-    entry.setValueInLibrary(
-        DartEntry.RESOLVED_UNIT, source1, AstFactory.compilationUnit());
-    entry.removeResolution(source1);
-  }
-
-  void test_resolvableCompilationUnit_builtUnit() {
-    Source librarySource = new TestSource('/lib.dart');
-    CompilationUnit unit = AstFactory.compilationUnit();
-    CompilationUnitElement element =
-        ElementFactory.compilationUnit('test.dart');
-    unit.element = element;
-    DartEntry entry = new DartEntry();
-    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-    entry.setValueInLibrary(DartEntry.BUILT_UNIT, librarySource, unit);
-    entry.invalidateAllResolutionInformation(false);
-    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
-    expect(resolvableUnit, isNotNull);
-    expect(resolvableUnit.element, isNull);
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_resolvableCompilationUnit_none() {
-    DartEntry entry = new DartEntry();
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_resolvableCompilationUnit_parsed() {
-    CompilationUnit unit = AstFactory.compilationUnit();
-    DartEntry entry = new DartEntry();
-    entry.setValue(DartEntry.PARSED_UNIT, unit);
-    expect(entry.resolvableCompilationUnit, unit);
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_resolvableCompilationUnit_resolved() {
-    Source librarySource = new TestSource('/lib.dart');
-    CompilationUnit unit = AstFactory.compilationUnit();
-    CompilationUnitElement element =
-        ElementFactory.compilationUnit('test.dart');
-    unit.element = element;
-    DartEntry entry = new DartEntry();
-    entry.setState(DartEntry.PARSED_UNIT, CacheState.FLUSHED);
-    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, librarySource, unit);
-    entry.invalidateAllResolutionInformation(false);
-    CompilationUnit resolvableUnit = entry.resolvableCompilationUnit;
-    expect(resolvableUnit, isNotNull);
-    expect(resolvableUnit.element, isNull);
-    expect(entry.resolvableCompilationUnit, isNull);
-  }
-
-  void test_setState_element() {
-    _setState(DartEntry.ELEMENT);
-  }
-
-  void test_setState_exportedLibraries() {
-    _setState(DartEntry.EXPORTED_LIBRARIES);
-  }
-
-  void test_setState_hints() {
-    _setStateInLibrary(DartEntry.HINTS);
-  }
-
-  void test_setState_importedLibraries() {
-    _setState(DartEntry.IMPORTED_LIBRARIES);
-  }
-
-  void test_setState_includedParts() {
-    _setState(DartEntry.INCLUDED_PARTS);
-  }
-
-  void test_setState_invalid_element() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setStateInLibrary(DartEntry.ELEMENT, null, CacheState.FLUSHED);
-      fail("Expected ArgumentError for ELEMENT");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_setState_invalid_resolutionErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setState(DartEntry.RESOLUTION_ERRORS, CacheState.FLUSHED);
-      fail("Expected ArgumentError for RESOLUTION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_setState_invalid_validState() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setState(SourceEntry.LINE_INFO, CacheState.VALID);
-      fail("Expected ArgumentError for a state of VALID");
-    } on ArgumentError {}
-  }
-
-  void test_setState_invalid_verificationErrors() {
-    DartEntry entry = new DartEntry();
-    try {
-      entry.setState(DartEntry.VERIFICATION_ERRORS, CacheState.FLUSHED);
-      fail("Expected ArgumentError for VERIFICATION_ERRORS");
-    } on ArgumentError {
-      // Expected
-    }
-  }
-
-  void test_setState_isClient() {
-    _setState(DartEntry.IS_CLIENT);
-  }
-
-  void test_setState_isLaunchable() {
-    _setState(DartEntry.IS_LAUNCHABLE);
-  }
-
-  void test_setState_lineInfo() {
-    _setState(SourceEntry.LINE_INFO);
-  }
-
-  void test_setState_parsedUnit() {
-    _setState(DartEntry.PARSED_UNIT);
-  }
-
-  void test_setState_parseErrors() {
-    _setState(DartEntry.PARSE_ERRORS);
-  }
-
-  void test_setState_publicNamespace() {
-    _setState(DartEntry.PUBLIC_NAMESPACE);
-  }
-
-  void test_setState_resolutionErrors() {
-    _setStateInLibrary(DartEntry.RESOLUTION_ERRORS);
-  }
-
-  void test_setState_resolvedUnit() {
-    _setStateInLibrary(DartEntry.RESOLVED_UNIT);
-  }
-
-  void test_setState_scanErrors() {
-    _setState(DartEntry.SCAN_ERRORS);
-  }
-
-  void test_setState_sourceKind() {
-    _setState(DartEntry.SOURCE_KIND);
-  }
-
-  void test_setState_tokenStream() {
-    _setState(DartEntry.TOKEN_STREAM);
-  }
-
-  void test_setState_verificationErrors() {
-    _setStateInLibrary(DartEntry.VERIFICATION_ERRORS);
-  }
-
-  void test_setValue_element() {
-    _setValue(
-        DartEntry.ELEMENT,
-        new LibraryElementImpl.forNode(
-            null, AstFactory.libraryIdentifier2(["lib"])));
-  }
-
-  void test_setValue_exportedLibraries() {
-    _setValue(DartEntry.EXPORTED_LIBRARIES, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_hints() {
-    _setValueInLibrary(DartEntry.HINTS,
-        <AnalysisError>[new AnalysisError(null, 0, 0, HintCode.DEAD_CODE)]);
-  }
-
-  void test_setValue_importedLibraries() {
-    _setValue(DartEntry.IMPORTED_LIBRARIES, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_includedParts() {
-    _setValue(DartEntry.INCLUDED_PARTS, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_isClient() {
-    _setValue(DartEntry.IS_CLIENT, true);
-  }
-
-  void test_setValue_isLaunchable() {
-    _setValue(DartEntry.IS_LAUNCHABLE, true);
-  }
-
-  void test_setValue_lineInfo() {
-    _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
-  }
-
-  void test_setValue_parsedUnit() {
-    _setValue(DartEntry.PARSED_UNIT, AstFactory.compilationUnit());
-  }
-
-  void test_setValue_parseErrors() {
-    _setValue(DartEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, ParserErrorCode.ABSTRACT_CLASS_MEMBER)
-    ]);
-  }
-
-  void test_setValue_publicNamespace() {
-    _setValue(DartEntry.PUBLIC_NAMESPACE,
-        new Namespace(new HashMap<String, Element>()));
-  }
-
-  void test_setValue_resolutionErrors() {
-    _setValueInLibrary(DartEntry.RESOLUTION_ERRORS, <AnalysisError>[
-      new AnalysisError(
-          null, 0, 0, CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION)
-    ]);
-  }
-
-  void test_setValue_resolvedUnit() {
-    _setValueInLibrary(DartEntry.RESOLVED_UNIT, AstFactory.compilationUnit());
-  }
-
-  void test_setValue_scanErrors() {
-    _setValue(DartEntry.SCAN_ERRORS, <AnalysisError>[
-      new AnalysisError(
-          null, 0, 0, ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT)
-    ]);
-  }
-
-  void test_setValue_sourceKind() {
-    _setValue(DartEntry.SOURCE_KIND, SourceKind.LIBRARY);
-  }
-
-  void test_setValue_tokenStream() {
-    _setValue(DartEntry.TOKEN_STREAM, new Token(TokenType.LT, 5));
-  }
-
-  void test_setValue_verificationErrors() {
-    _setValueInLibrary(DartEntry.VERIFICATION_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, StaticWarningCode.CASE_BLOCK_NOT_TERMINATED)
-    ]);
-  }
-
-  DartEntry _entryWithValidState([Source firstLibrary, Source secondLibrary]) {
-    DartEntry entry = new DartEntry();
-    entry.setValue(SourceEntry.CONTENT, null);
-    entry.setValue(SourceEntry.CONTENT_ERRORS, null);
-    entry.setValue(SourceEntry.LINE_INFO, null);
-    entry.setValue(DartEntry.CONTAINING_LIBRARIES, null);
-    entry.setValue(DartEntry.ELEMENT, null);
-    entry.setValue(DartEntry.EXPORTED_LIBRARIES, null);
-    entry.setValue(DartEntry.IMPORTED_LIBRARIES, null);
-    entry.setValue(DartEntry.INCLUDED_PARTS, null);
-    entry.setValue(DartEntry.IS_CLIENT, null);
-    entry.setValue(DartEntry.IS_LAUNCHABLE, null);
-    entry.setValue(DartEntry.PARSE_ERRORS, null);
-    entry.setValue(DartEntry.PARSED_UNIT, null);
-    entry.setValue(DartEntry.PUBLIC_NAMESPACE, null);
-    entry.setValue(DartEntry.SCAN_ERRORS, null);
-    entry.setValue(DartEntry.SOURCE_KIND, null);
-    entry.setValue(DartEntry.TOKEN_STREAM, null);
-    if (firstLibrary != null) {
-      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.BUILT_UNIT, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.HINTS, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary, null);
-      entry.setValueInLibrary(
-          DartEntry.VERIFICATION_ERRORS, firstLibrary, null);
-    }
-    if (secondLibrary != null) {
-      entry.setValueInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.BUILT_UNIT, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.HINTS, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary, null);
-      entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary, null);
-      entry.setValueInLibrary(
-          DartEntry.VERIFICATION_ERRORS, secondLibrary, null);
-    }
-    //
-    // Validate that the state was set correctly.
-    //
-    expect(entry.getState(SourceEntry.CONTENT), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.CONTENT_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.CONTAINING_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.ELEMENT), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.EXPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(DartEntry.IMPORTED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.INCLUDED_PARTS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_CLIENT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.IS_LAUNCHABLE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.PUBLIC_NAMESPACE), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SCAN_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.SOURCE_KIND), same(CacheState.VALID));
-    expect(entry.getState(DartEntry.TOKEN_STREAM), same(CacheState.VALID));
-    if (firstLibrary != null) {
-      expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.HINTS, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, firstLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, firstLibrary),
-          same(CacheState.VALID));
-      expect(
-          entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, firstLibrary),
-          same(CacheState.VALID));
-    }
-    if (secondLibrary != null) {
-      expect(entry.getStateInLibrary(DartEntry.BUILT_ELEMENT, secondLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.BUILT_UNIT, secondLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.HINTS, secondLibrary),
-          same(CacheState.VALID));
-      expect(
-          entry.getStateInLibrary(DartEntry.RESOLUTION_ERRORS, secondLibrary),
-          same(CacheState.VALID));
-      expect(entry.getStateInLibrary(DartEntry.RESOLVED_UNIT, secondLibrary),
-          same(CacheState.VALID));
-      expect(
-          entry.getStateInLibrary(DartEntry.VERIFICATION_ERRORS, secondLibrary),
-          same(CacheState.VALID));
-    }
-    return entry;
-  }
-
-  void _setState(DataDescriptor descriptor) {
-    DartEntry entry = new DartEntry();
-    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
-    entry.setState(descriptor, CacheState.FLUSHED);
-    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
-  }
-
-  void _setStateInLibrary(DataDescriptor descriptor) {
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
-    expect(entry.getStateInLibrary(descriptor, source),
-        isNot(same(CacheState.FLUSHED)));
-    entry.setStateInLibrary(descriptor, source, CacheState.FLUSHED);
-    expect(
-        entry.getStateInLibrary(descriptor, source), same(CacheState.FLUSHED));
-  }
-
-  void _setValue(DataDescriptor descriptor, Object newValue) {
-    DartEntry entry = new DartEntry();
-    Object value = entry.getValue(descriptor);
-    expect(newValue, isNot(same(value)));
-    entry.setValue(descriptor, newValue);
-    expect(entry.getState(descriptor), same(CacheState.VALID));
-    expect(entry.getValue(descriptor), same(newValue));
-  }
-
-  void _setValueInLibrary(DataDescriptor descriptor, Object newValue) {
-    Source source = new TestSource();
-    DartEntry entry = new DartEntry();
-    Object value = entry.getValueInLibrary(descriptor, source);
-    expect(newValue, isNot(same(value)));
-    entry.setValueInLibrary(descriptor, source, newValue);
-    expect(entry.getStateInLibrary(descriptor, source), same(CacheState.VALID));
-    expect(entry.getValueInLibrary(descriptor, source), same(newValue));
-  }
-}
-
-@reflectiveTest
-class GenerateDartErrorsTaskTest extends EngineTestCase {
-  void test_accept() {
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(null, null, null, null);
-    expect(task.accept(new GenerateDartErrorsTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(null, null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLibraryElement() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElement element = ElementFactory.library(context, "lib");
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(context, null, null, element);
-    expect(task.libraryElement, same(element));
-  }
-
-  void test_getSource() {
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(null, source, null, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    context.applyChanges(changeSet);
-    context.setContents(
-        source,
-        r'''
-library lib;
-class A {
-  int f = new A();
-}''');
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnit unit =
-        context.getResolvedCompilationUnit(source, libraryElement);
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(context, source, unit, libraryElement);
-    task.perform(
-        new GenerateDartErrorsTaskTestTV_perform(libraryElement, source));
-  }
-
-  void test_perform_validateDirectives() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.addedSource(source);
-    context.applyChanges(changeSet);
-    // TODO(scheglov) "import" causes second error reported
-//    context.setContents(source, EngineTestCase.createSource([
-//        "library lib;",
-//        "import 'invaliduri^.dart';",
-//        "export '\${a}lib3.dart';",
-//        "part '/does/not/exist.dart';",
-//        "class A {}"]));
-    context.setContents(
-        source,
-        r'''
-library lib;
-part '/does/not/exist.dart';
-class A {}''');
-    LibraryElement libraryElement = context.computeLibraryElement(source);
-    CompilationUnit unit =
-        context.getResolvedCompilationUnit(source, libraryElement);
-    GenerateDartErrorsTask task =
-        new GenerateDartErrorsTask(context, source, unit, libraryElement);
-    task.perform(new GenerateDartErrorsTaskTestTV_perform_validateDirectives(
-        libraryElement, source));
-  }
-}
-
-class GenerateDartErrorsTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) => true;
-}
-
-class GenerateDartErrorsTaskTestTV_perform extends TestTaskVisitor<bool> {
-  LibraryElement libraryElement;
-  Source source;
-  GenerateDartErrorsTaskTestTV_perform(this.libraryElement, this.source);
-  @override
-  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, same(libraryElement));
-    expect(task.source, same(source));
-    List<AnalysisError> errors = task.errors;
-    expect(errors, hasLength(1));
-    return true;
-  }
-}
-
-class GenerateDartErrorsTaskTestTV_perform_validateDirectives
-    extends TestTaskVisitor<bool> {
-  LibraryElement libraryElement;
-  Source source;
-  GenerateDartErrorsTaskTestTV_perform_validateDirectives(
-      this.libraryElement, this.source);
-  @override
-  bool visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, same(libraryElement));
-    expect(task.source, same(source));
-    List<AnalysisError> errors = task.errors;
-    expect(errors, hasLength(1));
-    expect(errors[0].errorCode, same(CompileTimeErrorCode.URI_DOES_NOT_EXIST));
-    return true;
-  }
-}
-
-@reflectiveTest
-class GenerateDartHintsTaskTest extends EngineTestCase {
-  void test_accept() {
-    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
-    expect(task.accept(new GenerateDartHintsTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getHintMap() {
-    GenerateDartHintsTask task = new GenerateDartHintsTask(null, null, null);
-    expect(task.hintMap, isNull);
-  }
-
-  void test_getLibraryElement() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElement element = ElementFactory.library(context, "lib");
-    GenerateDartHintsTask task =
-        new GenerateDartHintsTask(context, null, element);
-    expect(task.libraryElement, same(element));
-  }
-
-  void test_perform() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    Source unusedSource =
-        new FileBasedSource(FileUtilities2.createFile("/unused.dart"));
-    changeSet.addedSource(unusedSource);
-    Source partSource =
-        new FileBasedSource(FileUtilities2.createFile("/part.dart"));
-    changeSet.addedSource(partSource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-import 'unused.dart';
-part 'part.dart';''');
-    context.setContents(unusedSource, "library unused;");
-    context.setContents(partSource, "part of lib;");
-    List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(2);
-    units[0] = new TimestampedData<CompilationUnit>(
-        context.getModificationStamp(librarySource),
-        context.resolveCompilationUnit2(librarySource, librarySource));
-    units[1] = new TimestampedData<CompilationUnit>(
-        context.getModificationStamp(partSource),
-        context.resolveCompilationUnit2(partSource, librarySource));
-    GenerateDartHintsTask task = new GenerateDartHintsTask(
-        context, units, context.computeLibraryElement(librarySource));
-    task.perform(
-        new GenerateDartHintsTaskTestTV_perform(librarySource, partSource));
-  }
-}
-
-class GenerateDartHintsTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGenerateDartHintsTask(GenerateDartHintsTask task) => true;
-}
-
-class GenerateDartHintsTaskTestTV_perform extends TestTaskVisitor<bool> {
-  Source librarySource;
-  Source partSource;
-  GenerateDartHintsTaskTestTV_perform(this.librarySource, this.partSource);
-  @override
-  bool visitGenerateDartHintsTask(GenerateDartHintsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, isNotNull);
-    HashMap<Source, List<AnalysisError>> hintMap = task.hintMap;
-    expect(hintMap, hasLength(2));
-    expect(hintMap[librarySource], hasLength(1));
-    expect(hintMap[partSource], hasLength(0));
-    return true;
-  }
-}
-
-@reflectiveTest
-class GenerateDartLintsTaskTest extends EngineTestCase {
-  void test_accept() {
-    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
-    expect(task.accept(new GenerateDartLintsTaskTestTV_accept()), isTrue);
-  }
-
-  void test_exception() {
-    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_libraryElement() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElement element = ElementFactory.library(context, "lib");
-    GenerateDartLintsTask task =
-        new GenerateDartLintsTask(context, null, element);
-    expect(task.libraryElement, same(element));
-  }
-
-  void test_lintMap() {
-    GenerateDartLintsTask task = new GenerateDartLintsTask(null, null, null);
-    expect(task.lintMap, isNull);
-  }
-
-  void test_perform() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-''');
-    List<TimestampedData<CompilationUnit>> units = new List<TimestampedData>(1);
-    units[0] = new TimestampedData<CompilationUnit>(
-        context.getModificationStamp(librarySource),
-        context.resolveCompilationUnit2(librarySource, librarySource));
-    GenerateDartLintsTask task = new GenerateDartLintsTask(
-        context, units, context.computeLibraryElement(librarySource));
-    task.perform(new GenerateDartLintsTaskTestTV_perform(librarySource));
-  }
-}
-
-class GenerateDartLintsTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGenerateDartLintsTask(GenerateDartLintsTask task) => true;
-}
-
-class GenerateDartLintsTaskTestTV_perform extends TestTaskVisitor<bool> {
-  Source librarySource;
-  GenerateDartLintsTaskTestTV_perform(this.librarySource);
-  @override
-  bool visitGenerateDartLintsTask(GenerateDartLintsTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryElement, isNotNull);
-    return true;
-  }
-}
-
-@reflectiveTest
-class GetContentTaskTest extends EngineTestCase {
-  void test_accept() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.accept(new GetContentTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.exception, isNull);
-  }
-
-  void test_getModificationTime() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.modificationTime, -1);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart', '');
-    GetContentTask task = new GetContentTask(null, source);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_exception() {
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    //    final InternalAnalysisContext context = new AnalysisContextImpl();
-    //    context.setSourceFactory(new SourceFactory(new FileUriResolver()));
-    GetContentTask task = new GetContentTask(null, source);
-    task.perform(new GetContentTaskTestTV_perform_exception());
-  }
-
-  void test_perform_valid() {
-    Source source = new TestSource('/test.dart', 'class A {}');
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    GetContentTask task = new GetContentTask(context, source);
-    task.perform(new GetContentTaskTestTV_perform_valid(context, source));
-  }
-}
-
-class GetContentTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitGetContentTask(GetContentTask task) => true;
-}
-
-class GetContentTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
-  @override
-  bool visitGetContentTask(GetContentTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class GetContentTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
-  InternalAnalysisContext context;
-  Source source;
-  GetContentTaskTestTV_perform_valid(this.context, this.source);
-  @override
-  bool visitGetContentTask(GetContentTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.modificationTime, context.getModificationStamp(source));
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class HtmlEntryTest extends EngineTestCase {
-  void set state(DataDescriptor descriptor) {
-    HtmlEntry entry = new HtmlEntry();
-    expect(entry.getState(descriptor), isNot(same(CacheState.FLUSHED)));
-    entry.setState(descriptor, CacheState.FLUSHED);
-    expect(entry.getState(descriptor), same(CacheState.FLUSHED));
-  }
-
-  void test_creation() {
-    HtmlEntry entry = new HtmlEntry();
-    expect(entry, isNotNull);
-  }
-
-  void test_getAllErrors() {
-    Source source = new TestSource();
-    HtmlEntry entry = new HtmlEntry();
-    expect(entry.allErrors, hasLength(0));
-    entry.setValue(HtmlEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, ParserErrorCode.EXPECTED_TOKEN, [";"])
-    ]);
-    entry.setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
-      new AnalysisError(source, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
-    ]);
-    entry.setValue(HtmlEntry.HINTS,
-        <AnalysisError>[new AnalysisError(source, 0, 0, HintCode.DEAD_CODE)]);
-    expect(entry.allErrors, hasLength(3));
-  }
-
-  void test_invalidateAllResolutionInformation() {
-    HtmlEntry entry = _entryWithValidState();
-    entry.invalidateAllResolutionInformation(false);
-    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(HtmlEntry.REFERENCED_LIBRARIES), same(CacheState.VALID));
-    expect(
-        entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.INVALID));
-  }
-
-  void test_invalidateAllResolutionInformation_includingUris() {
-    HtmlEntry entry = _entryWithValidState();
-    entry.invalidateAllResolutionInformation(true);
-    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.INVALID));
-    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.INVALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.REFERENCED_LIBRARIES),
-        same(CacheState.INVALID));
-    expect(
-        entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.INVALID));
-  }
-
-  void test_setState_element() {
-    state = HtmlEntry.ELEMENT;
-  }
-
-  void test_setState_hints() {
-    state = HtmlEntry.HINTS;
-  }
-
-  void test_setState_lineInfo() {
-    state = SourceEntry.LINE_INFO;
-  }
-
-  void test_setState_parsedUnit() {
-    state = HtmlEntry.PARSED_UNIT;
-  }
-
-  void test_setState_parseErrors() {
-    state = HtmlEntry.PARSE_ERRORS;
-  }
-
-  void test_setState_referencedLibraries() {
-    state = HtmlEntry.REFERENCED_LIBRARIES;
-  }
-
-  void test_setState_resolutionErrors() {
-    state = HtmlEntry.RESOLUTION_ERRORS;
-  }
-
-  void test_setValue_element() {
-    _setValue(HtmlEntry.ELEMENT, new HtmlElementImpl(null, "test.html"));
-  }
-
-  void test_setValue_hints() {
-    _setValue(HtmlEntry.HINTS,
-        <AnalysisError>[new AnalysisError(null, 0, 0, HintCode.DEAD_CODE)]);
-  }
-
-  void test_setValue_illegal() {
-    HtmlEntry entry = new HtmlEntry();
-    try {
-      entry.setValue(DartEntry.ELEMENT, null);
-      fail("Expected ArgumentError for DartEntry.ELEMENT");
-    } on ArgumentError {}
-  }
-
-  void test_setValue_lineInfo() {
-    _setValue(SourceEntry.LINE_INFO, new LineInfo(<int>[0]));
-  }
-
-  void test_setValue_parsedUnit() {
-    _setValue(HtmlEntry.PARSED_UNIT, new ht.HtmlUnit(null, null, null));
-  }
-
-  void test_setValue_parseErrors() {
-    _setValue(HtmlEntry.PARSE_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
-    ]);
-  }
-
-  void test_setValue_referencedLibraries() {
-    _setValue(HtmlEntry.REFERENCED_LIBRARIES, <Source>[new TestSource()]);
-  }
-
-  void test_setValue_resolutionErrors() {
-    _setValue(HtmlEntry.RESOLUTION_ERRORS, <AnalysisError>[
-      new AnalysisError(null, 0, 0, HtmlWarningCode.INVALID_URI, ["-"])
-    ]);
-  }
-
-  HtmlEntry _entryWithValidState() {
-    HtmlEntry entry = new HtmlEntry();
-    entry.setValue(HtmlEntry.ELEMENT, null);
-    entry.setValue(HtmlEntry.HINTS, null);
-    entry.setValue(SourceEntry.LINE_INFO, null);
-    entry.setValue(HtmlEntry.PARSE_ERRORS, null);
-    entry.setValue(HtmlEntry.PARSED_UNIT, null);
-    entry.setValue(HtmlEntry.REFERENCED_LIBRARIES, null);
-    entry.setValue(HtmlEntry.RESOLUTION_ERRORS, null);
-    expect(entry.getState(HtmlEntry.ELEMENT), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.HINTS), same(CacheState.VALID));
-    expect(entry.getState(SourceEntry.LINE_INFO), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSE_ERRORS), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.PARSED_UNIT), same(CacheState.VALID));
-    expect(
-        entry.getState(HtmlEntry.REFERENCED_LIBRARIES), same(CacheState.VALID));
-    expect(entry.getState(HtmlEntry.RESOLUTION_ERRORS), same(CacheState.VALID));
-    return entry;
-  }
-
-  void _setValue(DataDescriptor descriptor, Object newValue) {
-    HtmlEntry entry = new HtmlEntry();
-    Object value = entry.getValue(descriptor);
-    expect(newValue, isNot(same(value)));
-    entry.setValue(descriptor, newValue);
-    expect(entry.getState(descriptor), same(CacheState.VALID));
-    expect(entry.getValue(descriptor), same(newValue));
-  }
-}
-
-@reflectiveTest
-class IncrementalAnalysisCacheTest {
-  Source _source = new TestSource();
-  DartEntry _entry = new DartEntry();
-  CompilationUnit _unit = new CompilationUnitMock();
-  IncrementalAnalysisCache _result;
-  void setUp() {
-    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, _unit);
-  }
-
-  void test_cacheResult() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = new CompilationUnitMock();
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(newUnit));
-    expect(_result.oldContents, "hbazlo");
-    expect(_result.newContents, "hbazlo");
-    expect(_result.offset, 0);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 0);
-  }
-
-  void test_cacheResult_noCache() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = new CompilationUnitMock();
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_cacheResult_noCacheNoResult() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_cacheResult_noResult() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_clear_differentSource() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    Source otherSource = new TestSource("blat.dart", "blat");
-    _result = IncrementalAnalysisCache.clear(cache, otherSource);
-    expect(_result, same(cache));
-  }
-
-  void test_clear_nullCache() {
-    IncrementalAnalysisCache cache = null;
-    _result = IncrementalAnalysisCache.clear(cache, _source);
-    expect(_result, isNull);
-  }
-
-  void test_clear_sameSource() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    _result = IncrementalAnalysisCache.clear(cache, _source);
-    expect(_result, isNull);
-  }
-
-  void test_update_append() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 4);
-  }
-
-  void test_update_appendToCachedResult() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = new CompilationUnitMock();
-    cache = IncrementalAnalysisCache.cacheResult(cache, newUnit);
-    expect(cache, isNotNull);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(newUnit));
-    expect(_result.oldContents, "hbazlo");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 4);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 1);
-  }
-
-  void test_update_appendWithNewResolvedUnit() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    CompilationUnit newUnit = new CompilationUnitMock();
-    newEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, newUnit);
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(newUnit));
-    expect(_result.oldContents, "hbazlo");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 4);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 1);
-  }
-
-  void test_update_appendWithNoNewResolvedUnit() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazxlo", 4, 0, 1, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbazxlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 4);
-  }
-
-  void test_update_delete() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hzlo", 1, 2, 0, newEntry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hzlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 1);
-  }
-
-  void test_update_insert_nonContiguous_after() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbazlox", 6, 0, 1, newEntry);
-    expect(_result, isNull);
-  }
-
-  void test_update_insert_nonContiguous_before() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    DartEntry newEntry = new DartEntry();
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "xhbazlo", 0, 0, 1, newEntry);
-    expect(_result, isNull);
-  }
-
-  void test_update_newSource_entry() {
-    Source oldSource = new TestSource("blat.dart", "blat");
-    DartEntry oldEntry = new DartEntry();
-    CompilationUnit oldUnit = new CompilationUnitMock();
-    oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, oldSource, "hello", "hbazlo", 1, 2, 3, oldEntry);
-    expect(cache.source, same(oldSource));
-    expect(cache.resolvedUnit, same(oldUnit));
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "foo", "foobz", 3, 0, 2, _entry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "foo");
-    expect(_result.newContents, "foobz");
-    expect(_result.offset, 3);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 2);
-  }
-
-  void test_update_newSource_noEntry() {
-    Source oldSource = new TestSource("blat.dart", "blat");
-    DartEntry oldEntry = new DartEntry();
-    CompilationUnit oldUnit = new CompilationUnitMock();
-    oldEntry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, oldUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, oldSource, "hello", "hbazlo", 1, 2, 3, oldEntry);
-    expect(cache.source, same(oldSource));
-    expect(cache.resolvedUnit, same(oldUnit));
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "foo", "foobar", 3, 0, 3, null);
-    expect(_result, isNull);
-  }
-
-  void test_update_noCache_entry() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbazlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 3);
-    expect(_result.hasWork, isTrue);
-  }
-
-  void test_update_noCache_entry_noOldSource_append() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, null, "hellxo", 4, 0, 1, _entry);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hellxo");
-    expect(_result.offset, 4);
-    expect(_result.oldLength, 0);
-    expect(_result.newLength, 1);
-    expect(_result.hasWork, isTrue);
-  }
-
-  void test_update_noCache_entry_noOldSource_delete() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, null, "helo", 4, 1, 0, _entry);
-    expect(_result, isNull);
-  }
-
-  void test_update_noCache_entry_noOldSource_replace() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, null, "helxo", 4, 1, 1, _entry);
-    expect(_result, isNull);
-  }
-
-  void test_update_noCache_noEntry() {
-    _result = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, null);
-    expect(_result, isNull);
-  }
-
-  void test_update_replace() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    _result = IncrementalAnalysisCache.update(
-        cache, _source, "hbazlo", "hbarrlo", 3, 1, 2, null);
-    expect(_result, isNotNull);
-    expect(_result.source, same(_source));
-    expect(_result.resolvedUnit, same(_unit));
-    expect(_result.oldContents, "hello");
-    expect(_result.newContents, "hbarrlo");
-    expect(_result.offset, 1);
-    expect(_result.oldLength, 2);
-    expect(_result.newLength, 4);
-  }
-
-  void test_verifyStructure_invalidUnit() {
-    String oldCode = "main() {foo;}";
-    String newCode = "main() {boo;}";
-    CompilationUnit badUnit = _parse("main() {bad;}");
-    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, badUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, oldCode, newCode, 8, 1, 1, _entry);
-    CompilationUnit newUnit = _parse(newCode);
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_verifyStructure_noCache() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = new CompilationUnitMock();
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_verifyStructure_noCacheNoUnit() {
-    IncrementalAnalysisCache cache = null;
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, isNull);
-  }
-
-  void test_verifyStructure_noUnit() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = null;
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, same(cache));
-    expect(_result.resolvedUnit, same(_unit));
-  }
-
-  void test_verifyStructure_otherSource() {
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, "hello", "hbazlo", 1, 2, 3, _entry);
-    CompilationUnit newUnit = new CompilationUnitMock();
-    Source otherSource = new TestSource("blat.dart", "blat");
-    _result =
-        IncrementalAnalysisCache.verifyStructure(cache, otherSource, newUnit);
-    expect(_result, same(cache));
-    expect(_result.resolvedUnit, same(_unit));
-  }
-
-  void test_verifyStructure_validUnit() {
-    String oldCode = "main() {foo;}";
-    String newCode = "main() {boo;}";
-    CompilationUnit goodUnit = _parse(newCode);
-    _entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, _source, goodUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null, _source, oldCode, newCode, 1, 2, 3, _entry);
-    CompilationUnit newUnit = _parse(newCode);
-    _result = IncrementalAnalysisCache.verifyStructure(cache, _source, newUnit);
-    expect(_result, same(cache));
-    expect(_result.resolvedUnit, same(goodUnit));
-  }
-
-  CompilationUnit _parse(String code) {
-    Scanner scanner = new Scanner(_source, new CharSequenceReader(code),
-        AnalysisErrorListener.NULL_LISTENER);
-    Parser parser = new Parser(_source, AnalysisErrorListener.NULL_LISTENER);
-    return parser.parseCompilationUnit(scanner.tokenize());
-  }
-}
-
-@reflectiveTest
-class IncrementalAnalysisTaskTest extends EngineTestCase {
-  void test_accept() {
-    IncrementalAnalysisTask task = new IncrementalAnalysisTask(null, null);
-    expect(task.accept(new IncrementalAnalysisTaskTestTV_accept()), isTrue);
-  }
-
-  void test_perform() {
-    // main() {} String foo;
-    // main() {String} String foo;
-    CompilationUnit newUnit =
-        _assertTask("main() {", "", "String", "} String foo;");
-    NodeList<CompilationUnitMember> declarations = newUnit.declarations;
-    FunctionDeclaration main = declarations[0] as FunctionDeclaration;
-    expect(main.name.name, "main");
-    BlockFunctionBody body = main.functionExpression.body as BlockFunctionBody;
-    ExpressionStatement statement =
-        body.block.statements[0] as ExpressionStatement;
-    expect(statement.toSource(), "String;");
-    SimpleIdentifier identifier = statement.expression as SimpleIdentifier;
-    expect(identifier.name, "String");
-    expect(identifier.staticElement, isNotNull);
-    TopLevelVariableDeclaration fooDecl =
-        declarations[1] as TopLevelVariableDeclaration;
-    SimpleIdentifier fooName = fooDecl.variables.variables[0].name;
-    expect(fooName.name, "foo");
-    expect(fooName.staticElement, isNotNull);
-    // assert element reference is preserved
-  }
-
-  CompilationUnit _assertTask(
-      String prefix, String removed, String added, String suffix) {
-    String oldCode = "$prefix$removed$suffix";
-    String newCode = "$prefix$added$suffix";
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source = new TestSource("/test.dart", oldCode);
-    DartEntry entry = new DartEntry();
-    CompilationUnit oldUnit = context.resolveCompilationUnit2(source, source);
-    expect(oldUnit, isNotNull);
-    entry.setValueInLibrary(DartEntry.RESOLVED_UNIT, source, oldUnit);
-    IncrementalAnalysisCache cache = IncrementalAnalysisCache.update(
-        null,
-        source,
-        oldCode,
-        newCode,
-        prefix.length,
-        removed.length,
-        added.length,
-        entry);
-    expect(cache, isNotNull);
-    IncrementalAnalysisTask task = new IncrementalAnalysisTask(context, cache);
-    CompilationUnit newUnit =
-        task.perform(new IncrementalAnalysisTaskTestTV_assertTask(task));
-    expect(newUnit, isNotNull);
-    return newUnit;
-  }
-}
-
-class IncrementalAnalysisTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitIncrementalAnalysisTask(IncrementalAnalysisTask task) => true;
-}
-
-class IncrementalAnalysisTaskTestTV_assertTask
-    extends TestTaskVisitor<CompilationUnit> {
-  IncrementalAnalysisTask task;
-  IncrementalAnalysisTaskTestTV_assertTask(this.task);
-  @override
-  CompilationUnit visitIncrementalAnalysisTask(
-          IncrementalAnalysisTask incrementalAnalysisTask) =>
-      task.compilationUnit;
-}
-
-@reflectiveTest
-class LintGeneratorTest extends EngineTestCase {
-  void test_generate() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-''');
-
-    CompilationUnit unit =
-        context.resolveCompilationUnit2(librarySource, librarySource);
-    List<CompilationUnit> units = <CompilationUnit>[];
-    units.add(unit);
-
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-
-    LintGeneratorTest_Linter linter = new LintGeneratorTest_Linter();
-
-    LintGenerator lintGenerator =
-        new LintGenerator(units, errorListener, [linter]);
-    lintGenerator.generate();
-
-    linter.testExpectations();
-  }
-
-  void test_generate_null_visitor() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ChangeSet changeSet = new ChangeSet();
-    Source librarySource =
-        new FileBasedSource(FileUtilities2.createFile("/test.dart"));
-    changeSet.addedSource(librarySource);
-    context.applyChanges(changeSet);
-    context.setContents(
-        librarySource,
-        r'''
-library lib;
-''');
-
-    CompilationUnit unit =
-        context.resolveCompilationUnit2(librarySource, librarySource);
-    List<CompilationUnit> units = <CompilationUnit>[];
-    units.add(unit);
-
-    RecordingErrorListener errorListener = new RecordingErrorListener();
-
-    Linter badLinter = new LintGeneratorTest_Linter_Null_Visitor();
-    LintGeneratorTest_Linter goodLinter = new LintGeneratorTest_Linter();
-
-    LintGenerator lintGenerator =
-        new LintGenerator(units, errorListener, [badLinter, goodLinter]);
-    // Test that generate does not fall down with a null visitor
-    lintGenerator.generate();
-    // Well-formed linter should still get called
-    goodLinter.testExpectations();
-  }
-}
-
-class LintGeneratorTest_Linter extends Linter with SimpleAstVisitor<Object> {
-  bool visited;
-
-  @override
-  AstVisitor getVisitor() => this;
-
-  testExpectations() {
-    expect(reporter, isNotNull);
-    expect(visited, isTrue);
-  }
-
-  @override
-  Object visitCompilationUnit(CompilationUnit node) {
-    visited = true;
-    return null;
-  }
-}
-
-class LintGeneratorTest_Linter_Null_Visitor extends Linter {
-  @override
-  AstVisitor getVisitor() => null;
-}
+class CompilationUnitMock extends TypedMock implements CompilationUnit {}
 
 class MockSourceFactory extends SourceFactory {
   MockSourceFactory() : super([]);
@@ -4803,773 +82,6 @@
 }
 
 @reflectiveTest
-class ParseDartTaskTest extends EngineTestCase {
-  void test_accept() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.accept(new ParseDartTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getCompilationUnit() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.compilationUnit, isNull);
-  }
-
-  void test_getErrors() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.errors, hasLength(0));
-  }
-
-  void test_getException() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart');
-    ParseDartTask task = new ParseDartTask(null, source, null, null);
-    expect(task.source, same(source));
-  }
-
-  void test_hasNonPartOfDirective() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.hasNonPartOfDirective, isFalse);
-  }
-
-  void test_hasPartOfDirective() {
-    ParseDartTask task = new ParseDartTask(null, null, null, null);
-    expect(task.hasPartOfDirective, isFalse);
-  }
-
-  void test_perform_exception() {
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = new ParseDartTask(context, source, null, null);
-    task.perform(new ParseDartTaskTestTV_perform_exception());
-  }
-
-  void test_perform_library() {
-    String content = r'''
-library lib;
-import 'lib2.dart';
-export 'lib3.dart';
-part 'part.dart';
-class A {''';
-    Source source = new TestSource('/test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = _createParseTask(context, source, content);
-    task.perform(new ParseDartTaskTestTV_perform_library(context, source));
-  }
-
-  void test_perform_part() {
-    String content = r'''
-part of lib;
-class B {}''';
-    Source source = new TestSource('/test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = _createParseTask(context, source, content);
-    task.perform(new ParseDartTaskTestTV_perform_part(context, source));
-  }
-
-  void test_perform_validateDirectives() {
-    String content = r'''
-library lib;
-import '/does/not/exist.dart';
-import '://invaliduri.dart';
-export '${a}lib3.dart';
-part 'part.dart';
-class A {}''';
-    Source source = new TestSource('/test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseDartTask task = _createParseTask(context, source, content);
-    task.perform(
-        new ParseDartTaskTestTV_perform_validateDirectives(context, source));
-  }
-
-  void test_resolveDirective_dartUri() {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ImportDirective directive = AstFactory.importDirective3('dart:core', null);
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    Source source =
-        ParseDartTask.resolveDirective(context, null, directive, listener);
-    expect(source, isNotNull);
-  }
-
-  void test_resolveDirective_exception() {
-    GatheringErrorListener listener = new GatheringErrorListener();
-    ImportDirective directive = AstFactory.importDirective3('dart:core', null);
-    AnalysisContext context = AnalysisContextFactory.contextWithCore();
-    context.sourceFactory = new MockSourceFactory();
-    Source source =
-        ParseDartTask.resolveDirective(context, null, directive, listener);
-    expect(source, isNull);
-    expect(listener.errors, hasLength(1));
-  }
-
-  /**
-   * Create and return a task that will parse the given content from the given source in the given
-   * context.
-   *
-   * @param context the context to be passed to the task
-   * @param source the source to be parsed
-   * @param content the content of the source to be parsed
-   * @return the task that was created
-   * @throws AnalysisException if the task could not be created
-   */
-  ParseDartTask _createParseTask(
-      InternalAnalysisContext context, Source source, String content) {
-    ScanDartTask scanTask = new ScanDartTask(context, source, content);
-    scanTask.perform(new ParseDartTaskTestTV_createParseTask());
-    return new ParseDartTask(
-        context, source, scanTask.tokenStream, scanTask.lineInfo);
-  }
-}
-
-class ParseDartTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitParseDartTask(ParseDartTask task) => true;
-}
-
-class ParseDartTaskTestTV_createParseTask extends TestTaskVisitor<Object> {
-  @override
-  Object visitScanDartTask(ScanDartTask task) => null;
-}
-
-class ParseDartTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
-  @override
-  bool visitParseDartTask(ParseDartTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ParseDartTaskTestTV_perform_library extends TestTaskVisitor<Object> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseDartTaskTestTV_perform_library(this.context, this.source);
-  @override
-  Object visitParseDartTask(ParseDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.compilationUnit, isNotNull);
-    expect(task.errors, hasLength(1));
-    expect(task.source, same(source));
-    expect(task.hasNonPartOfDirective, isTrue);
-    expect(task.hasPartOfDirective, isFalse);
-    return null;
-  }
-}
-
-class ParseDartTaskTestTV_perform_part extends TestTaskVisitor<Object> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseDartTaskTestTV_perform_part(this.context, this.source);
-  @override
-  Object visitParseDartTask(ParseDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.compilationUnit, isNotNull);
-    expect(task.errors, hasLength(0));
-    expect(task.source, same(source));
-    expect(task.hasNonPartOfDirective, isFalse);
-    expect(task.hasPartOfDirective, isTrue);
-    return null;
-  }
-}
-
-class ParseDartTaskTestTV_perform_validateDirectives
-    extends TestTaskVisitor<Object> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseDartTaskTestTV_perform_validateDirectives(this.context, this.source);
-  @override
-  Object visitParseDartTask(ParseDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.compilationUnit, isNotNull);
-    GatheringErrorListener errorListener = new GatheringErrorListener();
-    errorListener.addAll(task.errors);
-    errorListener.assertErrorsWithCodes([
-      CompileTimeErrorCode.URI_WITH_INTERPOLATION,
-      CompileTimeErrorCode.INVALID_URI
-    ]);
-    expect(task.source, same(source));
-    expect(task.hasNonPartOfDirective, isTrue);
-    expect(task.hasPartOfDirective, isFalse);
-    return null;
-  }
-}
-
-@reflectiveTest
-class ParseHtmlTaskTest extends EngineTestCase {
-  ParseHtmlTask parseContents(String contents, TestLogger testLogger) {
-    return parseSource(
-        new TestSource('/test.dart', contents), contents, testLogger);
-  }
-
-  ParseHtmlTask parseSource(
-      Source source, String contents, TestLogger testLogger) {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    context.setContents(source, contents);
-    ParseHtmlTask task = new ParseHtmlTask(context, source, contents);
-    Logger oldLogger = AnalysisEngine.instance.logger;
-    try {
-      AnalysisEngine.instance.logger = testLogger;
-      task.perform(new ParseHtmlTaskTestTV_parseSource(context, source));
-    } finally {
-      AnalysisEngine.instance.logger = oldLogger;
-    }
-    return task;
-  }
-
-  void test_accept() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.accept(new ParseHtmlTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.exception, isNull);
-  }
-
-  void test_getHtmlUnit() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.htmlUnit, isNull);
-  }
-
-  void test_getLineInfo() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.lineInfo, isNull);
-  }
-
-  void test_getReferencedLibraries() {
-    ParseHtmlTask task = new ParseHtmlTask(null, null, "");
-    expect(task.referencedLibraries, hasLength(0));
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart');
-    ParseHtmlTask task = new ParseHtmlTask(null, source, "");
-    expect(task.source, same(source));
-  }
-
-  void test_perform_embedded_source() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart'>
-    void buttonPressed() {}
-  </script>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseContents(contents, testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_empty_source_reference() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart' src=''/>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseContents(contents, testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_invalid_source_reference() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart' src='an;invalid:[]uri'/>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseContents(contents, testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_non_existing_source_reference() {
-    String contents = r'''
-<html>
-<head>
-  <script type='application/dart' src='does/not/exist.dart'/>
-</head>
-<body>
-</body>
-</html>''';
-    TestLogger testLogger = new TestLogger();
-    ParseHtmlTask task = parseSource(
-        new ParseHtmlTaskTest_non_existing_source(contents),
-        contents,
-        testLogger);
-    expect(task.referencedLibraries, hasLength(0));
-    expect(testLogger.errorCount, 0);
-    expect(testLogger.infoCount, 0);
-  }
-
-  void test_perform_referenced_source() {
-    // TODO(scheglov) this test fails because we put into cache TestSource
-    // test.dart (and actually should test.html), but resolve
-    // src='test.dart' as a FileBasedSource
-    // We need to switch to a virtual file system and use it everywhere.
-//    String contents = EngineTestCase.createSource([
-//        "<html>",
-//        "<head>",
-//        "  <script type='application/dart' src='test.dart'/>",
-//        "</head>",
-//        "<body>",
-//        "</body>",
-//        "</html>"]);
-//    TestLogger testLogger = new TestLogger();
-//    ParseHtmlTask task = parseContents(contents, testLogger);
-//    EngineTestCase.assertLength(1, task.referencedLibraries);
-//    JUnitTestCase.assertEquals(0, testLogger.errorCount);
-//    JUnitTestCase.assertEquals(0, testLogger.errorCount);
-  }
-}
-
-class ParseHtmlTaskTest_non_existing_source extends TestSource {
-  ParseHtmlTaskTest_non_existing_source(String arg0) : super(arg0);
-  @override
-  Uri resolveRelativeUri(Uri containedUri) {
-    try {
-      return parseUriWithException("file:/does/not/exist.dart");
-    } on URISyntaxException {
-      return null;
-    }
-  }
-}
-
-class ParseHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitParseHtmlTask(ParseHtmlTask task) => true;
-}
-
-class ParseHtmlTaskTestTV_parseSource extends TestTaskVisitor<bool> {
-  InternalAnalysisContext context;
-  Source source;
-  ParseHtmlTaskTestTV_parseSource(this.context, this.source);
-  @override
-  bool visitParseHtmlTask(ParseHtmlTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.htmlUnit, isNotNull);
-    expect(task.lineInfo, isNotNull);
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class PartitionManagerTest extends EngineTestCase {
-  void test_clearCache() {
-    PartitionManager manager = new PartitionManager();
-    DartSdk sdk = new MockDartSdk();
-    SdkCachePartition oldPartition = manager.forSdk(sdk);
-    manager.clearCache();
-    SdkCachePartition newPartition = manager.forSdk(sdk);
-    expect(newPartition, isNot(same(oldPartition)));
-  }
-
-  void test_creation() {
-    expect(new PartitionManager(), isNotNull);
-  }
-
-  void test_forSdk() {
-    PartitionManager manager = new PartitionManager();
-    DartSdk sdk1 = new MockDartSdk();
-    SdkCachePartition partition1 = manager.forSdk(sdk1);
-    expect(partition1, isNotNull);
-    expect(manager.forSdk(sdk1), same(partition1));
-    DartSdk sdk2 = new MockDartSdk();
-    SdkCachePartition partition2 = manager.forSdk(sdk2);
-    expect(partition2, isNotNull);
-    expect(manager.forSdk(sdk2), same(partition2));
-    expect(partition2, isNot(same(partition1)));
-  }
-}
-
-@reflectiveTest
-class ResolveDartLibraryTaskTest extends EngineTestCase {
-  void test_accept() {
-    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
-    expect(task.accept(new ResolveDartLibraryTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLibraryResolver() {
-    ResolveDartLibraryTask task = new ResolveDartLibraryTask(null, null, null);
-    expect(task.libraryResolver, isNull);
-  }
-
-  void test_getLibrarySource() {
-    Source source = new TestSource('/test.dart');
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(null, null, source);
-    expect(task.librarySource, same(source));
-  }
-
-  void test_getUnitSource() {
-    Source source = new TestSource('/test.dart');
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(null, source, null);
-    expect(task.unitSource, same(source));
-  }
-
-  void test_perform_exception() {
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(context, source, source);
-    task.perform(new ResolveDartLibraryTaskTestTV_perform_exception());
-  }
-
-  void test_perform_library() {
-    Source source = new TestSource(
-        '/test.dart',
-        r'''
-library lib;
-class A {}''');
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ResolveDartLibraryTask task =
-        new ResolveDartLibraryTask(context, source, source);
-    task.perform(new ResolveDartLibraryTaskTestTV_perform_library(source));
-  }
-}
-
-class ResolveDartLibraryTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) => true;
-}
-
-class ResolveDartLibraryTaskTestTV_perform_exception
-    extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ResolveDartLibraryTaskTestTV_perform_library
-    extends TestTaskVisitor<bool> {
-  Source source;
-  ResolveDartLibraryTaskTestTV_perform_library(this.source);
-  @override
-  bool visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.libraryResolver, isNotNull);
-    expect(task.librarySource, same(source));
-    expect(task.unitSource, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class ResolveDartUnitTaskTest extends EngineTestCase {
-  void test_accept() {
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
-    expect(task.accept(new ResolveDartUnitTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getException() {
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLibrarySource() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElementImpl element = ElementFactory.library(context, "lib");
-    Source source = element.source;
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, element);
-    expect(task.librarySource, same(source));
-  }
-
-  void test_getResolvedUnit() {
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, null, null);
-    expect(task.resolvedUnit, isNull);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('/test.dart');
-    ResolveDartUnitTask task = new ResolveDartUnitTask(null, source, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_exception() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElementImpl element = ElementFactory.library(context, "lib");
-    TestSource source = new TestSource();
-    source.generateExceptionOnRead = true;
-    (element.definingCompilationUnit as CompilationUnitElementImpl).source =
-        source;
-    ResolveDartUnitTask task =
-        new ResolveDartUnitTask(context, source, element);
-    task.perform(new ResolveDartUnitTaskTestTV_perform_exception());
-  }
-
-  void test_perform_library() {
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    LibraryElementImpl libraryElement = ElementFactory.library(context, "lib");
-    CompilationUnitElementImpl unitElement =
-        libraryElement.definingCompilationUnit as CompilationUnitElementImpl;
-    ClassElementImpl classElement = ElementFactory.classElement2("A");
-    classElement.nameOffset = 19;
-    ConstructorElementImpl constructorElement =
-        ElementFactory.constructorElement2(classElement, null);
-    constructorElement.synthetic = true;
-    classElement.constructors = <ConstructorElement>[constructorElement];
-    unitElement.types = <ClassElement>[classElement];
-    Source source = unitElement.source;
-    context.setContents(
-        source,
-        r'''
-library lib;
-class A {}''');
-    ResolveDartUnitTask task =
-        new ResolveDartUnitTask(context, source, libraryElement);
-    task.perform(
-        new ResolveDartUnitTaskTestTV_perform_library(source, context));
-  }
-}
-
-class ResolveDartUnitTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartUnitTask(ResolveDartUnitTask task) => true;
-}
-
-class ResolveDartUnitTaskTestTV_perform_exception
-    extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ResolveDartUnitTaskTestTV_perform_library extends TestTaskVisitor<bool> {
-  Source source;
-  InternalAnalysisContext context;
-  ResolveDartUnitTaskTestTV_perform_library(this.source, this.context);
-  @override
-  bool visitResolveDartUnitTask(ResolveDartUnitTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.librarySource, same(source));
-    expect(task.resolvedUnit, isNotNull);
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class ResolveHtmlTaskTest extends EngineTestCase {
-  void test_accept() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.accept(new ResolveHtmlTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getElement() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.element, isNull);
-  }
-
-  void test_getException() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getResolutionErrors() {
-    ResolveHtmlTask task = new ResolveHtmlTask(null, null, 0, null);
-    expect(task.resolutionErrors, hasLength(0));
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('test.dart', '');
-    ResolveHtmlTask task = new ResolveHtmlTask(null, source, 0, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_exception() {
-    Source source = new TestSource();
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ResolveHtmlTask task = new ResolveHtmlTask(context, source, 0, null);
-    task.perform(new ResolveHtmlTaskTestTV_perform_exception());
-  }
-
-  void test_perform_valid() {
-    int modificationStamp = 73;
-    String content = r'''
-<html>
-<head>
-  <script type='application/dart'>
-    void f() { x = 0; }
-  </script>
-</head>
-<body>
-</body>
-</html>''';
-    Source source = new TestSource("/test.html", content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ParseHtmlTask parseTask = new ParseHtmlTask(context, source, content);
-    parseTask.perform(new ResolveHtmlTaskTestTV_perform_valid_2());
-    ResolveHtmlTask task = new ResolveHtmlTask(
-        context, source, modificationStamp, parseTask.htmlUnit);
-    task.perform(
-        new ResolveHtmlTaskTestTV_perform_valid(modificationStamp, source));
-  }
-}
-
-class ResolveHtmlTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveHtmlTask(ResolveHtmlTask task) => true;
-}
-
-class ResolveHtmlTaskTestTV_perform_exception extends TestTaskVisitor<bool> {
-  @override
-  bool visitResolveHtmlTask(ResolveHtmlTask task) {
-    expect(task.exception, isNotNull);
-    return true;
-  }
-}
-
-class ResolveHtmlTaskTestTV_perform_valid extends TestTaskVisitor<Object> {
-  int modificationStamp;
-  Source source;
-  ResolveHtmlTaskTestTV_perform_valid(this.modificationStamp, this.source);
-  @override
-  Object visitResolveHtmlTask(ResolveHtmlTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.element, isNotNull);
-    expect(task.resolutionErrors, hasLength(1));
-    expect(task.source, same(source));
-    return null;
-  }
-}
-
-class ResolveHtmlTaskTestTV_perform_valid_2 extends TestTaskVisitor<Object> {
-  @override
-  Object visitParseHtmlTask(ParseHtmlTask task) => null;
-}
-
-@reflectiveTest
-class ScanDartTaskTest extends EngineTestCase {
-  void test_accept() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.accept(new ScanDartTaskTestTV_accept()), isTrue);
-  }
-
-  void test_getErrors() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.errors, hasLength(0));
-  }
-
-  void test_getException() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.exception, isNull);
-  }
-
-  void test_getLineInfo() {
-    ScanDartTask task = new ScanDartTask(null, null, null);
-    expect(task.lineInfo, isNull);
-  }
-
-  void test_getSource() {
-    Source source = new TestSource('test.dart', '');
-    ScanDartTask task = new ScanDartTask(null, source, null);
-    expect(task.source, same(source));
-  }
-
-  void test_perform_valid() {
-    String content = 'class A {}';
-    Source source = new TestSource('test.dart', content);
-    InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
-    ScanDartTask task = new ScanDartTask(context, source, content);
-    task.perform(new ScanDartTaskTestTV_perform_valid(context, source));
-  }
-}
-
-class ScanDartTaskTestTV_accept extends TestTaskVisitor<bool> {
-  @override
-  bool visitScanDartTask(ScanDartTask task) => true;
-}
-
-class ScanDartTaskTestTV_perform_valid extends TestTaskVisitor<bool> {
-  InternalAnalysisContext context;
-  Source source;
-  ScanDartTaskTestTV_perform_valid(this.context, this.source);
-  @override
-  bool visitScanDartTask(ScanDartTask task) {
-    CaughtException exception = task.exception;
-    if (exception != null) {
-      throw exception;
-    }
-    expect(task.tokenStream, isNotNull);
-    expect(task.errors, hasLength(0));
-    expect(task.lineInfo, isNotNull);
-    expect(task.source, same(source));
-    return true;
-  }
-}
-
-@reflectiveTest
-class SdkCachePartitionTest extends EngineTestCase {
-  void test_contains_false() {
-    SdkCachePartition partition = new SdkCachePartition(null, 8);
-    Source source = new TestSource();
-    expect(partition.contains(source), isFalse);
-  }
-
-  void test_contains_true() {
-    SdkCachePartition partition = new SdkCachePartition(null, 8);
-    SourceFactory factory = new SourceFactory(
-        [new DartUriResolver(DirectoryBasedDartSdk.defaultSdk)]);
-    Source source = factory.forUri("dart:core");
-    expect(partition.contains(source), isTrue);
-  }
-
-  void test_creation() {
-    expect(new SdkCachePartition(null, 8), isNotNull);
-  }
-}
-
-@reflectiveTest
 class SourcesChangedEventTest {
   void test_added() {
     var source = new StringSource('', '/test.dart');
@@ -5692,12 +204,6 @@
   }
 
   @override
-  EmbedderYamlLocator get embedderYamlLocator {
-    fail("Unexpected invocation of get embedderYamlLocator");
-    return null;
-  }
-
-  @override
   void set analysisOptions(AnalysisOptions options) {
     fail("Unexpected invocation of setAnalysisOptions");
   }
@@ -5719,7 +225,13 @@
   }
 
   @override
-  List<newContext.AnalysisTarget> get explicitTargets {
+  EmbedderYamlLocator get embedderYamlLocator {
+    fail("Unexpected invocation of get embedderYamlLocator");
+    return null;
+  }
+
+  @override
+  List<AnalysisTarget> get explicitTargets {
     fail("Unexpected invocation of visitCacheItems");
     return null;
   }
@@ -5755,12 +267,6 @@
   }
 
   @override
-  LibraryResolverFactory get libraryResolverFactory {
-    fail("Unexpected invocation of getLibraryResolverFactory");
-    return null;
-  }
-
-  @override
   List<Source> get librarySources {
     fail("Unexpected invocation of getLibrarySources");
     return null;
@@ -5790,7 +296,7 @@
   }
 
   @override
-  List<newContext.AnalysisTarget> get priorityTargets {
+  List<AnalysisTarget> get priorityTargets {
     fail("Unexpected invocation of visitCacheItems");
     return null;
   }
@@ -5802,12 +308,6 @@
   }
 
   @override
-  ResolverVisitorFactory get resolverVisitorFactory {
-    fail("Unexpected invocation of getResolverVisitorFactory");
-    return null;
-  }
-
-  @override
   SourceFactory get sourceFactory {
     fail("Unexpected invocation of getSourceFactory");
     return null;
@@ -5825,12 +325,6 @@
   }
 
   @override
-  AnalysisContextStatistics get statistics {
-    fail("Unexpected invocation of getStatistics");
-    return null;
-  }
-
-  @override
   TypeProvider get typeProvider {
     fail("Unexpected invocation of getTypeProvider");
     return null;
@@ -5842,19 +336,13 @@
   }
 
   @override
-  TypeResolverVisitorFactory get typeResolverVisitorFactory {
-    fail("Unexpected invocation of getTypeResolverVisitorFactory");
-    return null;
-  }
-
-  @override
   TypeSystem get typeSystem {
     fail("Unexpected invocation of getTypeSystem");
     return null;
   }
 
   @override
-  List<newContext.WorkManager> get workManagers {
+  List<WorkManager> get workManagers {
     fail("Unexpected invocation of workManagers");
     return null;
   }
@@ -5894,13 +382,6 @@
   }
 
   @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) {
-    fail("Unexpected invocation of computeHtmlElement");
-    return null;
-  }
-
-  @override
   List<Source> computeImportedLibraries(Source source) {
     fail("Unexpected invocation of computeImportedLibraries");
     return null;
@@ -5925,12 +406,6 @@
   }
 
   @override
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    fail("Unexpected invocation of computeResolvableCompilationUnit");
-    return null;
-  }
-
-  @override
   Future<CompilationUnit> computeResolvedCompilationUnitAsync(
       Source source, Source librarySource) {
     fail("Unexpected invocation of getResolvedCompilationUnitFuture");
@@ -5938,8 +413,7 @@
   }
 
   @override
-  Object computeResult(
-      newContext.AnalysisTarget target, newContext.ResultDescriptor result) {
+  Object computeResult(AnalysisTarget target, ResultDescriptor result) {
     fail("Unexpected invocation of computeResult");
     return null;
   }
@@ -5962,7 +436,7 @@
   }
 
   @override
-  CacheEntry getCacheEntry(newContext.AnalysisTarget target) {
+  CacheEntry getCacheEntry(AnalysisTarget target) {
     fail("Unexpected invocation of visitCacheItems");
     return null;
   }
@@ -5975,7 +449,7 @@
   }
 
   @override
-  Object getConfigurationData(newContext.ResultDescriptor key) {
+  Object getConfigurationData(ResultDescriptor key) {
     fail("Unexpected invocation of getConfigurationData");
     return null;
   }
@@ -6005,13 +479,6 @@
   }
 
   @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    fail("Unexpected invocation of getHtmlElement");
-    return null;
-  }
-
-  @override
   List<Source> getHtmlFilesReferencing(Source source) {
     fail("Unexpected invocation of getHtmlFilesReferencing");
     return null;
@@ -6086,15 +553,7 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    fail("Unexpected invocation of getResolvedHtmlUnit");
-    return null;
-  }
-
-  @override
-  Object getResult(
-      newContext.AnalysisTarget target, newContext.ResultDescriptor result) {
+  Object getResult(AnalysisTarget target, ResultDescriptor result) {
     fail("Unexpected invocation of getResult");
     return null;
   }
@@ -6130,8 +589,7 @@
   }
 
   @override
-  Stream<ComputedResult> onResultComputed(
-      newContext.ResultDescriptor descriptor) {
+  Stream<ComputedResult> onResultComputed(ResultDescriptor descriptor) {
     fail("Unexpected invocation of onResultComputed");
     return null;
   }
@@ -6149,12 +607,6 @@
   }
 
   @override
-  ht.HtmlUnit parseHtmlUnit(Source source) {
-    fail("Unexpected invocation of parseHtmlUnit");
-    return null;
-  }
-
-  @override
   AnalysisResult performAnalysisTask() {
     fail("Unexpected invocation of performAnalysisTask");
     return null;
@@ -6185,20 +637,13 @@
   }
 
   @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    fail("Unexpected invocation of resolveHtmlUnit");
-    return null;
-  }
-
-  @override
   void setChangedContents(Source source, String contents, int offset,
       int oldLength, int newLength) {
     fail("Unexpected invocation of setChangedContents");
   }
 
   @override
-  void setConfigurationData(newContext.ResultDescriptor key, Object data) {
+  void setConfigurationData(ResultDescriptor key, Object data) {
     fail("Unexpected invocation of setConfigurationData");
   }
 
@@ -6208,7 +653,7 @@
   }
 
   @override
-  bool shouldErrorsBeAnalyzed(Source source, Object entry) {
+  bool shouldErrorsBeAnalyzed(Source source) {
     fail("Unexpected invocation of shouldErrorsBeAnalyzed");
     return false;
   }
@@ -6224,844 +669,8 @@
     return false;
   }
 
-  @deprecated
-  @override
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state)) {
-    fail("Unexpected invocation of visitCacheItems");
-  }
-
   @override
   void visitContentCache(ContentCacheVisitor visitor) {
     fail("Unexpected invocation of visitContentCache");
   }
 }
-
-class TestAnalysisContext_test_applyChanges extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_applyChanges();
-  @override
-  ApplyChangesStatus applyChanges(ChangeSet changeSet) {
-    invoked = true;
-    return new ApplyChangesStatus(false);
-  }
-}
-
-class TestAnalysisContext_test_computeDocumentationComment
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeDocumentationComment();
-  @override
-  String computeDocumentationComment(Element element) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeErrors extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeErrors();
-  @override
-  List<AnalysisError> computeErrors(Source source) {
-    invoked = true;
-    return AnalysisError.NO_ERRORS;
-  }
-}
-
-class TestAnalysisContext_test_computeExportedLibraries
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeExportedLibraries();
-  @override
-  List<Source> computeExportedLibraries(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeHtmlElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeHtmlElement();
-  @override
-  @deprecated
-  HtmlElement computeHtmlElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeImportedLibraries
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeImportedLibraries();
-  @override
-  List<Source> computeImportedLibraries(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeKindOf extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeKindOf();
-  @override
-  SourceKind computeKindOf(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeLibraryElement
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeLibraryElement();
-  @override
-  LibraryElement computeLibraryElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeLineInfo extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeLineInfo();
-  @override
-  LineInfo computeLineInfo(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_computeResolvableCompilationUnit
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_computeResolvableCompilationUnit();
-  @override
-  CompilationUnit computeResolvableCompilationUnit(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_dispose extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_dispose();
-  @override
-  void dispose() {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_exists extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_exists();
-  @override
-  bool exists(Source source) {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_getAnalysisOptions extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getAnalysisOptions();
-  @override
-  AnalysisOptions get analysisOptions {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getCompilationUnitElement
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getCompilationUnitElement();
-  @override
-  CompilationUnitElement getCompilationUnitElement(
-      Source unitSource, Source librarySource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getContents extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getContents();
-  @override
-  TimestampedData<String> getContents(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getElement();
-  @override
-  Element getElement(ElementLocation location) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getErrors extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getErrors();
-  @override
-  AnalysisErrorInfo getErrors(Source source) {
-    invoked = true;
-    return new AnalysisErrorInfoImpl(AnalysisError.NO_ERRORS, null);
-  }
-}
-
-class TestAnalysisContext_test_getHtmlElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getHtmlElement();
-  @override
-  @deprecated
-  HtmlElement getHtmlElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getHtmlFilesReferencing
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getHtmlFilesReferencing();
-  @override
-  List<Source> getHtmlFilesReferencing(Source source) {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getHtmlSources extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getHtmlSources();
-  @override
-  List<Source> get htmlSources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getKindOf extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getKindOf();
-  @override
-  SourceKind getKindOf(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getLaunchableClientLibrarySources
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLaunchableClientLibrarySources();
-  @override
-  List<Source> get launchableClientLibrarySources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLaunchableServerLibrarySources
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLaunchableServerLibrarySources();
-  @override
-  List<Source> get launchableServerLibrarySources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLibrariesContaining
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrariesContaining();
-  @override
-  List<Source> getLibrariesContaining(Source source) {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLibrariesDependingOn
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrariesDependingOn();
-  @override
-  List<Source> getLibrariesDependingOn(Source librarySource) {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLibrariesReferencedFromHtml
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrariesReferencedFromHtml();
-  @override
-  List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getLibraryElement extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibraryElement();
-  @override
-  LibraryElement getLibraryElement(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getLibrarySources extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLibrarySources();
-  @override
-  List<Source> get librarySources {
-    invoked = true;
-    return Source.EMPTY_LIST;
-  }
-}
-
-class TestAnalysisContext_test_getLineInfo extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getLineInfo();
-  @override
-  LineInfo getLineInfo(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getModificationStamp
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getModificationStamp();
-  @override
-  int getModificationStamp(Source source) {
-    invoked = true;
-    return 0;
-  }
-}
-
-class TestAnalysisContext_test_getPublicNamespace extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getPublicNamespace();
-  @override
-  Namespace getPublicNamespace(LibraryElement library) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getResolvedCompilationUnit_element
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getResolvedCompilationUnit_element();
-  @override
-  CompilationUnit getResolvedCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getResolvedCompilationUnit_source
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getResolvedCompilationUnit_source();
-  @override
-  CompilationUnit getResolvedCompilationUnit2(
-      Source unitSource, Source librarySource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getResolvedHtmlUnit extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getResolvedHtmlUnit();
-  @override
-  @deprecated
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getSourceFactory extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getSourceFactory();
-  @override
-  SourceFactory get sourceFactory {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getStatistics extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getStatistics();
-  @override
-  AnalysisContextStatistics get statistics {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_getTypeProvider extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_getTypeProvider();
-  @override
-  TypeProvider get typeProvider {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_isClientLibrary extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_isClientLibrary();
-  @override
-  bool isClientLibrary(Source librarySource) {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_isDisposed extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_isDisposed();
-  @override
-  bool get isDisposed {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_isServerLibrary extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_isServerLibrary();
-  @override
-  bool isServerLibrary(Source librarySource) {
-    invoked = true;
-    return false;
-  }
-}
-
-class TestAnalysisContext_test_parseCompilationUnit
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_parseCompilationUnit();
-  @override
-  CompilationUnit parseCompilationUnit(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_parseHtmlUnit extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_parseHtmlUnit();
-  @override
-  ht.HtmlUnit parseHtmlUnit(Source source) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_performAnalysisTask extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_performAnalysisTask();
-  @override
-  AnalysisResult performAnalysisTask() {
-    invoked = true;
-    return new AnalysisResult(new List<ChangeNotice>(0), 0, null, 0);
-  }
-}
-
-class TestAnalysisContext_test_recordLibraryElements
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_recordLibraryElements();
-  @override
-  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_resolveCompilationUnit
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_resolveCompilationUnit();
-  @override
-  CompilationUnit resolveCompilationUnit2(
-      Source unitSource, Source librarySource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_resolveCompilationUnit_element
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_resolveCompilationUnit_element();
-  @override
-  CompilationUnit resolveCompilationUnit(
-      Source unitSource, LibraryElement library) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_resolveHtmlUnit extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_resolveHtmlUnit();
-  @override
-  @deprecated
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    invoked = true;
-    return null;
-  }
-}
-
-class TestAnalysisContext_test_setAnalysisOptions extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setAnalysisOptions();
-  @override
-  void set analysisOptions(AnalysisOptions options) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setAnalysisPriorityOrder
-    extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setAnalysisPriorityOrder();
-  @override
-  void set analysisPriorityOrder(List<Source> sources) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setChangedContents extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setChangedContents();
-  @override
-  void setChangedContents(Source source, String contents, int offset,
-      int oldLength, int newLength) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setContents extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setContents();
-  @override
-  void setContents(Source source, String contents) {
-    invoked = true;
-  }
-}
-
-class TestAnalysisContext_test_setSourceFactory extends TestAnalysisContext {
-  bool invoked = false;
-  TestAnalysisContext_test_setSourceFactory();
-  @override
-  void set sourceFactory(SourceFactory factory) {
-    invoked = true;
-  }
-}
-
-/**
- * Instances of the class `TestTaskVisitor` implement a task visitor that fails if any of its
- * methods are invoked. Subclasses typically override the expected methods to not cause a test
- * failure.
- */
-class TestTaskVisitor<E> implements AnalysisTaskVisitor<E> {
-  @override
-  E visitGenerateDartErrorsTask(GenerateDartErrorsTask task) {
-    fail("Unexpectedly invoked visitGenerateDartErrorsTask");
-    return null;
-  }
-
-  @override
-  E visitGenerateDartHintsTask(GenerateDartHintsTask task) {
-    fail("Unexpectedly invoked visitGenerateDartHintsTask");
-    return null;
-  }
-
-  @override
-  E visitGenerateDartLintsTask(GenerateDartLintsTask task) {
-    fail("Unexpectedly invoked visitGenerateDartLintsTask");
-    return null;
-  }
-
-  @override
-  E visitGetContentTask(GetContentTask task) {
-    fail("Unexpectedly invoked visitGetContentsTask");
-    return null;
-  }
-
-  @override
-  E visitIncrementalAnalysisTask(
-      IncrementalAnalysisTask incrementalAnalysisTask) {
-    fail("Unexpectedly invoked visitIncrementalAnalysisTask");
-    return null;
-  }
-
-  @override
-  E visitParseDartTask(ParseDartTask task) {
-    fail("Unexpectedly invoked visitParseDartTask");
-    return null;
-  }
-
-  @override
-  E visitParseHtmlTask(ParseHtmlTask task) {
-    fail("Unexpectedly invoked visitParseHtmlTask");
-    return null;
-  }
-
-  @override
-  E visitResolveDartLibraryCycleTask(ResolveDartLibraryCycleTask task) {
-    fail("Unexpectedly invoked visitResolveDartLibraryCycleTask");
-    return null;
-  }
-
-  @override
-  E visitResolveDartLibraryTask(ResolveDartLibraryTask task) {
-    fail("Unexpectedly invoked visitResolveDartLibraryTask");
-    return null;
-  }
-
-  @override
-  E visitResolveDartUnitTask(ResolveDartUnitTask task) {
-    fail("Unexpectedly invoked visitResolveDartUnitTask");
-    return null;
-  }
-
-  @override
-  E visitResolveHtmlTask(ResolveHtmlTask task) {
-    fail("Unexpectedly invoked visitResolveHtmlTask");
-    return null;
-  }
-
-  @override
-  E visitScanDartTask(ScanDartTask task) {
-    fail("Unexpectedly invoked visitScanDartTask");
-    return null;
-  }
-}
-
-@reflectiveTest
-class UniversalCachePartitionTest extends EngineTestCase {
-  void test_contains() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    expect(partition.contains(source), isTrue);
-  }
-
-  void test_creation() {
-    expect(new UniversalCachePartition(null, 8, null), isNotNull);
-  }
-
-  void test_entrySet() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    partition.put(source, entry);
-    Map<Source, SourceEntry> entryMap = partition.map;
-    expect(entryMap.length, 1);
-    Source entryKey = entryMap.keys.first;
-    expect(entryKey, same(source));
-    expect(entryMap[entryKey], same(entry));
-  }
-
-  void test_get() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    expect(partition.get(source), isNull);
-  }
-
-  void test_put_noFlush() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    partition.put(source, entry);
-    expect(partition.get(source), same(entry));
-  }
-
-  void test_remove() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    TestSource source = new TestSource();
-    DartEntry entry = new DartEntry();
-    partition.put(source, entry);
-    expect(partition.get(source), same(entry));
-    partition.remove(source);
-    expect(partition.get(source), isNull);
-  }
-
-  void test_setMaxCacheSize() {
-    UniversalCachePartition partition = new UniversalCachePartition(
-        null, 8, new _UniversalCachePartitionTest_test_setMaxCacheSize());
-    int size = 6;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      DartEntry entry = new DartEntry();
-      entry.setValue(DartEntry.PARSED_UNIT, null);
-      partition.put(source, entry);
-      partition.accessedAst(source);
-    }
-    _assertNonFlushedCount(size, partition);
-    int newSize = size - 2;
-    partition.maxCacheSize = newSize;
-    _assertNonFlushedCount(newSize, partition);
-  }
-
-  void test_size() {
-    UniversalCachePartition partition =
-        new UniversalCachePartition(null, 8, null);
-    int size = 4;
-    for (int i = 0; i < size; i++) {
-      Source source = new TestSource("/test$i.dart");
-      partition.put(source, new DartEntry());
-      partition.accessedAst(source);
-    }
-    expect(partition.size(), size);
-  }
-
-  void _assertNonFlushedCount(
-      int expectedCount, UniversalCachePartition partition) {
-    int nonFlushedCount = 0;
-    Map<Source, SourceEntry> entryMap = partition.map;
-    entryMap.values.forEach((SourceEntry value) {
-      if (value.getState(DartEntry.PARSED_UNIT) != CacheState.FLUSHED) {
-        nonFlushedCount++;
-      }
-    });
-    expect(nonFlushedCount, expectedCount);
-  }
-}
-
-@reflectiveTest
-class WorkManagerTest extends EngineTestCase {
-  void test_addFirst() {
-    TestSource source1 = new TestSource("/f1.dart");
-    TestSource source2 = new TestSource("/f2.dart");
-    WorkManager manager = new WorkManager();
-    manager.add(source1, SourcePriority.UNKNOWN);
-    manager.addFirst(source2, SourcePriority.UNKNOWN);
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.next(), same(source2));
-    expect(iterator.next(), same(source1));
-  }
-
-  void test_creation() {
-    expect(new WorkManager(), isNotNull);
-  }
-
-  void test_iterator_empty() {
-    WorkManager manager = new WorkManager();
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.hasNext, isFalse);
-    try {
-      iterator.next();
-      fail("Expected NoSuchElementException");
-    } on NoSuchElementException {}
-  }
-
-  void test_iterator_nonEmpty() {
-    TestSource source = new TestSource();
-    WorkManager manager = new WorkManager();
-    manager.add(source, SourcePriority.UNKNOWN);
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.hasNext, isTrue);
-    expect(iterator.next(), same(source));
-  }
-
-  void test_remove() {
-    TestSource source1 = new TestSource("/f1.dart");
-    TestSource source2 = new TestSource("/f2.dart");
-    TestSource source3 = new TestSource("/f3.dart");
-    WorkManager manager = new WorkManager();
-    manager.add(source1, SourcePriority.UNKNOWN);
-    manager.add(source2, SourcePriority.UNKNOWN);
-    manager.add(source3, SourcePriority.UNKNOWN);
-    manager.remove(source2);
-    WorkManager_WorkIterator iterator = manager.iterator();
-    expect(iterator.next(), same(source1));
-    expect(iterator.next(), same(source3));
-  }
-
-  void test_toString_empty() {
-    WorkManager manager = new WorkManager();
-    expect(manager.toString(), isNotNull);
-  }
-
-  void test_toString_nonEmpty() {
-    WorkManager manager = new WorkManager();
-    manager.add(new TestSource(), SourcePriority.HTML);
-    manager.add(new TestSource(), SourcePriority.LIBRARY);
-    manager.add(new TestSource(), SourcePriority.NORMAL_PART);
-    manager.add(new TestSource(), SourcePriority.PRIORITY_PART);
-    manager.add(new TestSource(), SourcePriority.UNKNOWN);
-    expect(manager.toString(), isNotNull);
-  }
-}
-
-class _AnalysisCacheTest_test_setMaxCacheSize implements CacheRetentionPolicy {
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
-      RetentionPriority.LOW;
-}
-
-class _AnalysisContext_sourceChangeDuringResolution
-    extends AnalysisContextForTests {
-  @override
-  DartEntry recordResolveDartLibraryTaskResults(ResolveDartLibraryTask task) {
-    ChangeSet changeSet = new ChangeSet();
-    changeSet.changedSource(task.librarySource);
-    applyChanges(changeSet);
-    return super.recordResolveDartLibraryTaskResults(task);
-  }
-}
-
-class _AnalysisContextImplTest_test_applyChanges_removeContainer
-    implements SourceContainer {
-  Source libB;
-  _AnalysisContextImplTest_test_applyChanges_removeContainer(this.libB);
-  @override
-  bool contains(Source source) => source == libB;
-}
-
-class _Source_getContent_throwException extends NonExistingSource {
-  _Source_getContent_throwException(String name)
-      : super(name, pathos.toUri(name), UriKind.FILE_URI);
-
-  @override
-  TimestampedData<String> get contents {
-    throw 'Read error';
-  }
-
-  @override
-  bool exists() => true;
-}
-
-class _UniversalCachePartitionTest_test_setMaxCacheSize
-    implements CacheRetentionPolicy {
-  @override
-  RetentionPriority getAstPriority(Source source, SourceEntry sourceEntry) =>
-      RetentionPriority.LOW;
-}
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index dd9394c..b36d31e 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -2,13 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_resolver_test;
+library analyzer.test.generated.incremental_resolver_test;
 
-import 'package:analyzer/src/context/cache.dart' as task;
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisCache;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/incremental_logger.dart' as log;
 import 'package:analyzer/src/generated/incremental_resolution_validator.dart';
@@ -3026,22 +3025,12 @@
 
   @override
   void reset() {
-    if (AnalysisEngine.instance.useTaskModel) {
-      analysisContext2 = AnalysisContextFactory.contextWithCore();
-    } else {
-      analysisContext2 = AnalysisContextFactory.oldContextWithCore();
-    }
+    analysisContext2 = AnalysisContextFactory.contextWithCore();
   }
 
   @override
   void resetWithOptions(AnalysisOptions options) {
-    if (AnalysisEngine.instance.useTaskModel) {
-      analysisContext2 =
-          AnalysisContextFactory.contextWithCoreAndOptions(options);
-    } else {
-      analysisContext2 =
-          AnalysisContextFactory.oldContextWithCoreAndOptions(options);
-    }
+    AnalysisContextFactory.contextWithCoreAndOptions(options);
   }
 
   void setUp() {
@@ -3391,28 +3380,10 @@
     int updateEndOld = updateOffset + edit.length;
     int updateOldNew = updateOffset + edit.replacement.length;
     IncrementalResolver resolver;
-    if (AnalysisEngine.instance.useTaskModel) {
-      LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
-      task.AnalysisCache cache = analysisContext2.analysisCache;
-      resolver = new IncrementalResolver(
-          null,
-          cache.get(source),
-          cache.get(lsu),
-          unit.element,
-          updateOffset,
-          updateEndOld,
-          updateOldNew);
-    } else {
-      resolver = new IncrementalResolver(
-          (analysisContext2 as AnalysisContextImpl)
-              .getReadableSourceEntryOrNull(source),
-          null,
-          null,
-          unit.element,
-          updateOffset,
-          updateEndOld,
-          updateOldNew);
-    }
+    LibrarySpecificUnit lsu = new LibrarySpecificUnit(source, source);
+    AnalysisCache cache = analysisContext2.analysisCache;
+    resolver = new IncrementalResolver(cache.get(source), cache.get(lsu),
+        unit.element, updateOffset, updateEndOld, updateOldNew);
     bool success = resolver.resolve(newNode);
     expect(success, isTrue);
     List<AnalysisError> newErrors = analysisContext.computeErrors(source);
@@ -4470,7 +4441,7 @@
     // Invalidate VERIFY_ERRORS.
     AnalysisCache cache = analysisContext2.analysisCache;
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    task.CacheEntry cacheEntry = cache.get(target);
+    CacheEntry cacheEntry = cache.get(target);
     expect(cacheEntry.getValue(VERIFY_ERRORS), hasLength(2));
     cacheEntry.setState(VERIFY_ERRORS, CacheState.INVALID);
     // Don't run tasks, so don't recompute VERIFY_ERRORS before incremental.
diff --git a/pkg/analyzer/test/generated/incremental_scanner_test.dart b/pkg/analyzer/test/generated/incremental_scanner_test.dart
index 6b72aa6..fad6244 100644
--- a/pkg/analyzer/test/generated/incremental_scanner_test.dart
+++ b/pkg/analyzer/test/generated/incremental_scanner_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.incremental_scanner_test;
+library analyzer.test.generated.incremental_scanner_test;
 
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/incremental_scanner.dart';
diff --git a/pkg/analyzer/test/generated/java_core_test.dart b/pkg/analyzer/test/generated/java_core_test.dart
index e60e9c1..0a914ec 100644
--- a/pkg/analyzer/test/generated/java_core_test.dart
+++ b/pkg/analyzer/test/generated/java_core_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.java_core_test;
+library analyzer.test.generated.java_core_test;
 
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/java_io_test.dart b/pkg/analyzer/test/generated/java_io_test.dart
index 2bd611d..0316817 100644
--- a/pkg/analyzer/test/generated/java_io_test.dart
+++ b/pkg/analyzer/test/generated/java_io_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.java_io_test;
+library analyzer.test.generated.java_io_test;
 
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 719d159..24928c2 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.non_error_resolver_test;
+library analyzer.test.generated.non_error_resolver_test;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -262,6 +262,82 @@
     verify([source]);
   }
 
+  void test_assert_with_message_await() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+import 'dart:async';
+f() async {
+  assert(false, await g());
+}
+Future<String> g() => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_dynamic() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, g());
+}
+g() => null;
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_non_string() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, 3);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_null() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, null);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_string() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  assert(false, 'message');
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_assert_with_message_suppresses_unused_var_hint() {
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+f() {
+  String message = 'msg';
+  assert(true, message);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_assignability_function_expr_rettype_from_typedef_cls() {
     // In the code below, the type of (() => f()) has a return type which is
     // a class, and that class is inferred from the return type of the typedef
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index d3c995c..574832b 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.parser_test;
+library analyzer.test.generated.parser_test;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -16,7 +16,7 @@
 import 'package:analyzer/src/generated/testing/element_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:unittest/unittest.dart';
+import 'package:unittest/unittest.dart' hide Configuration;
 
 import '../reflective_tests.dart';
 import '../utils.dart';
@@ -1344,6 +1344,11 @@
     parse4("parseStringLiteral", "'\$1'", [ParserErrorCode.MISSING_IDENTIFIER]);
   }
 
+  void test_invalidLiteralInConfiguration() {
+    parse4("parseConfiguration", "if (a == 'x \$y z') 'a.dart'",
+        [ParserErrorCode.INVALID_LITERAL_IN_CONFIGURATION]);
+  }
+
   void test_invalidOperator() {
     parse3("parseClassMember", <Object>["C"], "void operator ===(x) {}",
         [ParserErrorCode.INVALID_OPERATOR]);
@@ -2640,6 +2645,12 @@
   static bool parseFunctionBodies = true;
 
   /**
+   * A flag indicating whether conditional directives support should be enabled
+   * for a specific test.
+   */
+  bool enableConditionalDirectives = false;
+
+  /**
    * A flag indicating whether generic method support should be enabled for a
    * specific test.
    */
@@ -2700,6 +2711,7 @@
     // Parse the source.
     //
     Parser parser = createParser(listener);
+    parser.parseConditionalDirectives = enableConditionalDirectives;
     parser.parseGenericMethods = enableGenericMethods;
     parser.parseGenericMethodComments = enableGenericMethodComments;
     parser.parseFunctionBodies = parseFunctionBodies;
@@ -5158,6 +5170,36 @@
     expect(statement.assertKeyword, isNotNull);
     expect(statement.leftParenthesis, isNotNull);
     expect(statement.condition, isNotNull);
+    expect(statement.comma, isNull);
+    expect(statement.message, isNull);
+    expect(statement.rightParenthesis, isNotNull);
+    expect(statement.semicolon, isNotNull);
+  }
+
+  void test_parseAssertStatement_messageLowPrecedence() {
+    // Using a throw expression as an assert message would be silly in
+    // practice, but it's the lowest precedence expression type, so verifying
+    // that it works should give us high confidence that other expression types
+    // will work as well.
+    AssertStatement statement =
+        parse4('parseAssertStatement', 'assert (x, throw "foo");');
+    expect(statement.assertKeyword, isNotNull);
+    expect(statement.leftParenthesis, isNotNull);
+    expect(statement.condition, isNotNull);
+    expect(statement.comma, isNotNull);
+    expect(statement.message, isNotNull);
+    expect(statement.rightParenthesis, isNotNull);
+    expect(statement.semicolon, isNotNull);
+  }
+
+  void test_parseAssertStatement_messageString() {
+    AssertStatement statement =
+        parse4('parseAssertStatement', 'assert (x, "foo");');
+    expect(statement.assertKeyword, isNotNull);
+    expect(statement.leftParenthesis, isNotNull);
+    expect(statement.condition, isNotNull);
+    expect(statement.comma, isNotNull);
+    expect(statement.message, isNotNull);
     expect(statement.rightParenthesis, isNotNull);
     expect(statement.semicolon, isNotNull);
   }
@@ -7133,6 +7175,54 @@
     expect(expression.elseExpression, isNotNull);
   }
 
+  void test_parseConfiguration_noOperator_dottedIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a.b) 'c.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a", "b"]);
+    expect(configuration.equalToken, isNull);
+    expect(configuration.value, isNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
+  void test_parseConfiguration_noOperator_simpleIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a) 'b.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a"]);
+    expect(configuration.equalToken, isNull);
+    expect(configuration.value, isNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
+  void test_parseConfiguration_operator_dottedIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a.b == 'c') 'd.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a", "b"]);
+    expect(configuration.equalToken, isNotNull);
+    expect(configuration.value, isNotNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
+  void test_parseConfiguration_operator_simpleIdentifier() {
+    Configuration configuration =
+        parse4('parseConfiguration', "if (a == 'b') 'c.dart'");
+    expect(configuration.ifKeyword, isNotNull);
+    expect(configuration.leftParenthesis, isNotNull);
+    _expectDottedName(configuration.name, ["a"]);
+    expect(configuration.equalToken, isNotNull);
+    expect(configuration.value, isNotNull);
+    expect(configuration.rightParenthesis, isNotNull);
+    expect(configuration.libraryUri, isNotNull);
+  }
+
   void test_parseConstExpression_instanceCreation() {
     InstanceCreationExpression expression =
         parse4("parseConstExpression", "const A()");
@@ -7398,6 +7488,16 @@
     expect(statement.semicolon, isNotNull);
   }
 
+  void test_parseDottedName_multiple() {
+    DottedName name = parse4("parseDottedName", "a.b.c");
+    _expectDottedName(name, ["a", "b", "c"]);
+  }
+
+  void test_parseDottedName_single() {
+    DottedName name = parse4("parseDottedName", "a");
+    _expectDottedName(name, ["a"]);
+  }
+
   void test_parseEmptyStatement() {
     EmptyStatement statement = parse4("parseEmptyStatement", ";");
     expect(statement.semicolon, isNotNull);
@@ -7454,6 +7554,35 @@
     expect(expression.rightOperand, isNotNull);
   }
 
+  void test_parseExportDirective_configuration_multiple() {
+    enableConditionalDirectives = true;
+    ExportDirective directive = parse(
+        "parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(2));
+    _expectDottedName(directive.configurations[0].name, ['a']);
+    _expectDottedName(directive.configurations[1].name, ['c']);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
+  void test_parseExportDirective_configuration_single() {
+    enableConditionalDirectives = true;
+    ExportDirective directive = parse(
+        "parseExportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "export 'lib/lib.dart' if (a.b == 'c.dart') '';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(1));
+    _expectDottedName(directive.configurations[0].name, ['a', 'b']);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
   void test_parseExportDirective_hide() {
     ExportDirective directive = parse(
         "parseExportDirective",
@@ -8629,6 +8758,41 @@
     expect(clause.implementsKeyword, isNotNull);
   }
 
+  void test_parseImportDirective_configuration_multiple() {
+    enableConditionalDirectives = true;
+    ImportDirective directive = parse(
+        "parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' if (a) 'b.dart' if (c) 'd.dart';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(2));
+    _expectDottedName(directive.configurations[0].name, ['a']);
+    _expectDottedName(directive.configurations[1].name, ['c']);
+    expect(directive.deferredKeyword, isNull);
+    expect(directive.asKeyword, isNull);
+    expect(directive.prefix, isNull);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
+  void test_parseImportDirective_configuration_single() {
+    enableConditionalDirectives = true;
+    ImportDirective directive = parse(
+        "parseImportDirective",
+        <Object>[emptyCommentAndMetadata()],
+        "import 'lib/lib.dart' if (a.b == 'c.dart') '';");
+    expect(directive.keyword, isNotNull);
+    expect(directive.uri, isNotNull);
+    expect(directive.configurations, hasLength(1));
+    _expectDottedName(directive.configurations[0].name, ['a', 'b']);
+    expect(directive.deferredKeyword, isNull);
+    expect(directive.asKeyword, isNull);
+    expect(directive.prefix, isNull);
+    expect(directive.combinators, hasLength(0));
+    expect(directive.semicolon, isNotNull);
+  }
+
   void test_parseImportDirective_deferred() {
     ImportDirective directive = parse(
         "parseImportDirective",
@@ -11008,6 +11172,17 @@
     return invokeParserMethod2("createSyntheticStringLiteral", "", listener);
   }
 
+  void _expectDottedName(DottedName name, List<String> expectedComponents) {
+    int count = expectedComponents.length;
+    NodeList<SimpleIdentifier> components = name.components;
+    expect(components, hasLength(count));
+    for (int i = 0; i < count; i++) {
+      SimpleIdentifier component = components[i];
+      expect(component, isNotNull);
+      expect(component.name, expectedComponents[i]);
+    }
+  }
+
   /**
    * Invoke the method [Parser.isFunctionDeclaration] with the parser set to the token
    * stream produced by scanning the given source.
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index da69a28..c57ca34 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -2,11 +2,11 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.resolver_test;
+library analyzer.test.generated.resolver_test;
 
 import 'dart:collection';
 
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/element_resolver.dart';
@@ -44,16 +44,6 @@
   runReflectiveTests(ScopeTest);
   runReflectiveTests(ElementResolverTest);
   runReflectiveTests(InheritanceManagerTest);
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(LibraryElementBuilderTest);
-  }
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(LibraryResolver2Test);
-  }
-  if (!AnalysisEngine.instance.useTaskModel) {
-    runReflectiveTests(LibraryResolverTest);
-  }
-  runReflectiveTests(LibraryTest);
   runReflectiveTests(StaticTypeAnalyzerTest);
   runReflectiveTests(StaticTypeAnalyzer2Test);
   runReflectiveTests(SubtypeManagerTest);
@@ -89,10 +79,6 @@
    * Return the context that was created.
    */
   static InternalAnalysisContext contextWithCore() {
-    if (AnalysisEngine.instance.useTaskModel) {
-      NewAnalysisContextForTests context = new NewAnalysisContextForTests();
-      return initContextWithCore(context);
-    }
     AnalysisContextForTests context = new AnalysisContextForTests();
     return initContextWithCore(context);
   }
@@ -103,11 +89,6 @@
    */
   static InternalAnalysisContext contextWithCoreAndOptions(
       AnalysisOptions options) {
-    if (AnalysisEngine.instance.useTaskModel) {
-      NewAnalysisContextForTests context = new NewAnalysisContextForTests();
-      context._internalSetAnalysisOptions(options);
-      return initContextWithCore(context);
-    }
     AnalysisContextForTests context = new AnalysisContextForTests();
     context._internalSetAnalysisOptions(options);
     return initContextWithCore(context);
@@ -212,8 +193,8 @@
         'onValue', futureThenR, [futureElement.typeParameters[0]], null);
 
     DartType futureRType = futureElement.type.substitute4([futureThenR.type]);
-    MethodElementImpl thenMethod = ElementFactory.methodElementWithParameters(
-        futureElement, "then", futureRType, [
+    MethodElementImpl thenMethod = ElementFactory
+        .methodElementWithParameters(futureElement, "then", futureRType, [
       ElementFactory.requiredParameter2("onValue", thenOnValue.type),
       ElementFactory.namedParameter2("onError", provider.functionType)
     ]);
@@ -301,8 +282,8 @@
     ClassElementImpl htmlDocumentElement =
         ElementFactory.classElement("HtmlDocument", documentElement.type);
     htmlDocumentElement.methods = <MethodElement>[
-      ElementFactory.methodElement(
-          "query", elementType, <DartType>[provider.stringType])
+      ElementFactory
+          .methodElement("query", elementType, <DartType>[provider.stringType])
     ];
     htmlUnit.types = <ClassElement>[
       ElementFactory.classElement("AnchorElement", elementType),
@@ -322,8 +303,8 @@
       ElementFactory.functionElement3("query", elementElement,
           <ClassElement>[provider.stringType.element], ClassElement.EMPTY_LIST)
     ];
-    TopLevelVariableElementImpl document = ElementFactory
-        .topLevelVariableElement3(
+    TopLevelVariableElementImpl document =
+        ElementFactory.topLevelVariableElement3(
             "document", false, true, htmlDocumentElement.type);
     htmlUnit.topLevelVariables = <TopLevelVariableElement>[document];
     htmlUnit.accessors = <PropertyAccessorElement>[document.getter];
@@ -410,31 +391,11 @@
     context.recordLibraryElements(elementMap);
     return context;
   }
-
-  /**
-   * Create an analysis context that has a fake core library already resolved.
-   * Return the context that was created.
-   */
-  static AnalysisContextImpl oldContextWithCore() {
-    AnalysisContextForTests context = new AnalysisContextForTests();
-    return initContextWithCore(context);
-  }
-
-  /**
-   * Create an analysis context that uses the given [options] and has a fake
-   * core library already resolved. Return the context that was created.
-   */
-  static AnalysisContextImpl oldContextWithCoreAndOptions(
-      AnalysisOptions options) {
-    AnalysisContextForTests context = new AnalysisContextForTests();
-    context._internalSetAnalysisOptions(options);
-    return initContextWithCore(context);
-  }
 }
 
 /**
- * Instances of the class `AnalysisContextForTests` implement an analysis context that has a
- * fake SDK that is much smaller and faster for testing purposes.
+ * An analysis context that has a fake SDK that is much smaller and faster for
+ * testing purposes.
  */
 class AnalysisContextForTests extends AnalysisContextImpl {
   @override
@@ -1303,6 +1264,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     _listener = new GatheringErrorListener();
     _typeProvider = new TestTypeProvider();
     _resolver = _createResolver();
@@ -2003,12 +1965,9 @@
         definingCompilationUnit.source = source;
     _definingLibrary = ElementFactory.library(context, "test");
     _definingLibrary.definingCompilationUnit = definingCompilationUnit;
-    Library library = new Library(context, _listener, source);
-    library.libraryElement = _definingLibrary;
     _visitor = new ResolverVisitor(
-        library.libraryElement, source, _typeProvider, library.errorListener,
-        nameScope: library.libraryScope,
-        inheritanceManager: library.inheritanceManager);
+        _definingLibrary, source, _typeProvider, _listener,
+        nameScope: new LibraryScope(_definingLibrary, _listener));
     try {
       return _visitor.elementResolver;
     } catch (exception) {
@@ -3589,6 +3548,36 @@
     verify([source]);
   }
 
+  void test_unnecessaryNoSuchMethod_blockBody() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    return super.noSuchMethod(y);
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_expressionBody() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => super.noSuchMethod(y);
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [HintCode.UNNECESSARY_NO_SUCH_METHOD]);
+    verify([source]);
+  }
+
   void test_unnecessaryTypeCheck_null_is_Null() {
     Source source = addSource("bool b = null is Null;");
     computeLibrarySourceErrors(source);
@@ -3773,6 +3762,22 @@
     verify([source]);
   }
 
+  void test_unusedElement_class_isUsed_fieldDeclaration() {
+    enableUnusedElement = true;
+    var src = r'''
+class Foo {
+  _Bar x;
+}
+
+class _Bar {
+}
+''';
+    Source source = addSource(src);
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_unusedElement_class_notUsed_variableDeclaration() {
     enableUnusedElement = true;
     Source source = addSource(r'''
@@ -4841,7 +4846,7 @@
 }
 
 @reflectiveTest
-class InheritanceManagerTest extends EngineTestCase {
+class InheritanceManagerTest {
   /**
    * The type provider used to access the types.
    */
@@ -4862,7 +4867,6 @@
    */
   int _numOfMembersInObject = 0;
 
-  @override
   void setUp() {
     _typeProvider = new TestTypeProvider();
     _inheritanceManager = _createInheritanceManager();
@@ -5099,7 +5103,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_getter_method() {
     // class I1 { int m(); }
     // class I2 { int get m; }
     // class A implements I2, I1 {}
@@ -5122,7 +5127,8 @@
         [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_int_str() {
     // class I1 { int m(); }
     // class I2 { String m(); }
     // class A implements I1, I2 {}
@@ -5132,8 +5138,8 @@
         ElementFactory.methodElement(methodName, null, [_typeProvider.intType]);
     classI1.methods = <MethodElement>[methodM1];
     ClassElementImpl classI2 = ElementFactory.classElement2("I2");
-    MethodElement methodM2 = ElementFactory.methodElement(
-        methodName, null, [_typeProvider.stringType]);
+    MethodElement methodM2 = ElementFactory
+        .methodElement(methodName, null, [_typeProvider.stringType]);
     classI2.methods = <MethodElement>[methodM2];
     ClassElementImpl classA = ElementFactory.classElement2("A");
     classA.interfaces = <InterfaceType>[classI1.type, classI2.type];
@@ -5145,7 +5151,8 @@
         classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_method_getter() {
     // class I1 { int m(); }
     // class I2 { int get m; }
     // class A implements I1, I2 {}
@@ -5168,7 +5175,8 @@
         [StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_numOfRequiredParams() {
     // class I1 { dynamic m(int, [int]); }
     // class I2 { dynamic m(int, int, int); }
     // class A implements I1, I2 {}
@@ -5217,14 +5225,15 @@
         classA, [StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE]);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_inconsistentMethodInheritance_str_int() {
     // class I1 { int m(); }
     // class I2 { String m(); }
     // class A implements I2, I1 {}
     ClassElementImpl classI1 = ElementFactory.classElement2("I1");
     String methodName = "m";
-    MethodElement methodM1 = ElementFactory.methodElement(
-        methodName, null, [_typeProvider.stringType]);
+    MethodElement methodM1 = ElementFactory
+        .methodElement(methodName, null, [_typeProvider.stringType]);
     classI1.methods = <MethodElement>[methodM1];
     ClassElementImpl classI2 = ElementFactory.classElement2("I2");
     MethodElement methodM2 =
@@ -5326,7 +5335,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_getters() {
     // class I1 { int get g; }
     // class I2 { num get g; }
     // class A implements I1, I2 {}
@@ -5350,7 +5360,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_methods() {
     // class I1 { dynamic m(int); }
     // class I2 { dynamic m(num); }
     // class A implements I1, I2 {}
@@ -5384,7 +5395,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_2_setters() {
     // class I1 { set s(int); }
     // class I2 { set s(num); }
     // class A implements I1, I2 {}
@@ -5409,7 +5421,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_getters() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5448,7 +5461,8 @@
     _assertNoErrors(classD);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_methods() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5502,7 +5516,8 @@
     _assertNoErrors(classD);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_multipleSubtypes_3_setters() {
     // class A {}
     // class B extends A {}
     // class C extends B {}
@@ -5542,7 +5557,8 @@
     _assertNoErrors(classD);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_2_methods() {
     // class I1 { int m(); }
     // class I2 { int m([int]); }
     // class A implements I1, I2 {}
@@ -5569,7 +5585,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_3_methods() {
     // class I1 { int m(); }
     // class I2 { int m([int]); }
     // class I3 { int m([int, int]); }
@@ -5614,7 +5631,8 @@
     _assertNoErrors(classA);
   }
 
-  void test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
+  void
+      test_getMapOfMembersInheritedFromInterfaces_union_oneSubtype_4_methods() {
     // class I1 { int m(); }
     // class I2 { int m(); }
     // class I3 { int m([int]); }
@@ -6066,217 +6084,6 @@
 }
 
 @reflectiveTest
-class LibraryElementBuilderTest extends EngineTestCase {
-  /**
-   * The analysis context used to analyze sources.
-   */
-  InternalAnalysisContext _context;
-
-  /**
-   * Add a source file to the content provider. The file path should be absolute.
-   *
-   * @param filePath the path of the file being added
-   * @param contents the contents to be returned by the content provider for the specified file
-   * @return the source object representing the added file
-   */
-  Source addSource(String filePath, String contents) {
-    Source source = new FileBasedSource(FileUtilities2.createFile(filePath));
-    _context.setContents(source, contents);
-    return source;
-  }
-
-  @override
-  void setUp() {
-    _context = AnalysisContextFactory.contextWithCore();
-  }
-
-  @override
-  void tearDown() {
-    _context = null;
-    super.tearDown();
-  }
-
-  void test_accessorsAcrossFiles() {
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'first.dart';
-part 'second.dart';''');
-    addSource(
-        "/first.dart",
-        r'''
-part of lib;
-int get V => 0;''');
-    addSource(
-        "/second.dart",
-        r'''
-part of lib;
-void set V(int v) {}''');
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    List<CompilationUnitElement> sourcedUnits = element.parts;
-    expect(sourcedUnits, hasLength(2));
-    List<PropertyAccessorElement> firstAccessors = sourcedUnits[0].accessors;
-    expect(firstAccessors, hasLength(1));
-    List<PropertyAccessorElement> secondAccessors = sourcedUnits[1].accessors;
-    expect(secondAccessors, hasLength(1));
-    expect(secondAccessors[0].variable, same(firstAccessors[0].variable));
-  }
-
-  void test_empty() {
-    Source librarySource = addSource("/lib.dart", "library lib;");
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    expect(element.name, "lib");
-    expect(element.entryPoint, isNull);
-    expect(element.importedLibraries, hasLength(0));
-    expect(element.imports, hasLength(0));
-    expect(element.library, same(element));
-    expect(element.prefixes, hasLength(0));
-    expect(element.parts, hasLength(0));
-    CompilationUnitElement unit = element.definingCompilationUnit;
-    expect(unit, isNotNull);
-    expect(unit.name, "lib.dart");
-    expect(unit.library, element);
-    expect(unit.accessors, hasLength(0));
-    expect(unit.functions, hasLength(0));
-    expect(unit.functionTypeAliases, hasLength(0));
-    expect(unit.types, hasLength(0));
-    expect(unit.topLevelVariables, hasLength(0));
-  }
-
-  void test_libraryElement_docRange() {
-    String code = r'''
-/// My dart doc.
-library lib;
-
-class A {}''';
-    Source librarySource = addSource("/lib.dart", code);
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    SourceRange docRange = element.docRange;
-    expect(docRange, isNotNull);
-    expect(docRange.offset, code.indexOf('/// My dart doc.'));
-    expect(docRange.length, '/// My dart doc.'.length);
-  }
-
-  void test_missingLibraryDirectiveWithPart() {
-    addSource("/a.dart", "part of lib;");
-    Source librarySource = addSource("/lib.dart", "part 'a.dart';");
-    LibraryElement element = _buildLibrary(
-        librarySource, [ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART]);
-    expect(element, isNotNull);
-  }
-
-  void test_missingPartOfDirective() {
-    addSource("/a.dart", "class A {}");
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-library lib;
-
-part 'a.dart';''');
-    LibraryElement element =
-        _buildLibrary(librarySource, [CompileTimeErrorCode.PART_OF_NON_PART]);
-    expect(element, isNotNull);
-  }
-
-  void test_multipleFiles() {
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-library lib;
-part 'first.dart';
-part 'second.dart';
-
-class A {}''');
-    addSource(
-        "/first.dart",
-        r'''
-part of lib;
-class B {}''');
-    addSource(
-        "/second.dart",
-        r'''
-part of lib;
-class C {}''');
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    List<CompilationUnitElement> sourcedUnits = element.parts;
-    expect(sourcedUnits, hasLength(2));
-    _assertTypes(element.definingCompilationUnit, ["A"]);
-    if (sourcedUnits[0].name == "first.dart") {
-      _assertTypes(sourcedUnits[0], ["B"]);
-      _assertTypes(sourcedUnits[1], ["C"]);
-    } else {
-      _assertTypes(sourcedUnits[0], ["C"]);
-      _assertTypes(sourcedUnits[1], ["B"]);
-    }
-  }
-
-  void test_singleFile() {
-    Source librarySource = addSource(
-        "/lib.dart",
-        r'''
-/// My dart doc.
-library lib;
-
-class A {}''');
-    LibraryElement element = _buildLibrary(librarySource);
-    expect(element, isNotNull);
-    _assertTypes(element.definingCompilationUnit, ["A"]);
-  }
-
-  /**
-   * Ensure that there are elements representing all of the types in the given array of type names.
-   *
-   * @param unit the compilation unit containing the types
-   * @param typeNames the names of the types that should be found
-   */
-  void _assertTypes(CompilationUnitElement unit, List<String> typeNames) {
-    expect(unit, isNotNull);
-    List<ClassElement> types = unit.types;
-    expect(types, hasLength(typeNames.length));
-    for (ClassElement type in types) {
-      expect(type, isNotNull);
-      String actualTypeName = type.displayName;
-      bool wasExpected = false;
-      for (String expectedTypeName in typeNames) {
-        if (expectedTypeName == actualTypeName) {
-          wasExpected = true;
-        }
-      }
-      if (!wasExpected) {
-        fail("Found unexpected type $actualTypeName");
-      }
-    }
-  }
-
-  /**
-   * Build the element model for the library whose defining compilation unit has the given source.
-   *
-   * @param librarySource the source of the defining compilation unit for the library
-   * @param expectedErrorCodes the errors that are expected to be found while building the element
-   *          model
-   * @return the element model that was built for the library
-   * @throws Exception if the element model could not be built
-   */
-  LibraryElement _buildLibrary(Source librarySource,
-      [List<ErrorCode> expectedErrorCodes = ErrorCode.EMPTY_LIST]) {
-    LibraryResolver resolver = new LibraryResolver(_context);
-    LibraryElementBuilder builder = new LibraryElementBuilder(
-        resolver.analysisContext, resolver.errorListener);
-    Library library = resolver.createLibrary(librarySource);
-    LibraryElement element = builder.buildLibrary(library);
-    GatheringErrorListener listener = new GatheringErrorListener();
-    listener.addAll2(resolver.errorListener);
-    listener.assertErrorsWithCodes(expectedErrorCodes);
-    return element;
-  }
-}
-
-@reflectiveTest
 class LibraryImportScopeTest extends ResolverTestCase {
   void test_conflictingImports() {
     AnalysisContext context = AnalysisContextFactory.contextWithCore();
@@ -6457,104 +6264,6 @@
 }
 
 @reflectiveTest
-class LibraryResolver2Test extends ResolverTestCase {
-  LibraryResolver2 _resolver;
-
-  Source _coreLibrarySource;
-
-  Source _asyncLibrarySource;
-
-  @override
-  void setUp() {
-    super.setUp();
-    _resolver = new LibraryResolver2(analysisContext2);
-    _coreLibrarySource =
-        analysisContext2.sourceFactory.forUri(DartSdk.DART_CORE);
-    _asyncLibrarySource =
-        analysisContext2.sourceFactory.forUri(DartSdk.DART_ASYNC);
-  }
-
-  void test_imports_relative() {
-    Source sourceA = addSource(r'''
-library libA;
-import 'libB.dart';
-class A {}''');
-    Source sourceB = addNamedSource(
-        "/libB.dart",
-        r'''
-library libB;
-import 'test.dart
-class B {}''');
-    List<ResolvableLibrary> cycle = new List<ResolvableLibrary>();
-    ResolvableLibrary coreLib = _createResolvableLibrary(_coreLibrarySource);
-    coreLib.libraryElement = analysisContext2
-        .computeLibraryElement(_coreLibrarySource) as LibraryElementImpl;
-    ResolvableLibrary asyncLib = _createResolvableLibrary(_asyncLibrarySource);
-    asyncLib.libraryElement = analysisContext2
-        .computeLibraryElement(_asyncLibrarySource) as LibraryElementImpl;
-    ResolvableLibrary libA = _createResolvableLibrary(sourceA);
-    ResolvableLibrary libB = _createResolvableLibrary(sourceB);
-    libA.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libB];
-    libB.importedLibraries = <ResolvableLibrary>[coreLib, asyncLib, libA];
-    cycle.add(libA);
-    cycle.add(libB);
-    LibraryElement library = _resolver.resolveLibrary(sourceA, cycle);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-  }
-
-  ResolvableLibrary _createResolvableLibrary(Source source) {
-    CompilationUnit unit = analysisContext2.parseCompilationUnit(source);
-    ResolvableLibrary resolvableLibrary = new ResolvableLibrary(source);
-    resolvableLibrary.resolvableCompilationUnits = <ResolvableCompilationUnit>[
-      new ResolvableCompilationUnit(source, unit)
-    ];
-    return resolvableLibrary;
-  }
-}
-
-@reflectiveTest
-class LibraryResolverTest extends ResolverTestCase {
-  LibraryResolver _resolver;
-
-  @override
-  void setUp() {
-    super.setUp();
-    _resolver = new LibraryResolver(analysisContext2);
-  }
-
-  void test_imports_dart_html() {
-    Source source = addSource(r'''
-library libA;
-import 'dart:html';
-class A {}''');
-    LibraryElement library = _resolver.resolveLibrary(source, true);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "dart.dom.html"]);
-  }
-
-  void test_imports_none() {
-    Source source = addSource(r'''
-library libA;
-class A {}''');
-    LibraryElement library = _resolver.resolveLibrary(source, true);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core"]);
-  }
-
-  void test_imports_relative() {
-    addNamedSource("/libB.dart", "library libB;");
-    Source source = addSource(r'''
-library libA;
-import 'libB.dart';
-class A {}''');
-    LibraryElement library = _resolver.resolveLibrary(source, true);
-    List<LibraryElement> importedLibraries = library.importedLibraries;
-    assertNamedElements(importedLibraries, ["dart.core", "libB"]);
-  }
-}
-
-@reflectiveTest
 class LibraryScopeTest extends ResolverTestCase {
   void test_creation_empty() {
     LibraryElement definingLibrary = createDefaultTestLibrary();
@@ -6591,112 +6300,6 @@
 }
 
 @reflectiveTest
-class LibraryTest extends EngineTestCase {
-  /**
-   * The error listener to which all errors will be reported.
-   */
-  GatheringErrorListener _errorListener;
-
-  /**
-   * The analysis context to pass in to all libraries created by the tests.
-   */
-  InternalAnalysisContext _analysisContext;
-
-  /**
-   * The library used by the tests.
-   */
-  Library _library;
-
-  @override
-  void setUp() {
-    _analysisContext = AnalysisContextFactory.contextWithCore();
-    _errorListener = new GatheringErrorListener();
-    _library = _createLibrary("/lib.dart");
-  }
-
-  @override
-  void tearDown() {
-    _errorListener = null;
-    _analysisContext = null;
-    _library = null;
-    super.tearDown();
-  }
-
-  void test_getExplicitlyImportsCore() {
-    expect(_library.explicitlyImportsCore, isFalse);
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getExports() {
-    expect(_library.exports, hasLength(0));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getImports() {
-    expect(_library.imports, hasLength(0));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getImportsAndExports() {
-    _library.importedLibraries = <Library>[_createLibrary("/imported.dart")];
-    _library.exportedLibraries = <Library>[_createLibrary("/exported.dart")];
-    expect(_library.importsAndExports, hasLength(2));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getLibraryScope() {
-    LibraryElementImpl element = new LibraryElementImpl.forNode(
-        _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
-    element.definingCompilationUnit =
-        new CompilationUnitElementImpl("lib.dart");
-    _library.libraryElement = element;
-    expect(_library.libraryScope, isNotNull);
-    _errorListener.assertNoErrors();
-  }
-
-  void test_getLibrarySource() {
-    expect(_library.librarySource, isNotNull);
-  }
-
-  void test_setExplicitlyImportsCore() {
-    _library.explicitlyImportsCore = true;
-    expect(_library.explicitlyImportsCore, isTrue);
-    _errorListener.assertNoErrors();
-  }
-
-  void test_setExportedLibraries() {
-    Library exportLibrary = _createLibrary("/exported.dart");
-    _library.exportedLibraries = <Library>[exportLibrary];
-    List<Library> exports = _library.exports;
-    expect(exports, hasLength(1));
-    expect(exports[0], same(exportLibrary));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_setImportedLibraries() {
-    Library importLibrary = _createLibrary("/imported.dart");
-    _library.importedLibraries = <Library>[importLibrary];
-    List<Library> imports = _library.imports;
-    expect(imports, hasLength(1));
-    expect(imports[0], same(importLibrary));
-    _errorListener.assertNoErrors();
-  }
-
-  void test_setLibraryElement() {
-    LibraryElementImpl element = new LibraryElementImpl.forNode(
-        _analysisContext, AstFactory.libraryIdentifier2(["lib"]));
-    _library.libraryElement = element;
-    expect(_library.libraryElement, same(element));
-  }
-
-  Library _createLibrary(String definingCompilationUnitPath) => new Library(
-      _analysisContext,
-      _errorListener,
-      new FileBasedSource(
-          FileUtilities2.createFile(definingCompilationUnitPath)));
-}
-
-@reflectiveTest
 class MemberMapTest {
   /**
    * The null type.
@@ -6742,61 +6345,6 @@
   }
 }
 
-/**
- * An analysis context that has a fake SDK that is much smaller and faster for
- * testing purposes.
- */
-class NewAnalysisContextForTests extends newContext.AnalysisContextImpl {
-  @override
-  void set analysisOptions(AnalysisOptions options) {
-    AnalysisOptions currentOptions = analysisOptions;
-    bool needsRecompute = currentOptions.analyzeFunctionBodiesPredicate !=
-            options.analyzeFunctionBodiesPredicate ||
-        currentOptions.generateImplicitErrors !=
-            options.generateImplicitErrors ||
-        currentOptions.generateSdkErrors != options.generateSdkErrors ||
-        currentOptions.dart2jsHint != options.dart2jsHint ||
-        (currentOptions.hint && !options.hint) ||
-        currentOptions.preserveComments != options.preserveComments ||
-        currentOptions.enableStrictCallChecks != options.enableStrictCallChecks;
-    if (needsRecompute) {
-      fail(
-          "Cannot set options that cause the sources to be reanalyzed in a test context");
-    }
-    super.analysisOptions = options;
-  }
-
-  @override
-  bool exists(Source source) =>
-      super.exists(source) || sourceFactory.dartSdk.context.exists(source);
-
-  @override
-  TimestampedData<String> getContents(Source source) {
-    if (source.isInSystemLibrary) {
-      return sourceFactory.dartSdk.context.getContents(source);
-    }
-    return super.getContents(source);
-  }
-
-  @override
-  int getModificationStamp(Source source) {
-    if (source.isInSystemLibrary) {
-      return sourceFactory.dartSdk.context.getModificationStamp(source);
-    }
-    return super.getModificationStamp(source);
-  }
-
-  /**
-   * Set the analysis options, even if they would force re-analysis. This method should only be
-   * invoked before the fake SDK is initialized.
-   *
-   * @param options the analysis options to be set
-   */
-  void _internalSetAnalysisOptions(AnalysisOptions options) {
-    super.analysisOptions = options;
-  }
-}
-
 @reflectiveTest
 class NonHintCodeTest extends ResolverTestCase {
   void test_deadCode_deadBlock_conditionalElse_debugConst() {
@@ -7581,6 +7129,67 @@
     verify([source]);
   }
 
+  void test_unnecessaryNoSuchMethod_blockBody_notReturnStatement() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    print(y);
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_blockBody_notSingleStatement() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) {
+    print(y);
+    return super.noSuchMethod(y);
+  }
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_expressionBody_notNoSuchMethod() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => super.hashCode;
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_unnecessaryNoSuchMethod_expressionBody_notSuper() {
+    Source source = addSource(r'''
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x);
+}
+class B extends A {
+  mmm();
+  noSuchMethod(y) => 42;
+}''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_unusedImport_annotationOnDirective() {
     Source source = addSource(r'''
 library L;
@@ -8427,6 +8036,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     reset();
   }
 
@@ -9724,7 +9334,9 @@
     expect(declarations, hasLength(2));
     Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
         .variables
-        .variables[0].name.staticElement;
+        .variables[0]
+        .name
+        .staticElement;
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
         PropertyInducingElement, expectedElement);
     expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -9915,7 +9527,9 @@
     expect(declarations, hasLength(2));
     Element expectedElement = (declarations[0] as TopLevelVariableDeclaration)
         .variables
-        .variables[0].name.staticElement;
+        .variables[0]
+        .name
+        .staticElement;
     EngineTestCase.assertInstanceOf((obj) => obj is PropertyInducingElement,
         PropertyInducingElement, expectedElement);
     expectedElement = (expectedElement as PropertyInducingElement).getter;
@@ -10363,6 +9977,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     _listener = new GatheringErrorListener();
     _typeProvider = new TestTypeProvider();
     _analyzer = _createAnalyzer();
@@ -11630,12 +11245,9 @@
     LibraryElementImpl definingLibrary =
         new LibraryElementImpl.forNode(context, null);
     definingLibrary.definingCompilationUnit = definingCompilationUnit;
-    Library library = new Library(context, _listener, source);
-    library.libraryElement = definingLibrary;
     _visitor = new ResolverVisitor(
-        library.libraryElement, source, _typeProvider, library.errorListener,
-        nameScope: library.libraryScope,
-        inheritanceManager: library.inheritanceManager);
+        definingLibrary, source, _typeProvider, _listener,
+        nameScope: new LibraryScope(definingLibrary, _listener));
     _visitor.overrideManager.enterScope();
     try {
       return _visitor.typeAnalyzer;
@@ -12140,17 +11752,17 @@
   TypeAssertions _assertions;
   AsserterBuilder<Element, DartType> _hasElement;
   AsserterBuilder<DartType, DartType> _isType;
-  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>,
-      DartType> _isFunction2Of;
-  AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>,
-      DartType> _isInstantiationOf;
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, DartType>
+      _isFunction2Of;
+  AsserterBuilderBuilder<Asserter<DartType>, List<Asserter<DartType>>, DartType>
+      _isInstantiationOf;
   Asserter<DartType> _isInt;
   Asserter<DartType> _isNum;
   Asserter<DartType> _isString;
   Asserter<DartType> _isDynamic;
   AsserterBuilder<Asserter<DartType>, InterfaceType> _isListOf;
-  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>,
-      InterfaceType> _isMapOf;
+  AsserterBuilder2<Asserter<DartType>, Asserter<DartType>, InterfaceType>
+      _isMapOf;
 
   @override
   void setUp() {
@@ -12594,7 +12206,7 @@
         List<int> l0 = [];
      }
    ''');
-    LibraryElement library = resolve2(source);
+    resolve2(source);
     assertNoErrors(source);
     verify([source]);
   }
@@ -13153,9 +12765,6 @@
   }
 
   void test_genericFunction() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     _resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
     SimpleIdentifier f = _findIdentifier('f');
     FunctionElementImpl e = f.staticElement;
@@ -13168,10 +12777,113 @@
     expect(ft.toString(), '(String) → String');
   }
 
-  void test_genericMethod() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
+  void test_genericFunction_bounds() {
+    _resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
+    SimpleIdentifier f = _findIdentifier('f');
+    FunctionElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T extends num]');
+    expect(e.type.boundTypeParameters.toString(), '[T extends num]');
+    expect(e.type.typeParameters.toString(), '[]');
+    expect(e.type.toString(), '<T extends num>(T) → T');
+  }
+
+  void test_genericFunction_static() {
+    _resolveTestUnit(r'''
+class C<E> {
+  static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+''');
+    SimpleIdentifier f = _findIdentifier('f');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.boundTypeParameters.toString(), '[T]');
+    // TODO(jmesserly): we could get rid of this {E/E} substitution, but it's
+    // probably harmless, as E won't be used in the function (error verifier
+    // checks this), and {E/E} is a no-op anyway.
+    expect(e.type.typeParameters.toString(), '[E]');
+    expect(e.type.typeArguments.toString(), '[E]');
+    expect(e.type.toString(), '<T>(T) → T');
+
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  void test_genericFunction_typedef() {
+    String code = r'''
+typedef T F<T>(T x);
+F f0;
+
+class C {
+  static F f1;
+  F f2;
+  void g(F f3) {
+    F f4;
+    f0(3);
+    f1(3);
+    f2(3);
+    f3(3);
+    f4(3);
+  }
+}
+
+class D<S> {
+  static F f1;
+  F f2;
+  void g(F f3) {
+    F f4;
+    f0(3);
+    f1(3);
+    f2(3);
+    f3(3);
+    f4(3);
+  }
+}
+''';
+    _resolveTestUnit(code);
+
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInMethod(testUnit, "C", "g");
+
+      ExpressionStatement exps0 = statements[1];
+      ExpressionStatement exps1 = statements[2];
+      ExpressionStatement exps2 = statements[3];
+      ExpressionStatement exps3 = statements[4];
+      ExpressionStatement exps4 = statements[5];
+      Expression exp0 = exps0.expression;
+      Expression exp1 = exps1.expression;
+      Expression exp2 = exps2.expression;
+      Expression exp3 = exps3.expression;
+      Expression exp4 = exps4.expression;
+      expect(exp0.staticType, typeProvider.dynamicType);
+      expect(exp1.staticType, typeProvider.dynamicType);
+      expect(exp2.staticType, typeProvider.dynamicType);
+      expect(exp3.staticType, typeProvider.dynamicType);
+      expect(exp4.staticType, typeProvider.dynamicType);
     }
+    {
+      List<Statement> statements =
+          AstFinder.getStatementsInMethod(testUnit, "D", "g");
+
+      ExpressionStatement exps0 = statements[1];
+      ExpressionStatement exps1 = statements[2];
+      ExpressionStatement exps2 = statements[3];
+      ExpressionStatement exps3 = statements[4];
+      ExpressionStatement exps4 = statements[5];
+      Expression exp0 = exps0.expression;
+      Expression exp1 = exps1.expression;
+      Expression exp2 = exps2.expression;
+      Expression exp3 = exps3.expression;
+      Expression exp4 = exps4.expression;
+      expect(exp0.staticType, typeProvider.dynamicType);
+      expect(exp1.staticType, typeProvider.dynamicType);
+      expect(exp2.staticType, typeProvider.dynamicType);
+      expect(exp3.staticType, typeProvider.dynamicType);
+      expect(exp4.staticType, typeProvider.dynamicType);
+    }
+  }
+
+  void test_genericMethod() {
     _resolveTestUnit(r'''
 class C<E> {
   List/*<T>*/ f/*<T>*/(E e) => null;
@@ -13196,10 +12908,27 @@
     expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
   }
 
+  void test_genericMethod_explicitTypeParams() {
+    _resolveTestUnit(r'''
+class C<E> {
+  List/*<T>*/ f/*<T>*/(E e) => null;
+}
+main() {
+  C<String> cOfString;
+  var x = cOfString.f/*<int>*/('hi');
+}
+''');
+    SimpleIdentifier f = _findIdentifier('f/*<int>*/');
+    FunctionType ft = f.staticType;
+    expect(ft.toString(), '(String) → List<int>');
+    expect('${ft.typeArguments}/${ft.typeParameters}', '[String, int]/[E, T]');
+
+    SimpleIdentifier x = _findIdentifier('x');
+    expect(x.staticType,
+        typeProvider.listType.substitute4([typeProvider.intType]));
+  }
+
   void test_genericMethod_functionTypedParameter() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     _resolveTestUnit(r'''
 class C<E> {
   List/*<T>*/ f/*<T>*/(/*=T*/ f(E e)) => null;
@@ -13223,6 +12952,28 @@
     expect(ft.toString(), '((String) → int) → List<int>');
   }
 
+  void test_genericMethod_implicitDynamic() {
+    // Regression test for:
+    // https://github.com/dart-lang/sdk/issues/25100#issuecomment-162047588
+    // These should not cause any hints or warnings.
+    _resolveTestUnit(r'''
+class List<E> {
+  /*=T*/ map/*<T>*/(/*=T*/ f(E e)) => null;
+}
+void foo() {
+  List list = null;
+  list.map((e) => e);
+  list.map((e) => 3);
+}''');
+
+    SimpleIdentifier map1 = _findIdentifier('map((e) => e);');
+    expect(map1.staticType.toString(), '((dynamic) → dynamic) → dynamic');
+    expect(map1.propagatedType, isNull);
+    SimpleIdentifier map2 = _findIdentifier('map((e) => 3);');
+    expect(map2.staticType.toString(), '((dynamic) → int) → int');
+    expect(map2.propagatedType, isNull);
+  }
+
   void test_genericMethod_nestedCapture() {
     _resolveTestUnit(r'''
 class C<T> {
@@ -13255,6 +13006,98 @@
     expect(f.staticType.toString(), '<S>(S) → dynamic');
   }
 
+  void test_genericMethod_override() {
+    _resolveTestUnit(r'''
+class C {
+  /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
+}
+''');
+    SimpleIdentifier f =
+        _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
+    MethodElementImpl e = f.staticElement;
+    expect(e.typeParameters.toString(), '[T]');
+    expect(e.type.boundTypeParameters.toString(), '[T]');
+    expect(e.type.toString(), '<T>(T) → T');
+
+    FunctionType ft = e.type.instantiate([typeProvider.stringType]);
+    expect(ft.toString(), '(String) → String');
+  }
+
+  void test_genericMethod_override_bounds() {
+    _resolveTestUnit(r'''
+class A {}
+class B extends A {}
+class C {
+  /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+''');
+  }
+
+  void test_genericMethod_override_invalidReturnType() {
+    Source source = addSource(r'''
+class C {
+  Iterable/*<T>*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  String f/*<S>*/(/*=S*/ x) => null;
+}''');
+    // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+    // from CodeChecker don't have working equality.
+    List<AnalysisError> errors = analysisContext2.computeErrors(source);
+    expect(errors.map((e) => e.errorCode.name), [
+      'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
+      'STRONG_MODE_INVALID_METHOD_OVERRIDE'
+    ]);
+    expect(errors[0].message, contains('Iterable<S>'),
+        reason: 'errors should be in terms of the type parameters '
+            'at the error location');
+    verify([source]);
+  }
+
+  void test_genericMethod_override_invalidTypeParamBounds() {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C {
+  /*=T*/ f/*<T extends A>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=T*/ f/*<T extends B>*/(/*=T*/ x) => null;
+}''');
+    // TODO(jmesserly): this is modified code from assertErrors, which we can't
+    // use directly because STRONG_MODE_* errors don't have working equality.
+    List<AnalysisError> errors = analysisContext2.computeErrors(source);
+    expect(errors.map((e) => e.errorCode.name), [
+      'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+      'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND'
+    ]);
+    verify([source]);
+  }
+
+  void test_genericMethod_override_invalidTypeParamCount() {
+    Source source = addSource(r'''
+class C {
+  /*=T*/ f/*<T>*/(/*=T*/ x) => null;
+}
+class D extends C {
+  /*=S*/ f/*<T, S>*/(/*=T*/ x) => null;
+}''');
+    // TODO(jmesserly): we can't use assertErrors because STRONG_MODE_* errors
+    // from CodeChecker don't have working equality.
+    List<AnalysisError> errors = analysisContext2.computeErrors(source);
+    expect(errors.map((e) => e.errorCode.name), [
+      'STRONG_MODE_INVALID_METHOD_OVERRIDE',
+      'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS'
+    ]);
+    verify([source]);
+  }
+
   void test_pseudoGeneric_max_doubleDouble() {
     String code = r'''
 import 'dart:math';
@@ -13525,9 +13368,6 @@
   }
 
   void test_localVariableInference_transitive_field_inferred_lexical() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 class A {
   final x = 3;
@@ -13544,9 +13384,6 @@
   }
 
   void test_localVariableInference_transitive_field_inferred_reversed() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 class A {
   f() {
@@ -13617,9 +13454,6 @@
   }
 
   void test_localVariableInference_transitive_toplevel_inferred_lexical() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 final x = 3;
 main() {
@@ -13632,9 +13466,6 @@
   }
 
   void test_localVariableInference_transitive_toplevel_inferred_reversed() {
-    if (!AnalysisEngine.instance.useTaskModel) {
-      return;
-    }
     String code = r'''
 main() {
   var v = x;
@@ -13672,7 +13503,7 @@
 }
 
 @reflectiveTest
-class SubtypeManagerTest extends EngineTestCase {
+class SubtypeManagerTest {
   /**
    * The inheritance manager being tested.
    */
@@ -13683,9 +13514,7 @@
    */
   CompilationUnitElementImpl _definingCompilationUnit;
 
-  @override
   void setUp() {
-    super.setUp();
     AnalysisContext context = AnalysisContextFactory.contextWithCore();
     FileBasedSource source =
         new FileBasedSource(FileUtilities2.createFile("/test.dart"));
@@ -14131,8 +13960,6 @@
   }
 
   void test_finalPropertyInducingVariable_classMember_instance() {
-    // TODO(scheglov) remove after switching to the task model
-    if (!AnalysisEngine.instance.useTaskModel) return;
     addNamedSource(
         "/lib.dart",
         r'''
@@ -14149,8 +13976,6 @@
   }
 
   void test_finalPropertyInducingVariable_classMember_instance_inherited() {
-    // TODO(scheglov) remove after switching to the task model
-    if (!AnalysisEngine.instance.useTaskModel) return;
     addNamedSource(
         "/lib.dart",
         r'''
@@ -14168,9 +13993,8 @@
         code, typeProvider.dynamicType, typeProvider.intType);
   }
 
-  void test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
-    // TODO(scheglov) remove after switching to the task model
-    if (!AnalysisEngine.instance.useTaskModel) return;
+  void
+      test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
     addNamedSource(
         "/lib.dart",
         r'''
@@ -14189,8 +14013,6 @@
   }
 
   void test_finalPropertyInducingVariable_classMember_instance_unprefixed() {
-    // TODO(scheglov) remove after switching to the task model
-    if (!AnalysisEngine.instance.useTaskModel) return;
     String code = r'''
 class A {
   final v = 0;
@@ -14203,8 +14025,6 @@
   }
 
   void test_finalPropertyInducingVariable_classMember_static() {
-    // TODO(scheglov) remove after switching to the task model
-    if (!AnalysisEngine.instance.useTaskModel) return;
     addNamedSource(
         "/lib.dart",
         r'''
@@ -14221,8 +14041,6 @@
   }
 
   void test_finalPropertyInducingVariable_topLevelVariable_prefixed() {
-    // TODO(scheglov) remove after switching to the task model
-    if (!AnalysisEngine.instance.useTaskModel) return;
     addNamedSource("/lib.dart", "final V = 0;");
     String code = r'''
 import 'lib.dart' as p;
@@ -14234,8 +14052,6 @@
   }
 
   void test_finalPropertyInducingVariable_topLevelVariable_simple() {
-    // TODO(scheglov) remove after switching to the task model
-    if (!AnalysisEngine.instance.useTaskModel) return;
     addNamedSource("/lib.dart", "final V = 0;");
     String code = r'''
 import 'lib.dart';
@@ -14397,7 +14213,8 @@
     expect(vParameter.identifier.propagatedType, same(stringType));
   }
 
-  void test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
+  void
+      test_functionExpression_asInvocationArgument_functionExpressionInvocation() {
     String code = r'''
 main() {
   (f(String value)) {} ((v) {
@@ -15571,24 +15388,23 @@
 }
 
 @reflectiveTest
-class TypeResolverVisitorTest extends EngineTestCase {
+class TypeResolverVisitorTest {
   /**
    * The error listener to which errors will be reported.
    */
   GatheringErrorListener _listener;
 
   /**
-   * The object representing the information about the library in which the types are being
-   * resolved.
-   */
-  Library _library;
-
-  /**
    * The type provider used to access the types.
    */
   TestTypeProvider _typeProvider;
 
   /**
+   * The library scope in which types are to be resolved.
+   */
+  LibraryScope libraryScope;
+
+  /**
    * The visitor used to resolve types needed to form the type hierarchy.
    */
   TypeResolverVisitor _visitor;
@@ -15613,22 +15429,20 @@
     _listener.assertNoErrors();
   }
 
-  @override
   void setUp() {
     _listener = new GatheringErrorListener();
     InternalAnalysisContext context = AnalysisContextFactory.contextWithCore();
     Source librarySource =
         new FileBasedSource(FileUtilities2.createFile("/lib.dart"));
-    _library = new Library(context, _listener, librarySource);
     LibraryElementImpl element = new LibraryElementImpl.forNode(
         context, AstFactory.libraryIdentifier2(["lib"]));
     element.definingCompilationUnit =
         new CompilationUnitElementImpl("lib.dart");
-    _library.libraryElement = element;
     _typeProvider = new TestTypeProvider();
-    _visitor = new TypeResolverVisitor(_library.libraryElement, librarySource,
-        _typeProvider, _library.errorListener,
-        nameScope: _library.libraryScope);
+    libraryScope = new LibraryScope(element, _listener);
+    _visitor = new TypeResolverVisitor(
+        element, librarySource, _typeProvider, _listener,
+        nameScope: libraryScope);
   }
 
   void test_visitCatchClause_exception() {
@@ -16188,7 +16002,7 @@
   void _resolveNode(AstNode node, [List<Element> definedElements]) {
     if (definedElements != null) {
       for (Element element in definedElements) {
-        _library.libraryScope.define(element);
+        libraryScope.define(element);
       }
     }
     node.accept(_visitor);
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index a0c7355..d0d8949 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.scanner_test;
+library analyzer.test.generated.scanner_test;
 
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index c16f1f8..e9dfd94 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -2,7 +2,7 @@
 // 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.generated.source_factory;
+library analyzer.test.generated.test.generated.source_factory;
 
 import 'dart:convert';
 
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index d98f837..2c1e2d2 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.static_type_warning_code_test;
+library analyzer.test.generated.static_type_warning_code_test;
 
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -58,6 +58,30 @@
     assertErrors(source, [StaticWarningCode.AMBIGUOUS_IMPORT]);
   }
 
+  void test_assert_message_suppresses_type_promotion() {
+    // If a variable is assigned to inside the expression for an assert
+    // message, type promotion should be suppressed, just as it would be if the
+    // assignment occurred outside an assert statement.  (Note that it is a
+    // dubious practice for the computation of an assert message to have side
+    // effects, since it is only evaluated if the assert fails).
+    resetWithOptions(new AnalysisOptionsImpl()..enableAssertMessage = true);
+    Source source = addSource('''
+class C {
+  void foo() {}
+}
+
+f(Object x) {
+  if (x is C) {
+    x.foo();
+    assert(true, () { x = new C(); return 'msg'; }());
+  }
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+    // Do not verify since `x.foo()` fails to resolve.
+  }
+
   void test_await_flattened() {
     Source source = addSource('''
 import 'dart:async';
@@ -1098,7 +1122,8 @@
     verify([source]);
   }
 
-  void test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() {
+  void
+      test_typePromotion_booleanAnd_useInRight_accessedInClosureRight_mutated() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -1127,7 +1152,8 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
   }
 
-  void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() {
+  void
+      test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_after() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -1138,7 +1164,8 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
   }
 
-  void test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() {
+  void
+      test_typePromotion_conditional_useInThen_accessedInClosure_hasAssignment_before() {
     Source source = addSource(r'''
 callMe(f()) { f(); }
 main(Object p) {
@@ -1418,6 +1445,18 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
   }
 
+  void test_undefinedGetter_typeLiteral_cascadeTarget() {
+    Source source = addSource(r'''
+class T {
+  static int get foo => 42;
+}
+main() {
+  T..foo;
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_GETTER]);
+  }
+
   void test_undefinedGetter_typeLiteral_conditionalAccess() {
     // When applied to a type literal, the conditional access operator '?.'
     // cannot be used to access instance getters of Type.
@@ -1589,6 +1628,19 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
   }
 
+  void test_undefinedMethod_typeLiteral_cascadeTarget() {
+    Source source = addSource('''
+class T {
+  static void foo() {}
+}
+main() {
+  T..foo();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
   void test_undefinedMethod_typeLiteral_conditionalAccess() {
     // When applied to a type literal, the conditional access operator '?.'
     // cannot be used to access instance methods of Type.
@@ -1689,6 +1741,18 @@
     assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
   }
 
+  void test_undefinedSetter_typeLiteral_cascadeTarget() {
+    Source source = addSource(r'''
+class T {
+  static void set foo(_) {}
+}
+main() {
+  T..foo = 42;
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_SETTER]);
+  }
+
   void test_undefinedSetter_void() {
     Source source = addSource(r'''
 class T {
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index f48528e..eb6aa8b 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.static_warning_code_test;
+library analyzer.test.generated.static_warning_code_test;
 
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 0a9a727..48bbfb2 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.generated;
+library analyzer.test.generated.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 20cc0e2..b3e9215 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.test_support;
+library analyzer.test.generated.test_support;
 
 import 'dart:collection';
 
@@ -13,6 +13,8 @@
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:unittest/unittest.dart';
 
 import 'resolver_test.dart';
@@ -91,7 +93,13 @@
     return null;
   }
 
-  void setUp() {}
+  void setUp() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+    new ExtensionManager().processPlugins(plugins);
+  }
 
   void tearDown() {}
 
@@ -530,19 +538,9 @@
   }
 
   @override
-  void logError2(String message, Object exception) {
-    errorCount++;
-  }
-
-  @override
   void logInformation(String message, [CaughtException exception]) {
     infoCount++;
   }
-
-  @override
-  void logInformation2(String message, Object exception) {
-    infoCount++;
-  }
 }
 
 class TestSource extends Source {
@@ -557,10 +555,6 @@
    */
   bool generateExceptionOnRead = false;
 
-  @override
-  int get modificationStamp =>
-      generateExceptionOnRead ? -1 : _modificationStamp;
-
   /**
    * The number of times that the contents of this source have been requested.
    */
@@ -586,10 +580,15 @@
   }
 
   int get hashCode => 0;
+
   bool get isInSystemLibrary {
     return false;
   }
 
+  @override
+  int get modificationStamp =>
+      generateExceptionOnRead ? -1 : _modificationStamp;
+
   String get shortName {
     return _name;
   }
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index e4501be..cd16dcf 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -4,7 +4,7 @@
 
 // Tests related to the [TypeSystem] class.
 
-library engine.type_system_test;
+library analyzer.test.generated.type_system_test;
 
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -66,7 +66,8 @@
         ElementFactory.methodElement("call", objectType, <DartType>[intType]);
     classBottom.methods = <MethodElement>[methodBottom];
 
-    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
+    DartType top =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
     InterfaceType bottom = classBottom.type;
 
     _checkIsStrictAssignableTo(bottom, top);
@@ -117,14 +118,14 @@
   }
 
   void test_isAssignableTo_fuzzy_arrows() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
-    FunctionType left =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], bottomType);
+    FunctionType top = TypeBuilder.function(
+        required: <DartType>[dynamicType], result: objectType);
+    FunctionType left = TypeBuilder.function(
+        required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder.function(
+        required: <DartType>[dynamicType], result: bottomType);
+    FunctionType bottom = TypeBuilder.function(
+        required: <DartType>[objectType], result: bottomType);
 
     _checkCrossLattice(top, left, right, bottom);
   }
@@ -166,23 +167,36 @@
   }
 
   void test_isAssignableTo_named_optional() {
-    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
-    DartType o = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType]);
-    DartType n = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType});
-    DartType rr =
-        TypeBuilder.functionType(<DartType>[intType, intType], intType);
-    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
-        optional: <DartType>[intType]);
-    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
-        named: <String, DartType>{'x': intType});
-    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType, intType]);
-    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType});
-    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
+    DartType r =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    DartType o = TypeBuilder.function(
+        required: <DartType>[], optional: <DartType>[intType], result: intType);
+    DartType n = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType rr = TypeBuilder.function(
+        required: <DartType>[intType, intType], result: intType);
+    DartType ro = TypeBuilder.function(
+        required: <DartType>[intType],
+        optional: <DartType>[intType],
+        result: intType);
+    DartType rn = TypeBuilder.function(
+        required: <DartType>[intType],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType oo = TypeBuilder.function(
+        required: <DartType>[],
+        optional: <DartType>[intType, intType],
+        result: intType);
+    DartType nn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType},
+        result: intType);
+    DartType nnn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
+        result: intType);
 
     _checkGroups(r,
         interassignable: [r, o, ro, rn, oo], unrelated: [n, rr, nn, nnn]);
@@ -220,20 +234,22 @@
 
   void test_isAssignableTo_simple_function() {
     FunctionType top =
-        TypeBuilder.functionType(<DartType>[intType], objectType);
-    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    FunctionType left =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    FunctionType right = TypeBuilder.function(
+        required: <DartType>[objectType], result: objectType);
     FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
 
     _checkCrossLattice(top, left, right, bottom);
   }
 
   void test_isAssignableTo_void_functions() {
-    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
+    FunctionType top =
+        TypeBuilder.function(required: <DartType>[intType], result: voidType);
     FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
 
     _checkEquivalent(bottom, top);
   }
@@ -320,9 +336,11 @@
 
   void test_boundedByAnotherTypeParameter() {
     // <TFrom, TTo extends Iterable<TFrom>>(TFrom) -> TTo
-    var tFrom = _typeParameter('TFrom');
-    var tTo = _typeParameter('TTo', iterableType.substitute4([tFrom]));
-    var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+    var tFrom = TypeBuilder.variable('TFrom');
+    var tTo =
+        TypeBuilder.variable('TTo', bound: iterableType.substitute4([tFrom]));
+    var cast = TypeBuilder.function(
+        types: [tFrom, tTo], required: [tFrom], result: tTo);
     expect(_inferCall(cast, [stringType]), [
       stringType,
       iterableType.substitute4([stringType])
@@ -340,11 +358,11 @@
     foo.supertype = clonable.type.substitute4([foo.type]);
 
     // <S extends Clonable<S>>
-    var s = _typeParameter('S');
+    var s = TypeBuilder.variable('S');
     (s.element as TypeParameterElementImpl).bound =
         clonable.type.substitute4([s]);
     // (S, S) -> S
-    var clone = _functionType([s], [s, s], s);
+    var clone = TypeBuilder.function(types: [s], required: [s, s], result: s);
     expect(_inferCall(clone, [foo.type, foo.type]), [foo.type]);
 
     // Something invalid...
@@ -355,141 +373,133 @@
 
   void test_genericCastFunction() {
     // <TFrom, TTo>(TFrom) -> TTo
-    var tFrom = _typeParameter('TFrom');
-    var tTo = _typeParameter('TTo');
-    var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+    var tFrom = TypeBuilder.variable('TFrom');
+    var tTo = TypeBuilder.variable('TTo');
+    var cast = TypeBuilder.function(
+        types: [tFrom, tTo], required: [tFrom], result: tTo);
     expect(_inferCall(cast, [intType]), [intType, dynamicType]);
   }
 
   void test_genericCastFunctionWithUpperBound() {
     // <TFrom, TTo extends TFrom>(TFrom) -> TTo
-    var tFrom = _typeParameter('TFrom');
-    var tTo = _typeParameter('TTo', tFrom);
-    var cast = _functionType([tFrom, tTo], [tFrom], tTo);
+    var tFrom = TypeBuilder.variable('TFrom');
+    var tTo = TypeBuilder.variable('TTo', bound: tFrom);
+    var cast = TypeBuilder.function(
+        types: [tFrom, tTo], required: [tFrom], result: tTo);
     expect(_inferCall(cast, [intType]), [intType, intType]);
   }
 
   void test_parametersToFunctionParam() {
     // <T>(f(T t)) -> T
-    var t = _typeParameter('T');
-    var cast = _functionType([
+    var t = TypeBuilder.variable('T');
+    var cast = TypeBuilder.function(types: [
       t
-    ], [
-      _functionType([], [t], dynamicType)
-    ], t);
+    ], required: [
+      TypeBuilder.function(required: [t], result: dynamicType)
+    ], result: t);
     expect(
         _inferCall(cast, [
-          _functionType([], [numType], dynamicType)
+          TypeBuilder.function(required: [numType], result: dynamicType)
         ]),
         [numType]);
   }
 
   void test_parametersUseLeastUpperBound() {
     // <T>(T x, T y) -> T
-    var t = _typeParameter('T');
-    var cast = _functionType([t], [t, t], t);
+    var t = TypeBuilder.variable('T');
+    var cast = TypeBuilder.function(types: [t], required: [t, t], result: t);
     expect(_inferCall(cast, [intType, doubleType]), [numType]);
   }
 
   void test_parameterTypeUsesUpperBound() {
     // <T extends num>(T) -> dynamic
-    var t = _typeParameter('T', numType);
-    var f = _functionType([t], [t], dynamicType);
+    var t = TypeBuilder.variable('T', bound: numType);
+    var f =
+        TypeBuilder.function(types: [t], required: [t], result: dynamicType);
     expect(_inferCall(f, [intType]), [intType]);
   }
 
   void test_returnFunctionWithGenericParameter() {
     // <T>(T -> T) -> (T -> void)
-    var t = _typeParameter('T');
-    var f = _functionType([
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [
       t
-    ], [
-      _functionType([], [t], t)
-    ], _functionType([], [t], voidType));
+    ], required: [
+      TypeBuilder.function(required: [t], result: t)
+    ], result: TypeBuilder.function(required: [t], result: voidType));
     expect(
         _inferCall(f, [
-          _functionType([], [numType], intType)
+          TypeBuilder.function(required: [numType], result: intType)
         ]),
         [numType]);
   }
 
   void test_returnFunctionWithGenericParameterAndReturn() {
     // <T>(T -> T) -> (T -> T)
-    var t = _typeParameter('T');
-    var f = _functionType([
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [
       t
-    ], [
-      _functionType([], [t], t)
-    ], _functionType([], [t], t));
+    ], required: [
+      TypeBuilder.function(required: [t], result: t)
+    ], result: TypeBuilder.function(required: [t], result: t));
     expect(
         _inferCall(f, [
-          _functionType([], [numType], intType)
+          TypeBuilder.function(required: [numType], result: intType)
         ]),
         [numType]);
   }
 
   void test_returnFunctionWithGenericReturn() {
     // <T>(T -> T) -> (() -> T)
-    var t = _typeParameter('T');
-    var f = _functionType([
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [
       t
-    ], [
-      _functionType([], [t], t)
-    ], _functionType([], [], t));
+    ], required: [
+      TypeBuilder.function(required: [t], result: t)
+    ], result: TypeBuilder.function(required: [], result: t));
     expect(
         _inferCall(f, [
-          _functionType([], [numType], intType)
+          TypeBuilder.function(required: [numType], result: intType)
         ]),
         [intType]);
   }
 
   void test_unifyParametersToFunctionParam() {
     // <T>(f(T t), g(T t)) -> T
-    var t = _typeParameter('T');
-    var cast = _functionType([
+    var t = TypeBuilder.variable('T');
+    var cast = TypeBuilder.function(types: [
       t
-    ], [
-      _functionType([], [t], dynamicType),
-      _functionType([], [t], dynamicType)
-    ], t);
+    ], required: [
+      TypeBuilder.function(required: [t], result: dynamicType),
+      TypeBuilder.function(required: [t], result: dynamicType)
+    ], result: t);
     expect(
         _inferCall(cast, [
-          _functionType([], [intType], dynamicType),
-          _functionType([], [doubleType], dynamicType)
+          TypeBuilder.function(required: [intType], result: dynamicType),
+          TypeBuilder.function(required: [doubleType], result: dynamicType)
         ]),
         [dynamicType]);
   }
 
   void test_unusedReturnTypeIsDynamic() {
     // <T>() -> T
-    var t = _typeParameter('T');
-    var f = _functionType([t], [], t);
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [t], required: [], result: t);
     expect(_inferCall(f, []), [dynamicType]);
   }
 
   void test_unusedReturnTypeWithUpperBound() {
     // <T extends num>() -> T
-    var t = _typeParameter('T', numType);
-    var f = _functionType([t], [], t);
+    var t = TypeBuilder.variable('T', bound: numType);
+    var f = TypeBuilder.function(types: [t], required: [], result: t);
     expect(_inferCall(f, []), [numType]);
   }
 
-  FunctionTypeImpl _functionType(
-      List<DartType> typeParams, List<DartType> params, DartType result) {
-    FunctionElementImpl f = ElementFactory.functionElement8(params, result);
-    f.typeParameters =
-        new List<TypeParameterElement>.from(typeParams.map((t) => t.element));
-    return f.type = new FunctionTypeImpl(f);
-  }
-
   List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments) {
     FunctionType inferred = typeSystem.inferCallFromArguments(
         typeProvider, ft, ft.parameters.map((p) => p.type).toList(), arguments);
     return inferred.typeArguments;
   }
-
-  TypeParameterType _typeParameter(String name, [DartType bound]) =>
-      ElementFactory.typeParameterWithType(name, bound).type;
 }
 
 @reflectiveTest
@@ -513,7 +523,7 @@
     typeSystem = new StrongTypeSystemImpl();
   }
 
-  void test_isSubtypeOf_bottom_isBottom() {
+  void test_bottom_isBottom() {
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
     List<DartType> equivalents = <DartType>[bottomType];
     List<DartType> supertypes = <DartType>[
@@ -529,19 +539,20 @@
     _checkGroups(bottomType, equivalents: equivalents, supertypes: supertypes);
   }
 
-  void test_isSubtypeOf_call_method() {
+  void test_call_method() {
     ClassElementImpl classBottom = ElementFactory.classElement2("Bottom");
     MethodElement methodBottom =
         ElementFactory.methodElement("call", objectType, <DartType>[intType]);
     classBottom.methods = <MethodElement>[methodBottom];
 
-    DartType top = TypeBuilder.functionType(<DartType>[intType], objectType);
+    DartType top =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
     InterfaceType bottom = classBottom.type;
 
     _checkIsStrictSubtypeOf(bottom, top);
   }
 
-  void test_isSubtypeOf_classes() {
+  void test_classes() {
     ClassElement classTop = ElementFactory.classElement2("A");
     ClassElement classLeft = ElementFactory.classElement("B", classTop.type);
     ClassElement classRight = ElementFactory.classElement("C", classTop.type);
@@ -555,7 +566,7 @@
     _checkLattice(top, left, right, bottom);
   }
 
-  void test_isSubtypeOf_double() {
+  void test_double() {
     List<DartType> equivalents = <DartType>[doubleType];
     List<DartType> supertypes = <DartType>[numType];
     List<DartType> unrelated = <DartType>[intType];
@@ -563,7 +574,7 @@
         equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
   }
 
-  void test_isSubtypeOf_dynamic_isTop() {
+  void test_dynamic_isTop() {
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
     List<DartType> equivalents = <DartType>[dynamicType, objectType];
     List<DartType> subtypes = <DartType>[
@@ -578,20 +589,98 @@
     _checkGroups(dynamicType, equivalents: equivalents, subtypes: subtypes);
   }
 
-  void test_isSubtypeOf_fuzzy_arrows() {
-    FunctionType top =
-        TypeBuilder.functionType(<DartType>[dynamicType], objectType);
-    FunctionType left =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[dynamicType], bottomType);
-    FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], bottomType);
+  void test_fuzzy_arrows() {
+    FunctionType top = TypeBuilder.function(
+        required: <DartType>[dynamicType], result: objectType);
+    FunctionType left = TypeBuilder.function(
+        required: <DartType>[objectType], result: objectType);
+    FunctionType right = TypeBuilder.function(
+        required: <DartType>[dynamicType], result: bottomType);
+    FunctionType bottom = TypeBuilder.function(
+        required: <DartType>[objectType], result: bottomType);
 
     _checkLattice(top, left, right, bottom);
   }
 
-  void test_isSubtypeOf_generics() {
+  void test_genericFunction_generic_monomorphic() {
+    DartType s = TypeBuilder.variable("S");
+    DartType t = TypeBuilder.variable("T", bound: s);
+    DartType u = TypeBuilder.variable("U", bound: intType);
+    DartType v = TypeBuilder.variable("V", bound: u);
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [s, t], required: [s], result: t),
+        TypeBuilder.function(required: [dynamicType], result: dynamicType));
+
+    _checkIsNotSubtypeOf(
+        TypeBuilder.function(types: [u, v], required: [u], result: v),
+        TypeBuilder.function(required: [objectType], result: objectType));
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [u, v], required: [u], result: v),
+        TypeBuilder.function(required: [intType], result: intType));
+  }
+
+  void test_genericFunction_simple() {
+    DartType s = TypeBuilder.variable("S");
+    DartType t = TypeBuilder.variable("T");
+
+    _checkEquivalent(
+        TypeBuilder.function(types: [t]), TypeBuilder.function(types: [s]));
+
+    _checkEquivalent(TypeBuilder.function(types: [t], required: [t], result: t),
+        TypeBuilder.function(types: [s], required: [s], result: s));
+  }
+
+  void test_genericFunction_simple_bounded() {
+    DartType s = TypeBuilder.variable("S");
+    DartType t = TypeBuilder.variable("T", bound: s);
+    DartType u = TypeBuilder.variable("U");
+    DartType v = TypeBuilder.variable("V", bound: u);
+
+    _checkEquivalent(TypeBuilder.function(types: [s, t]),
+        TypeBuilder.function(types: [u, v]));
+
+    _checkEquivalent(
+        TypeBuilder.function(types: [s, t], required: [s], result: t),
+        TypeBuilder.function(types: [u, v], required: [u], result: v));
+
+    {
+      DartType top =
+          TypeBuilder.function(types: [s, t], required: [t], result: s);
+      DartType left =
+          TypeBuilder.function(types: [u, v], required: [u], result: u);
+      DartType right =
+          TypeBuilder.function(types: [u, v], required: [v], result: v);
+      DartType bottom =
+          TypeBuilder.function(types: [s, t], required: [s], result: t);
+      _checkLattice(top, left, right, bottom);
+    }
+  }
+
+  void test_genericFunction_simple_fBounded() {
+    ClassElementImpl AClass = ElementFactory.classElement2('A', ["Q"]);
+    InterfaceType AType = AClass.type;
+    ClassElementImpl BClass = ElementFactory.classElement2('B', ["R"]);
+    BClass.supertype = AType.substitute4([BClass.typeParameters[0].type]);
+    InterfaceType BType = BClass.type;
+
+    DartType s = TypeBuilder.variable("S");
+    (s.element as TypeParameterElementImpl).bound = AType.substitute4([s]);
+    DartType t = TypeBuilder.variable("T", bound: s);
+    DartType u = TypeBuilder.variable("U");
+    (u.element as TypeParameterElementImpl).bound = BType.substitute4([u]);
+    DartType v = TypeBuilder.variable("V", bound: u);
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [s]), TypeBuilder.function(types: [u]));
+
+    _checkIsStrictSubtypeOf(
+        TypeBuilder.function(types: [s, t], required: [s], result: t),
+        TypeBuilder.function(types: [u, v], required: [u], result: v));
+  }
+
+  void test_generics() {
     ClassElementImpl LClass = ElementFactory.classElement2('L', ["T"]);
     InterfaceType LType = LClass.type;
     ClassElementImpl MClass = ElementFactory.classElement2('M', ["T"]);
@@ -608,7 +697,7 @@
     _checkLattice(top, left, right, bottom);
   }
 
-  void test_isSubtypeOf_int() {
+  void test_int() {
     List<DartType> equivalents = <DartType>[intType];
     List<DartType> supertypes = <DartType>[numType];
     List<DartType> unrelated = <DartType>[doubleType];
@@ -616,24 +705,37 @@
         equivalents: equivalents, supertypes: supertypes, unrelated: unrelated);
   }
 
-  void test_isSubtypeOf_named_optional() {
-    DartType r = TypeBuilder.functionType(<DartType>[intType], intType);
-    DartType o = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType]);
-    DartType n = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType});
-    DartType rr =
-        TypeBuilder.functionType(<DartType>[intType, intType], intType);
-    DartType ro = TypeBuilder.functionType(<DartType>[intType], intType,
-        optional: <DartType>[intType]);
-    DartType rn = TypeBuilder.functionType(<DartType>[intType], intType,
-        named: <String, DartType>{'x': intType});
-    DartType oo = TypeBuilder.functionType(<DartType>[], intType,
-        optional: <DartType>[intType, intType]);
-    DartType nn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType});
-    DartType nnn = TypeBuilder.functionType(<DartType>[], intType,
-        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType});
+  void test_named_optional() {
+    DartType r =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    DartType o = TypeBuilder.function(
+        required: <DartType>[], optional: <DartType>[intType], result: intType);
+    DartType n = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType rr = TypeBuilder.function(
+        required: <DartType>[intType, intType], result: intType);
+    DartType ro = TypeBuilder.function(
+        required: <DartType>[intType],
+        optional: <DartType>[intType],
+        result: intType);
+    DartType rn = TypeBuilder.function(
+        required: <DartType>[intType],
+        named: <String, DartType>{'x': intType},
+        result: intType);
+    DartType oo = TypeBuilder.function(
+        required: <DartType>[],
+        optional: <DartType>[intType, intType],
+        result: intType);
+    DartType nn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType},
+        result: intType);
+    DartType nnn = TypeBuilder.function(
+        required: <DartType>[],
+        named: <String, DartType>{'x': intType, 'y': intType, 'z': intType},
+        result: intType);
 
     _checkGroups(r,
         equivalents: [r],
@@ -663,7 +765,7 @@
         equivalents: [nnn], subtypes: [], unrelated: [r, o, rr, ro, rn, oo]);
   }
 
-  void test_isSubtypeOf_num() {
+  void test_num() {
     List<DartType> equivalents = <DartType>[numType];
     List<DartType> supertypes = <DartType>[];
     List<DartType> unrelated = <DartType>[stringType];
@@ -675,29 +777,31 @@
         subtypes: subtypes);
   }
 
-  // Regression test for https://github.com/dart-lang/sdk/issues/25069
-  void test_isSubtypeOf_simple_function_void() {
-    FunctionType functionType =
-        TypeBuilder.functionType(<DartType>[intType], objectType);
-    _checkIsNotSubtypeOf(voidType, functionType);
-  }
-
-  void test_isSubtypeOf_simple_function() {
+  void test_simple_function() {
     FunctionType top =
-        TypeBuilder.functionType(<DartType>[intType], objectType);
-    FunctionType left = TypeBuilder.functionType(<DartType>[intType], intType);
-    FunctionType right =
-        TypeBuilder.functionType(<DartType>[objectType], objectType);
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    FunctionType left =
+        TypeBuilder.function(required: <DartType>[intType], result: intType);
+    FunctionType right = TypeBuilder.function(
+        required: <DartType>[objectType], result: objectType);
     FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
 
     _checkLattice(top, left, right, bottom);
   }
 
-  void test_isSubtypeOf_void_functions() {
-    FunctionType top = TypeBuilder.functionType(<DartType>[intType], voidType);
+  /// Regression test for https://github.com/dart-lang/sdk/issues/25069
+  void test_simple_function_void() {
+    FunctionType functionType =
+        TypeBuilder.function(required: <DartType>[intType], result: objectType);
+    _checkIsNotSubtypeOf(voidType, functionType);
+  }
+
+  void test_void_functions() {
+    FunctionType top =
+        TypeBuilder.function(required: <DartType>[intType], result: voidType);
     FunctionType bottom =
-        TypeBuilder.functionType(<DartType>[objectType], intType);
+        TypeBuilder.function(required: <DartType>[objectType], result: intType);
 
     _checkIsStrictSubtypeOf(bottom, top);
   }
@@ -774,14 +878,25 @@
 }
 
 class TypeBuilder {
-  static FunctionType functionType(
-      List<DartType> parameters, DartType returnType,
-      {List<DartType> optional, Map<String, DartType> named}) {
-    return ElementFactory
-        .functionElement8(parameters, returnType,
-            optional: optional, named: named)
-        .type;
+  static FunctionTypeImpl function(
+      {List<DartType> types,
+      List<DartType> required,
+      List<DartType> optional,
+      Map<String, DartType> named,
+      DartType result}) {
+    result = result ?? VoidTypeImpl.instance;
+    required = required ?? [];
+    FunctionElementImpl f = ElementFactory.functionElement8(required, result,
+        optional: optional, named: named);
+    if (types != null) {
+      f.typeParameters =
+          new List<TypeParameterElement>.from(types.map((t) => t.element));
+    }
+    return f.type = new FunctionTypeImpl(f);
   }
+
+  static TypeParameterType variable(String name, {DartType bound}) =>
+      ElementFactory.typeParameterWithType(name, bound).type;
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index c156aac..bd5876b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library engine.utilities_test;
+library analyzer.test.generated.utilities_test;
 
 import 'dart:collection';
 
@@ -2109,6 +2109,12 @@
   Expression get(AssertStatement node) => node.condition;
 }
 
+class Getter_NodeReplacerTest_test_assertStatement_2
+    implements NodeReplacerTest_Getter {
+  @override
+  Expression get(AssertStatement node) => node.message;
+}
+
 class Getter_NodeReplacerTest_test_assignmentExpression
     implements NodeReplacerTest_Getter {
   @override
@@ -3460,9 +3466,10 @@
   }
 
   void test_assertStatement() {
-    AssertStatement node =
-        AstFactory.assertStatement(AstFactory.booleanLiteral(true));
+    AssertStatement node = AstFactory.assertStatement(
+        AstFactory.booleanLiteral(true), AstFactory.string2('foo'));
     _assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement());
+    _assertReplace(node, new Getter_NodeReplacerTest_test_assertStatement_2());
   }
 
   void test_assignmentExpression() {
diff --git a/pkg/analyzer/test/instrumentation/instrumentation_test.dart b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
index ac8755e..a938d4d 100644
--- a/pkg/analyzer/test/instrumentation/instrumentation_test.dart
+++ b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
@@ -2,7 +2,7 @@
 // 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 test.instrumentation;
+library analyzer.test.instrumentation.instrumentation_test;
 
 import 'dart:async';
 
diff --git a/pkg/analyzer/test/instrumentation/test_all.dart b/pkg/analyzer/test/instrumentation/test_all.dart
index f9bfc2d..46bb206 100644
--- a/pkg/analyzer/test/instrumentation/test_all.dart
+++ b/pkg/analyzer/test/instrumentation/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.instrumentation.test_all;
+library analyzer.test.instrumentation.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index 71e4838..c5313da 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -2,7 +2,7 @@
 // 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 test.parse.compilation.unit;
+library analyzer.test.parse_compilation_unit_test;
 
 import 'package:analyzer/analyzer.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/reflective_tests.dart b/pkg/analyzer/test/reflective_tests.dart
index 8180cf7..24c36cb 100644
--- a/pkg/analyzer/test/reflective_tests.dart
+++ b/pkg/analyzer/test/reflective_tests.dart
@@ -2,7 +2,7 @@
 // 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 reflective_tests;
+library analyzer.test.reflective_tests;
 
 @MirrorsUsed(metaTargets: 'ReflectiveTest')
 import 'dart:mirrors';
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index 92b8cfc..d71304b 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -2,7 +2,7 @@
 // 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 test.source.analysis_options_provider;
+library analyzer.test.source.analysis_options_provider_test;
 
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index ee50643..c152773 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -2,7 +2,7 @@
 // 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 test.source.embedder;
+library analyzer.test.source.embedder_test;
 
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/embedder.dart';
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
new file mode 100644
index 0000000..3c3facb
--- /dev/null
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.source.error_processor;
+
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
+import 'package:unittest/unittest.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+import '../generated/test_support.dart';
+import '../utils.dart';
+
+main() {
+  AnalysisError invalid_assignment =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
+    ['x'],
+    ['y']
+  ]);
+
+  AnalysisError missing_return =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.MISSING_RETURN, [
+    ['x']
+  ]);
+
+  AnalysisError unused_local_variable = new AnalysisError(
+      new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
+    ['x']
+  ]);
+
+  AnalysisError use_of_void_result =
+      new AnalysisError(new TestSource(), 0, 1, HintCode.USE_OF_VOID_RESULT, [
+    ['x']
+  ]);
+
+  initializeTestEnvironment();
+  oneTimeSetup();
+
+  setUp(() {
+    context = new TestContext();
+  });
+
+  group('ErrorProcessorTest', () {
+    test('configureOptions', () {
+      configureOptions('''
+analyzer:
+  errors:
+    invalid_assignment: error # severity ERROR
+    missing_return: false # ignore
+    unused_local_variable: true # skipped
+    use_of_void_result: unsupported_action # skipped
+''');
+      expect(getProcessor(invalid_assignment).severity, ErrorSeverity.ERROR);
+      expect(getProcessor(missing_return).severity, isNull);
+      expect(getProcessor(unused_local_variable), isNull);
+      expect(getProcessor(use_of_void_result), isNull);
+    });
+  });
+
+  group('ErrorConfigTest', () {
+    var config = '''
+analyzer:
+  errors:
+    invalid_assignment: unsupported_action # should be skipped
+    missing_return: false
+    unused_local_variable: error
+''';
+
+    group('processing', () {
+      test('yaml map', () {
+        var options = optionsProvider.getOptionsFromString(config);
+        var errorConfig = new ErrorConfig(options['analyzer']['errors']);
+        expect(errorConfig.processors, hasLength(2));
+
+        // ignore
+        var missingReturnProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(missing_return));
+        expect(missingReturnProcessor.severity, isNull);
+
+        // error
+        var unusedLocalProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(unused_local_variable));
+        expect(unusedLocalProcessor.severity, ErrorSeverity.ERROR);
+
+        // skip
+        var invalidAssignmentProcessor = errorConfig.processors.firstWhere(
+            (p) => p.appliesTo(invalid_assignment),
+            orElse: () => null);
+        expect(invalidAssignmentProcessor, isNull);
+      });
+      test('string map', () {
+        var options = {
+          'invalid_assignment': 'unsupported_action', // should be skipped
+          'missing_return': 'false',
+          'unused_local_variable': 'error'
+        };
+        var errorConfig = new ErrorConfig(options);
+        expect(errorConfig.processors, hasLength(2));
+
+        // ignore
+        var missingReturnProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(missing_return));
+        expect(missingReturnProcessor.severity, isNull);
+
+        // error
+        var unusedLocalProcessor = errorConfig.processors
+            .firstWhere((p) => p.appliesTo(unused_local_variable));
+        expect(unusedLocalProcessor.severity, ErrorSeverity.ERROR);
+
+        // skip
+        var invalidAssignmentProcessor = errorConfig.processors.firstWhere(
+            (p) => p.appliesTo(invalid_assignment),
+            orElse: () => null);
+        expect(invalidAssignmentProcessor, isNull);
+      });
+    });
+  });
+}
+
+TestContext context;
+
+AnalysisOptionsProvider optionsProvider = new AnalysisOptionsProvider();
+ErrorProcessor processor;
+
+void configureOptions(String options) {
+  Map<String, YamlNode> optionMap =
+      optionsProvider.getOptionsFromString(options);
+  configureContextOptions(context, optionMap);
+}
+
+ErrorProcessor getProcessor(AnalysisError error) =>
+    ErrorProcessor.getProcessor(context, error);
+
+void oneTimeSetup() {
+  List<Plugin> plugins = <Plugin>[];
+  plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+  plugins.add(AnalysisEngine.instance.commandLinePlugin);
+  plugins.add(AnalysisEngine.instance.optionsPlugin);
+  ExtensionManager manager = new ExtensionManager();
+  manager.processPlugins(plugins);
+}
+
+class TestContext extends AnalysisContextImpl {}
diff --git a/pkg/analyzer/test/source/package_map_provider_test.dart b/pkg/analyzer/test/source/package_map_provider_test.dart
index 3701630..f02b60a 100644
--- a/pkg/analyzer/test/source/package_map_provider_test.dart
+++ b/pkg/analyzer/test/source/package_map_provider_test.dart
@@ -2,7 +2,7 @@
 // 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 test.package.map.provider;
+library analyzer.test.source.package_map_provider_test;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index caf88da..0017961 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -2,7 +2,7 @@
 // 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 test.source.package_map_resolver;
+library analyzer.test.source.package_map_resolver_test;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
diff --git a/pkg/analyzer/test/source/path_filter_test.dart b/pkg/analyzer/test/source/path_filter_test.dart
index a7e58fb..1cada77 100644
--- a/pkg/analyzer/test/source/path_filter_test.dart
+++ b/pkg/analyzer/test/source/path_filter_test.dart
@@ -2,7 +2,7 @@
 // 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 test.source.path_filter;
+library analyzer.test.source.path_filter_test;
 
 import 'package:analyzer/source/path_filter.dart';
 import 'package:path/path.dart';
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index 01416af..dbb7425 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -2,7 +2,7 @@
 // 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 test.source.sdk_ext;
+library analyzer.test.source.sdk_ext_test;
 
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/sdk_ext.dart';
diff --git a/pkg/analyzer/test/source/test_all.dart b/pkg/analyzer/test/source/test_all.dart
index c47b329..725d23e 100644
--- a/pkg/analyzer/test/source/test_all.dart
+++ b/pkg/analyzer/test/source/test_all.dart
@@ -2,13 +2,14 @@
 // 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 test.source;
+library analyzer.test.source.test_all;
 
 import 'package:unittest/unittest.dart';
 
 import '../utils.dart';
 import 'analysis_options_provider_test.dart' as analysis_options_provider_test;
 import 'embedder_test.dart' as embedder_test;
+import 'error_processor_test.dart' as error_processor_test;
 import 'package_map_provider_test.dart' as package_map_provider_test;
 import 'package_map_resolver_test.dart' as package_map_resolver_test;
 import 'path_filter_test.dart' as path_filter_test;
@@ -20,6 +21,7 @@
   group('source', () {
     analysis_options_provider_test.main();
     embedder_test.main();
+    error_processor_test.main();
     package_map_provider_test.main();
     package_map_resolver_test.main();
     path_filter_test.main();
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index 135fd42..33f782b 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -2,19 +2,20 @@
 // 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 test.src.task.abstract_context_test;
+library analyzer.test.src.context.abstract_context;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisCache, AnalysisContextImpl, AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/task/model.dart';
+import 'package:plugin/manager.dart';
+import 'package:plugin/plugin.dart';
 import 'package:unittest/unittest.dart';
 
 import 'mock_sdk.dart';
@@ -124,6 +125,14 @@
   }
 
   void setUp() {
+    List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
+
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
+
     prepareAnalysisContext();
   }
 
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 0962474..37bd49c 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -2,15 +2,10 @@
 // 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 test.src.task.driver_test;
+library analyzer.test.src.context.cache_test;
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show
-        AnalysisContext,
-        CacheState,
-        InternalAnalysisContext,
-        RetentionPriority;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -34,9 +29,7 @@
   runReflectiveTests(ResultDataTest);
 }
 
-AnalysisCache createCache(
-    {AnalysisContext context,
-    RetentionPriority policy: RetentionPriority.LOW}) {
+AnalysisCache createCache({AnalysisContext context}) {
   CachePartition partition = new UniversalCachePartition(context);
   return new AnalysisCache(<CachePartition>[partition]);
 }
@@ -1121,9 +1114,7 @@
 }
 
 class _InternalAnalysisContextMock extends TypedMock
-    implements InternalAnalysisContext {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+    implements InternalAnalysisContext {}
 
 /**
  * Keep the given [keepDescriptor], invalidate all the other results.
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 5fd7926..ca87671 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.context.context_test;
+library analyzer.test.src.context.context_test;
 
 import 'dart:async';
 
@@ -13,24 +13,7 @@
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    show
-        AnalysisContext,
-        AnalysisContextStatistics,
-        AnalysisDelta,
-        AnalysisEngine,
-        AnalysisErrorInfo,
-        AnalysisLevel,
-        AnalysisNotScheduledError,
-        AnalysisOptions,
-        AnalysisOptionsImpl,
-        AnalysisResult,
-        ApplyChangesStatus,
-        CacheState,
-        ChangeNotice,
-        ChangeSet,
-        IncrementalAnalysisCache,
-        TimestampedData;
+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';
@@ -854,7 +837,7 @@
   }
 
   void test_exists_true() {
-    expect(context.exists(new AnalysisContextImplTest_Source_exists_true()),
+    expect(context.exists(new _AnalysisContextImplTest_Source_exists_true()),
         isTrue);
   }
 
@@ -1314,7 +1297,7 @@
     int stamp = 42;
     expect(
         context.getModificationStamp(
-            new AnalysisContextImplTest_Source_getModificationStamp_fromSource(
+            new _AnalysisContextImplTest_Source_getModificationStamp_fromSource(
                 stamp)),
         stamp);
   }
@@ -1322,7 +1305,7 @@
   void test_getModificationStamp_overridden() {
     int stamp = 42;
     Source source =
-        new AnalysisContextImplTest_Source_getModificationStamp_overridden(
+        new _AnalysisContextImplTest_Source_getModificationStamp_overridden(
             stamp);
     context.setContents(source, "");
     expect(stamp != context.getModificationStamp(source), isTrue);
@@ -1382,16 +1365,6 @@
     expect(context.getSourcesWithFullName(filePath), unorderedEquals(expected));
   }
 
-  void test_getStatistics() {
-    AnalysisContextStatistics statistics = context.statistics;
-    expect(statistics, isNotNull);
-    // The following lines are fragile.
-    // The values depend on the number of libraries in the SDK.
-//    assertLength(0, statistics.getCacheRows());
-//    assertLength(0, statistics.getExceptions());
-//    assertLength(0, statistics.getSources());
-  }
-
   void test_handleContentsChanged() {
     ContentCache contentCache = new ContentCache();
     context.contentCache = contentCache;
@@ -2727,6 +2700,27 @@
   }
 }
 
+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;
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index ad1c2f6..f9ce626 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -2,7 +2,7 @@
 // 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 test.src.mock_sdk;
+library analyzer.test.src.context.mock_sdk;
 
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
@@ -321,6 +321,13 @@
   }
 }
 
+class _MockSdkFile {
+  final String path;
+  final String content;
+
+  const _MockSdkFile(this.path, this.content);
+}
+
 class _MockSdkLibrary implements SdkLibrary {
   final String shortName;
   final String path;
@@ -354,13 +361,6 @@
   UnimplementedError get unimplemented => new UnimplementedError();
 }
 
-class _MockSdkFile {
-  final String path;
-  final String content;
-
-  const _MockSdkFile(this.path, this.content);
-}
-
 /**
  * An [AnalysisContextImpl] that only contains sources for a Dart SDK.
  */
@@ -374,8 +374,7 @@
     if (factory == null) {
       return super.createCacheFromSourceFactory(factory);
     }
-    return new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager_new.forSdk(sdk)
-    ]);
+    return new AnalysisCache(
+        <CachePartition>[AnalysisEngine.instance.partitionManager.forSdk(sdk)]);
   }
 }
diff --git a/pkg/analyzer/test/src/context/test_all.dart b/pkg/analyzer/test/src/context/test_all.dart
index bbd021d..301b13c 100644
--- a/pkg/analyzer/test/src/context/test_all.dart
+++ b/pkg/analyzer/test/src/context/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.src.context.test_all;
+library analyzer.test.src.context.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/mock_sdk.dart b/pkg/analyzer/test/src/mock_sdk.dart
index d4f6ac1..4641b07 100644
--- a/pkg/analyzer/test/src/mock_sdk.dart
+++ b/pkg/analyzer/test/src/mock_sdk.dart
@@ -2,11 +2,11 @@
 // 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 test.src.mock_sdk;
+library analyzer.test.src.mock_sdk;
 
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
-import 'package:analyzer/src/context/context.dart' as newContext;
+import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -201,11 +201,7 @@
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      if (AnalysisEngine.instance.useTaskModel) {
-        _analysisContext = new newContext.SdkAnalysisContext();
-      } else {
-        _analysisContext = new SdkAnalysisContext();
-      }
+      _analysisContext = new SdkAnalysisContext();
       SourceFactory factory = new SourceFactory([new DartUriResolver(this)]);
       _analysisContext.sourceFactory = factory;
       ChangeSet changeSet = new ChangeSet();
diff --git a/pkg/analyzer/test/src/plugin/plugin_config_test.dart b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
index cc06b96..2c9fa04 100644
--- a/pkg/analyzer/test/src/plugin/plugin_config_test.dart
+++ b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.plugin.plugin_config_test;
+library analyzer.test.src.plugin.plugin_config_test;
 
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/src/plugin/plugin_configuration.dart';
diff --git a/pkg/analyzer/test/src/summary/summary_test.dart b/pkg/analyzer/test/src/summary/summary_test.dart
index be2844e..e6107e4 100644
--- a/pkg/analyzer/test/src/summary/summary_test.dart
+++ b/pkg/analyzer/test/src/summary/summary_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.serialization.elements_test;
+library analyzer.test.src.summary.summary_test;
 
 import 'dart:typed_data';
 
@@ -67,6 +67,7 @@
 
   @override
   void setUp() {
+    super.setUp();
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.enableGenericMethods = true;
     resetWithOptions(options);
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index dcb6980..09d71ad 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.dart_test;
+library analyzer.test.src.task.dart_test;
 
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
@@ -47,7 +47,6 @@
   runReflectiveTests(ComputePropagableVariableDependenciesTaskTest);
   runReflectiveTests(ContainingLibrariesTaskTest);
   runReflectiveTests(DartErrorsTaskTest);
-  runReflectiveTests(ErrorFilterTest);
   runReflectiveTests(EvaluateUnitConstantsTaskTest);
   runReflectiveTests(GatherUsedImportedElementsTaskTest);
   runReflectiveTests(GatherUsedLocalElementsTaskTest);
@@ -1116,8 +1115,9 @@
         computeResult(target, CONSTANT_VALUE,
             matcher: isComputeConstantValueTask);
         expect(outputs[CONSTANT_VALUE], same(target));
-        EvaluationResultImpl evaluationResult = (annotation.elementAnnotation
-            as ElementAnnotationImpl).evaluationResult;
+        EvaluationResultImpl evaluationResult =
+            (annotation.elementAnnotation as ElementAnnotationImpl)
+                .evaluationResult;
         return evaluationResult;
       }
     }
@@ -1285,8 +1285,9 @@
     for (String otherVariableName in otherVariables) {
       PropertyInducingElement otherVariableElement =
           AstFinder.getTopLevelVariableElement(unit, otherVariableName);
-      _expectCircularityError((otherVariableElement
-          as TopLevelVariableElementImpl).evaluationResult);
+      _expectCircularityError(
+          (otherVariableElement as TopLevelVariableElementImpl)
+              .evaluationResult);
     }
   }
 
@@ -1426,6 +1427,62 @@
     expect(outputs[LIBRARY_CYCLE], hasLength(1));
   }
 
+  void test_library_cycle_override_inference_incremental() {
+    enableStrongMode();
+    Source lib1Source = newSource(
+        '/my_lib1.dart',
+        '''
+library my_lib1;
+import 'my_lib3.dart';
+''');
+    Source lib2Source = newSource(
+        '/my_lib2.dart',
+        '''
+library my_lib2;
+import 'my_lib1.dart';
+''');
+    Source lib3Source = newSource(
+        '/my_lib3.dart',
+        '''
+library my_lib3;
+import 'my_lib2.dart';
+
+class A {
+  int foo(int x) => null;
+}
+class B extends A {
+  foo(x) => null;
+}
+''');
+    AnalysisTarget lib1Target = new LibrarySpecificUnit(lib1Source, lib1Source);
+    AnalysisTarget lib2Target = new LibrarySpecificUnit(lib2Source, lib2Source);
+    AnalysisTarget lib3Target = new LibrarySpecificUnit(lib3Source, lib3Source);
+
+    computeResult(lib1Target, RESOLVED_UNIT);
+    computeResult(lib2Target, RESOLVED_UNIT);
+    computeResult(lib3Target, RESOLVED_UNIT);
+    CompilationUnit unit = outputs[RESOLVED_UNIT];
+    ClassElement b = unit.declarations[1].element;
+    expect(b.getMethod('foo').returnType.toString(), 'int');
+
+    // add a dummy edit.
+    context.setContents(
+        lib1Source,
+        '''
+library my_lib1;
+import 'my_lib3.dart';
+var foo = 123;
+''');
+
+    computeResult(lib1Target, RESOLVED_UNIT);
+    computeResult(lib2Target, RESOLVED_UNIT);
+    computeResult(lib3Target, RESOLVED_UNIT);
+    unit = outputs[RESOLVED_UNIT];
+    b = unit.declarations[1].element;
+    expect(b.getMethod('foo').returnType.toString(), 'int',
+        reason: 'edit should not affect member inference');
+  }
+
   void test_library_cycle_incremental_partial() {
     enableStrongMode();
     Source lib1Source = newSource(
@@ -1962,32 +2019,6 @@
 }
 
 @reflectiveTest
-class ErrorFilterTest extends _AbstractDartTaskTest {
-  @override
-  setUp() {
-    super.setUp();
-    context.setConfigurationData(CONFIGURED_ERROR_FILTERS, [
-      (AnalysisError error) => error.errorCode.name == 'INVALID_ASSIGNMENT'
-    ]);
-  }
-
-  test_error_filters() {
-    AnalysisTarget library = newSource(
-        '/test.dart',
-        '''
-main() {
-  int x = ""; // INVALID_ASSIGNMENT (suppressed)
-  // UNUSED_LOCAL_VARIABLE
-}''');
-    computeResult(library, DART_ERRORS, matcher: isDartErrorsTask);
-    expect(outputs, hasLength(1));
-    List<AnalysisError> errors = outputs[DART_ERRORS];
-    expect(errors, hasLength(1));
-    expect(errors.first.errorCode, HintCode.UNUSED_LOCAL_VARIABLE);
-  }
-}
-
-@reflectiveTest
 class EvaluateUnitConstantsTaskTest extends _AbstractDartTaskTest {
   test_perform() {
     Source source = newSource(
@@ -3879,8 +3910,9 @@
     VariableElement tau =
         AstFinder.getTopLevelVariable(unit, 'tau').name.staticElement;
     Expression piFirstUse = (AstFinder
-        .getTopLevelVariable(unit, 'tau')
-        .initializer as ConditionalExpression).condition;
+            .getTopLevelVariable(unit, 'tau')
+            .initializer as ConditionalExpression)
+        .condition;
 
     expect(piFirstUse.staticType, context.typeProvider.boolType);
     expect(piFirst.type, context.typeProvider.boolType);
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index a10cfef..7938cc9 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.dart_work_manager_test;
+library analyzer.test.src.task.dart_work_manager_test;
 
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/ast.dart';
@@ -210,8 +210,8 @@
   }
 
   void test_applyPriorityTargets_isLibrary_computeErrors() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
     entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
@@ -234,8 +234,8 @@
   }
 
   void test_applyPriorityTargets_isLibrary_computeUnit() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(false);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(false);
     entry1.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry2.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
     entry3.setValue(SOURCE_KIND, SourceKind.LIBRARY, []);
@@ -593,8 +593,8 @@
     entry1.setValue(SCAN_ERRORS, <AnalysisError>[error1], []);
     entry1.setValue(PARSE_ERRORS, <AnalysisError>[error2], []);
     // PARSED_UNIT is ready, set errors
-    manager.resultsComputed(
-        source1, {PARSED_UNIT: AstFactory.compilationUnit()});
+    manager
+        .resultsComputed(source1, {PARSED_UNIT: AstFactory.compilationUnit()});
     // all of the errors are included
     ChangeNoticeImpl notice = context.getNotice(source1);
     expect(notice.errors, unorderedEquals([error1, error2]));
@@ -611,8 +611,7 @@
     expect(cache.getState(part1, CONTAINING_LIBRARIES), CacheState.VALID);
     // configure AnalysisContext mock
     when(context.prioritySources).thenReturn(<Source>[]);
-    when(context.shouldErrorsBeAnalyzed(anyObject, anyObject))
-        .thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(anyObject)).thenReturn(false);
     // library1 parts
     manager.resultsComputed(library1, {
       INCLUDED_PARTS: [part1, part2],
@@ -705,7 +704,7 @@
   void test_resultsComputed_sourceKind_isLibrary() {
     manager.unknownSourceQueue.addAll([source1, source2, source3]);
     when(context.prioritySources).thenReturn(<Source>[]);
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
     manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
     expect_librarySourceQueue([source2]);
     expect_unknownSourceQueue([source1, source3]);
@@ -714,7 +713,7 @@
   void test_resultsComputed_sourceKind_isLibrary_isPriority_computeErrors() {
     manager.unknownSourceQueue.addAll([source1, source2, source3]);
     when(context.prioritySources).thenReturn(<Source>[source2]);
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
     manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
     expect_unknownSourceQueue([source1, source3]);
     expect(manager.priorityResultQueue,
@@ -724,7 +723,7 @@
   void test_resultsComputed_sourceKind_isLibrary_isPriority_computeUnit() {
     manager.unknownSourceQueue.addAll([source1, source2, source3]);
     when(context.prioritySources).thenReturn(<Source>[source2]);
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(false);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(false);
     manager.resultsComputed(source2, {SOURCE_KIND: SourceKind.LIBRARY});
     expect_unknownSourceQueue([source1, source3]);
     expect(
@@ -762,13 +761,9 @@
   }
 }
 
-class _DartSdkMock extends TypedMock implements DartSdk {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _DartSdkMock extends TypedMock implements DartSdk {}
 
-class _DartWorkManagerMock extends TypedMock implements DartWorkManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _DartWorkManagerMock extends TypedMock implements DartWorkManager {}
 
 class _InternalAnalysisContextMock extends TypedMock
     implements InternalAnalysisContext {
@@ -800,20 +795,15 @@
     return _pendingNotices.putIfAbsent(
         source, () => new ChangeNoticeImpl(source));
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class _SourceFactoryMock extends TypedMock implements SourceFactory {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _SourceFactoryMock extends TypedMock implements SourceFactory {}
 
 class _SourceMock extends TypedMock implements Source {
   final String shortName;
   _SourceMock(this.shortName);
   @override
   String get fullName => '/' + shortName;
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
   @override
   String toString() => fullName;
 }
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 9560dc8..e135d99 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -2,16 +2,10 @@
 // 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 test.src.task.driver_test;
+library analyzer.test.src.task.driver_test;
 
 import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/generated/engine.dart'
-    hide
-        AnalysisCache,
-        AnalysisContextImpl,
-        AnalysisTask,
-        UniversalCachePartition,
-        WorkManager;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/task/driver.dart';
 import 'package:analyzer/src/task/inputs.dart';
@@ -761,8 +755,6 @@
     }
     return entry;
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -788,6 +780,4 @@
   }
 }
 
-class _WorkManagerMock extends TypedMock implements WorkManager {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _WorkManagerMock extends TypedMock implements WorkManager {}
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
index b335664..da4c462 100644
--- a/pkg/analyzer/test/src/task/general_test.dart
+++ b/pkg/analyzer/test/src/task/general_test.dart
@@ -2,10 +2,9 @@
 // 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 test.src.task.general_test;
+library analyzer.test.src.task.general_test;
 
-import 'package:analyzer/src/generated/engine.dart'
-    hide AnalysisTask, GetContentTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/general.dart';
 import 'package:analyzer/task/general.dart';
@@ -81,6 +80,4 @@
   }
 }
 
-class _MockContext extends TypedMock implements AnalysisContext {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class _MockContext extends TypedMock implements AnalysisContext {}
diff --git a/pkg/analyzer/test/src/task/html_test.dart b/pkg/analyzer/test/src/task/html_test.dart
index 0806e90..c8f1f97 100644
--- a/pkg/analyzer/test/src/task/html_test.dart
+++ b/pkg/analyzer/test/src/task/html_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.html_test;
+library analyzer.test.src.task.html_test;
 
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/html.dart';
@@ -303,15 +303,22 @@
     <title>test page</title>
   </head>
   <body>
-    <h1>Test</h1>
+    <h1 myAttr='my value'>Test</h1>
   </body>
 </html>
 ''';
     AnalysisTarget target = newSource('/test.html', code);
     computeResult(target, HTML_DOCUMENT);
     expect(task, isParseHtmlTask);
-    expect(outputs[HTML_DOCUMENT], isNotNull);
     expect(outputs[HTML_DOCUMENT_ERRORS], isEmpty);
+    // HTML_DOCUMENT
+    {
+      Document document = outputs[HTML_DOCUMENT];
+      expect(document, isNotNull);
+      // verify that attributes are not lower-cased
+      Element element = document.body.getElementsByTagName('h1').single;
+      expect(element.attributes['myAttr'], 'my value');
+    }
     // LINE_INFO
     {
       LineInfo lineInfo = outputs[LINE_INFO];
diff --git a/pkg/analyzer/test/src/task/html_work_manager_test.dart b/pkg/analyzer/test/src/task/html_work_manager_test.dart
index 0785f97..8d1d168 100644
--- a/pkg/analyzer/test/src/task/html_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/html_work_manager_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.html_work_manager_test;
+library analyzer.test.src.task.html_work_manager_test;
 
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/engine.dart'
@@ -110,8 +110,8 @@
   }
 
   void test_applyPriorityTargets() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
     manager.priorityResultQueue.add(new TargetedResult(source1, HTML_ERRORS));
     manager.priorityResultQueue.add(new TargetedResult(source2, HTML_ERRORS));
     // -source1 +source3
@@ -346,6 +346,4 @@
     return _pendingNotices.putIfAbsent(
         source, () => new ChangeNoticeImpl(source));
   }
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index b495be7..a331255 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.incremental_element_builder_test;
+library analyzer.test.src.task.incremental_element_builder_test;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index 3943a99..be97598 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.inputs_test;
+library analyzer.test.src.task.inputs_test;
 
 import 'package:analyzer/src/task/inputs.dart';
 import 'package:analyzer/src/task/model.dart';
@@ -37,6 +37,7 @@
   ConstantTaskInputBuilder builder;
 
   void setUp() {
+    super.setUp();
     builder = new ConstantTaskInputBuilder(input);
   }
 
@@ -555,7 +556,7 @@
 }
 
 @reflectiveTest
-class ObjectToListTaskInputBuilderTest extends EngineTestCase {
+class ObjectToListTaskInputBuilderTest {
   static final AnalysisTarget target = new TestSource();
   static final ResultDescriptorImpl result =
       new ResultDescriptorImpl('result', null);
@@ -705,7 +706,7 @@
 }
 
 @reflectiveTest
-class SimpleTaskInputBuilderTest extends EngineTestCase {
+class SimpleTaskInputBuilderTest {
   static final AnalysisTarget target = new TestSource();
   static final ResultDescriptorImpl result =
       new ResultDescriptorImpl('result', null);
diff --git a/pkg/analyzer/test/src/task/manager_test.dart b/pkg/analyzer/test/src/task/manager_test.dart
index 783c015..e78cba4 100644
--- a/pkg/analyzer/test/src/task/manager_test.dart
+++ b/pkg/analyzer/test/src/task/manager_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.manager_test;
+library analyzer.test.src.task.manager_test;
 
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/task/manager.dart';
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index 00cdcfa..4db1ee2 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -2,9 +2,9 @@
 // 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 test.src.task.model_test;
+library analyzer.test.src.task.model_test;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/task/model.dart';
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index eacff89..6d35a3e 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -2,11 +2,12 @@
 // 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 test.src.task.options_test;
+library analyzer.test.src.task.options_test;
 
 import 'package:analyzer/analyzer.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisContextImpl;
+import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/task/general.dart';
@@ -68,30 +69,36 @@
     expect(analysisOptions.enableSuperMixins, true);
   }
 
-  test_configure_error_filters() {
+  test_configure_error_processors() {
     configureContext('''
 analyzer:
   errors:
     invalid_assignment: ignore
-    unused_local_variable: ignore
+    unused_local_variable: error
 ''');
 
-    List<ErrorFilter> filters =
-        context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-    expect(filters, hasLength(2));
+    List<ErrorProcessor> processors =
+        context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+    expect(processors, hasLength(2));
 
-    var unused_error = new AnalysisError(
+    var unused_local = new AnalysisError(
         new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
       ['x']
     ]);
-    var invalid_assignment_error =
+    var invalid_assignment =
         new AnalysisError(new TestSource(), 0, 1, HintCode.INVALID_ASSIGNMENT, [
       ['x'],
       ['y']
     ]);
 
-    expect(filters.any((filter) => filter(unused_error)), isTrue);
-    expect(filters.any((filter) => filter(invalid_assignment_error)), isTrue);
+    // ignore
+    var invalidAssignment =
+        processors.firstWhere((p) => p.appliesTo(invalid_assignment));
+    expect(invalidAssignment.severity, isNull);
+
+    // error
+    var unusedLocal = processors.firstWhere((p) => p.appliesTo(unused_local));
+    expect(unusedLocal.severity, ErrorSeverity.ERROR);
   }
 
   test_configure_strong_mode() {
diff --git a/pkg/analyzer/test/src/task/options_work_manager_test.dart b/pkg/analyzer/test/src/task/options_work_manager_test.dart
index 424a729..cf6cac0 100644
--- a/pkg/analyzer/test/src/task/options_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/options_work_manager_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.options_work_manager_test;
+library analyzer.test.src.task.options_work_manager_test;
 
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/generated/engine.dart'
@@ -111,8 +111,8 @@
   }
 
   void test_applyPriorityTargets() {
-    when(context.shouldErrorsBeAnalyzed(source2, null)).thenReturn(true);
-    when(context.shouldErrorsBeAnalyzed(source3, null)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source2)).thenReturn(true);
+    when(context.shouldErrorsBeAnalyzed(source3)).thenReturn(true);
     manager.priorityResultQueue
         .add(new TargetedResult(source1, ANALYSIS_OPTIONS_ERRORS));
     manager.priorityResultQueue
@@ -136,8 +136,8 @@
         source1, 1, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
     AnalysisError error2 = new AnalysisError(
         source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
-    entry1.setValue(
-        ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
+    entry1
+        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
 
     List<AnalysisError> errors = manager.getErrors(source1);
     expect(errors, unorderedEquals([error1, error2]));
@@ -233,8 +233,8 @@
         source1, 2, 0, AnalysisOptionsErrorCode.PARSE_ERROR, ['']);
     LineInfo lineInfo = new LineInfo([0]);
     entry1.setValue(LINE_INFO, lineInfo, []);
-    entry1.setValue(
-        ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
+    entry1
+        .setValue(ANALYSIS_OPTIONS_ERRORS, <AnalysisError>[error1, error2], []);
     // RESOLVED_UNIT is ready, set errors
     manager.resultsComputed(source1, {ANALYSIS_OPTIONS_ERRORS: null});
     // all of the errors are included
@@ -282,6 +282,4 @@
   @override
   ChangeNoticeImpl getNotice(Source source) =>
       _pendingNotices.putIfAbsent(source, () => new ChangeNoticeImpl(source));
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index a1170ef..b896776 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -5,7 +5,7 @@
 // TODO(jmesserly): this file needs to be refactored, it's a port from
 // package:dev_compiler's tests
 /// General type checking tests
-library test.src.task.strong.checker_test;
+library analyzer.test.src.task.strong.checker_test;
 
 import 'package:unittest/unittest.dart';
 
@@ -247,7 +247,7 @@
       class B extends A {
         B() : super(/*severe:STATIC_TYPE_ERROR*/"hello");
 
-        B.c2(int x, String y) : super.c2(/*severe:STATIC_TYPE_ERROR*/y, 
+        B.c2(int x, String y) : super.c2(/*severe:STATIC_TYPE_ERROR*/y,
                                          /*severe:STATIC_TYPE_ERROR*/x);
 
         B.c3(num x, Object y) : super.c3(x, /*info:DOWN_CAST_IMPLICIT*/y);
@@ -1351,6 +1351,49 @@
        '''
   });
 
+  testChecker('generic class method override', {
+    '/main.dart': '''
+          class A {}
+          class B extends A {}
+
+          class Base<T extends B> {
+            T foo() => null;
+          }
+
+          class Derived<S extends A> extends Base<B> {
+            /*severe:INVALID_METHOD_OVERRIDE*/S foo() => null;
+          }
+
+          class Derived2<S extends B> extends Base<B> {
+            S foo() => null;
+          }
+       '''
+  });
+
+  testChecker('generic method override', {
+    '/main.dart': '''
+          class Future<T> {
+            /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+          }
+
+          class DerivedFuture<T> extends Future<T> {
+            /*=S*/ then/*<S>*/(/*=S*/ onValue(T t)) => null;
+          }
+
+          class DerivedFuture2<A> extends Future<A> {
+            /*=B*/ then/*<B>*/(/*=B*/ onValue(A a)) => null;
+          }
+
+          class DerivedFuture3<T> extends Future<T> {
+            /*=S*/ then/*<S>*/(Object onValue(T t)) => null;
+          }
+
+          class DerivedFuture4<A> extends Future<A> {
+            /*=B*/ then/*<B>*/(Object onValue(A a)) => null;
+          }
+       '''
+  });
+
   testChecker('unary operators', {
     '/main.dart': '''
       class A {
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 8fe4b37..a643e3b 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -5,7 +5,7 @@
 // TODO(jmesserly): this file needs to be refactored, it's a port from
 // package:dev_compiler's tests
 /// Tests for type inference.
-library test.src.task.strong.inferred_type_test;
+library analyzer.test.src.task.strong.inferred_type_test;
 
 import 'package:unittest/unittest.dart';
 
@@ -349,6 +349,36 @@
     '''
   });
 
+  testChecker('infer list literal nested in map literal', {
+    '/main.dart': r'''
+class Resource {}
+class Folder extends Resource {}
+
+Resource getResource(String str) => null;
+
+class Foo<T> {
+  Foo(T t);
+}
+
+main() {
+  // List inside map
+  var map = <String, List<Folder>>{
+    'pkgA': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')],
+    'pkgB': /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/')]
+  };
+  // Also try map inside list
+  var list = <Map<String, Folder>>[
+    /*info:INFERRED_TYPE_LITERAL*/{ 'pkgA': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/') },
+    /*info:INFERRED_TYPE_LITERAL*/{ 'pkgB': /*info:DOWN_CAST_IMPLICIT*/getResource('/pkgB/lib/') },
+  ];
+  // Instance creation too
+  var foo = new Foo<List<Folder>>(
+    /*info:INFERRED_TYPE_LITERAL*/[/*info:DOWN_CAST_IMPLICIT*/getResource('/pkgA/lib/')]
+  );
+}
+    '''
+  });
+
   // but flags can enable this behavior.
   testChecker('infer if complex expressions read possibly inferred field', {
     '/a.dart': '''
@@ -1120,6 +1150,63 @@
       }
       ''';
     testChecker('infer downwards', {'/main.dart': code});
+
+    testChecker('infer if value types match context', {'/main.dart': r'''
+class DartType {}
+typedef void Asserter<T>(T type);
+typedef Asserter<T> AsserterBuilder<S, T>(S arg);
+
+Asserter<DartType> _isInt;
+Asserter<DartType> _isString;
+
+abstract class C {
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
+    assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertEOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  }
+}
+
+abstract class G<T> {
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
+
+  method(AsserterBuilder<List<Asserter<DartType>>, DartType> assertEOf) {
+    assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    this.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    this.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+    assertEOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  }
+}
+
+AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+
+main() {
+  AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
+  assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  C.assertBOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  C.assertCOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+
+  C c;
+  c.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  c.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+
+  G<int> g;
+  g.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+  g.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
+}
+    '''});
   });
 
   group('downwards inference on function arguments', () {
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 360f6c1..b325909c 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -4,381 +4,33 @@
 
 // TODO(jmesserly): this file needs to be refactored, it's a port from
 // package:dev_compiler's tests
-library test.src.task.strong.strong_test_helper;
+library analyzer.test.src.task.strong.strong_test_helper;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/context/context.dart' show SdkAnalysisContext;
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/engine.dart' hide SdkAnalysisContext;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/task/strong/checker.dart';
-import 'package:analyzer/src/task/strong/rules.dart';
-import 'package:logging/logging.dart'; // TODO(jmesserly): remove
-import 'package:source_span/source_span.dart'; // TODO(jmesserly): remove
+import 'package:logging/logging.dart';
+import 'package:source_span/source_span.dart';
 import 'package:unittest/unittest.dart';
 
-/// Run the checker on a program with files contents as indicated in
-/// [testFiles].
-///
-/// This function makes several assumptions to make it easier to describe error
-/// expectations:
-///
-///   * a file named `/main.dart` exists in [testFiles].
-///   * all expected failures are listed in the source code using comments
-///   immediately in front of the AST node that should contain the error.
-///   * errors are formatted as a token `level:Type`, where `level` is the
-///   logging level were the error would be reported at, and `Type` is the
-///   concrete subclass of [StaticInfo] that denotes the error.
-///
-/// For example, to check that an assignment produces a warning about a boxing
-/// conversion, you can describe the test as follows:
-///
-///     testChecker({
-///       '/main.dart': '''
-///           testMethod() {
-///             dynamic x = /*warning:Box*/3;
-///           }
-///       '''
-///     });
-///
-void testChecker(String name, Map<String, String> testFiles) {
-  test(name, () {
-    expect(testFiles.containsKey('/main.dart'), isTrue,
-        reason: '`/main.dart` is missing in testFiles');
+const String GREEN_COLOR = '\u001b[32m';
 
-    var provider = new MemoryResourceProvider();
-    testFiles.forEach((key, value) {
-      var scheme = 'package:';
-      if (key.startsWith(scheme)) {
-        key = '/packages/${key.substring(scheme.length)}';
-      }
-      provider.newFile(key, value);
-    });
-    var uriResolver = new TestUriResolver(provider);
-    // Enable task model strong mode
-    AnalysisEngine.instance.useTaskModel = true;
-    var context = AnalysisEngine.instance.createAnalysisContext();
-    context.analysisOptions.strongMode = true;
-    context.analysisOptions.strongModeHints = true;
+const String NO_COLOR = '\u001b[0m';
 
-    context.sourceFactory = new SourceFactory([
-      new MockDartSdk(mockSdkSources, reportMissing: true).resolver,
-      uriResolver
-    ]);
+const String _CYAN_COLOR = '\u001b[36m';
 
-    // Run the checker on /main.dart.
-    Source mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart'));
-    var initialLibrary =
-        context.resolveCompilationUnit2(mainSource, mainSource);
+const String _MAGENTA_COLOR = '\u001b[35m';
 
-    var collector = new _ErrorCollector();
-    var checker = new CodeChecker(
-        new TypeRules(context.typeProvider), collector,
-        hints: true);
+const String _RED_COLOR = '\u001b[31m';
 
-    // Extract expectations from the comments in the test files, and
-    // check that all errors we emit are included in the expected map.
-    var allLibraries = reachableLibraries(initialLibrary.element.library);
-    for (var lib in allLibraries) {
-      for (var unit in lib.units) {
-        var errors = <AnalysisError>[];
-        collector.errors = errors;
-
-        var source = unit.source;
-        if (source.uri.scheme == 'dart') continue;
-
-        var librarySource = context.getLibrariesContaining(source).single;
-        var resolved = context.resolveCompilationUnit2(source, librarySource);
-        var analyzerErrors = context
-            .getErrors(source)
-            .errors
-            .where((error) =>
-                error.errorCode.name.startsWith('STRONG_MODE_INFERRED_TYPE'))
-            .toList();
-        errors.addAll(analyzerErrors);
-        checker.visitCompilationUnit(resolved);
-
-        new _ExpectedErrorVisitor(errors).validate(resolved);
-      }
-    }
-  });
-}
-
-class _ErrorCollector implements AnalysisErrorListener {
-  List<AnalysisError> errors;
-  final bool hints;
-  _ErrorCollector({this.hints: true});
-
-  void onError(AnalysisError error) {
-    // Unless DDC hints are requested, filter them out.
-    var HINT = ErrorSeverity.INFO.ordinal;
-    if (hints || error.errorCode.errorSeverity.ordinal > HINT) {
-      errors.add(error);
-    }
-  }
-}
-
-class TestUriResolver extends ResourceUriResolver {
-  final MemoryResourceProvider provider;
-  TestUriResolver(provider)
-      : provider = provider,
-        super(provider);
-
-  @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
-    if (uri.scheme == 'package') {
-      return (provider.getResource('/packages/' + uri.path) as File)
-          .createSource(uri);
-    }
-    return super.resolveAbsolute(uri, actualUri);
-  }
-}
-
-class _ExpectedErrorVisitor extends UnifyingAstVisitor {
-  final Set<AnalysisError> _actualErrors;
-  CompilationUnit _unit;
-  String _unitSourceCode;
-
-  _ExpectedErrorVisitor(List<AnalysisError> actualErrors)
-      : _actualErrors = new Set.from(actualErrors);
-
-  validate(CompilationUnit unit) {
-    _unit = unit;
-    // This reads the file. Only safe because tests use MemoryFileSystem.
-    _unitSourceCode = unit.element.source.contents.data;
-
-    // Visit the compilation unit.
-    unit.accept(this);
-
-    if (_actualErrors.isNotEmpty) {
-      var actualMsgs = _actualErrors.map(_formatActualError).join('\n');
-      fail('Unexpected errors reported by checker:\n\n$actualMsgs');
-    }
-  }
-
-  visitNode(AstNode node) {
-    var token = node.beginToken;
-    var comment = token.precedingComments;
-    // Use error marker found in an immediately preceding comment,
-    // and attach it to the outermost expression that starts at that token.
-    if (comment != null) {
-      while (comment.next != null) {
-        comment = comment.next;
-      }
-      if (comment.end == token.offset && node.parent.beginToken != token) {
-        var commentText = '$comment';
-        var start = commentText.lastIndexOf('/*');
-        var end = commentText.lastIndexOf('*/');
-        if (start != -1 && end != -1) {
-          expect(start, lessThan(end));
-          var errors = commentText.substring(start + 2, end).split(',');
-          var expectations =
-              errors.map(_ErrorExpectation.parse).where((x) => x != null);
-
-          for (var e in expectations) _expectError(node, e);
-        }
-      }
-    }
-    return super.visitNode(node);
-  }
-
-  void _expectError(AstNode node, _ErrorExpectation expected) {
-    // See if we can find the expected error in our actual errors
-    for (var actual in _actualErrors) {
-      if (actual.offset == node.offset && actual.length == node.length) {
-        var actualMsg = _formatActualError(actual);
-        expect(_actualErrorLevel(actual), expected.level,
-            reason: 'expected different error code at:\n\n$actualMsg');
-        expect(errorCodeName(actual.errorCode), expected.typeName,
-            reason: 'expected different error type at:\n\n$actualMsg');
-
-        // We found it. Stop the search.
-        _actualErrors.remove(actual);
-        return;
-      }
-    }
-
-    var span = _createSpan(node.offset, node.length);
-    var levelName = expected.level.name.toLowerCase();
-    var msg = span.message(expected.typeName, color: colorOf(levelName));
-    fail('expected error was not reported at:\n\n$levelName: $msg');
-  }
-
-  Level _actualErrorLevel(AnalysisError actual) {
-    return const <ErrorSeverity, Level>{
-      ErrorSeverity.ERROR: Level.SEVERE,
-      ErrorSeverity.WARNING: Level.WARNING,
-      ErrorSeverity.INFO: Level.INFO
-    }[actual.errorCode.errorSeverity];
-  }
-
-  String _formatActualError(AnalysisError actual) {
-    var span = _createSpan(actual.offset, actual.length);
-    var levelName = _actualErrorLevel(actual).name.toLowerCase();
-    var msg = span.message(actual.message, color: colorOf(levelName));
-    return '$levelName: [${errorCodeName(actual.errorCode)}] $msg';
-  }
-
-  SourceSpan _createSpan(int offset, int len) {
-    return createSpanHelper(_unit.lineInfo, offset, offset + len,
-        _unit.element.source, _unitSourceCode);
-  }
-}
-
-SourceLocation locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
-  var loc = lineInfo.getLocation(offset);
-  return new SourceLocation(offset,
-      sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
-}
-
-SourceSpanWithContext createSpanHelper(
-    LineInfo lineInfo, int start, int end, Source source, String content) {
-  var startLoc = locationForOffset(lineInfo, source.uri, start);
-  var endLoc = locationForOffset(lineInfo, source.uri, end);
-
-  var lineStart = startLoc.offset - startLoc.column;
-  // Find the end of the line. This is not exposed directly on LineInfo, but
-  // we can find it pretty easily.
-  // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get
-  // some help from the LineInfo API.
-  int lineEnd = endLoc.offset;
-  int lineNum = lineInfo.getLocation(lineEnd).lineNumber;
-  while (lineEnd < content.length &&
-      lineInfo.getLocation(++lineEnd).lineNumber == lineNum);
-
-  var text = content.substring(start, end);
-  var lineText = content.substring(lineStart, lineEnd);
-  return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
-}
-
-/// Describes an expected message that should be produced by the checker.
-class _ErrorExpectation {
-  final Level level;
-  final String typeName;
-  _ErrorExpectation(this.level, this.typeName);
-
-  static _ErrorExpectation _parse(String descriptor) {
-    var tokens = descriptor.split(':');
-    expect(tokens.length, 2, reason: 'invalid error descriptor');
-    var name = tokens[0].toUpperCase();
-    var typeName = tokens[1];
-
-    var level =
-        Level.LEVELS.firstWhere((l) => l.name == name, orElse: () => null);
-    expect(level, isNotNull,
-        reason: 'invalid level in error descriptor: `${tokens[0]}`');
-    expect(typeName, isNotNull,
-        reason: 'invalid type in error descriptor: ${tokens[1]}');
-    return new _ErrorExpectation(level, typeName);
-  }
-
-  static _ErrorExpectation parse(String descriptor) {
-    descriptor = descriptor.trim();
-    var tokens = descriptor.split(' ');
-    if (tokens.length == 1) return _parse(tokens[0]);
-    expect(tokens.length, 4, reason: 'invalid error descriptor');
-    expect(tokens[1], "should", reason: 'invalid error descriptor');
-    expect(tokens[2], "be", reason: 'invalid error descriptor');
-    if (tokens[0] == "pass") return null;
-    // TODO(leafp) For now, we just use whatever the current expectation is,
-    // eventually we could do more automated reporting here.
-    return _parse(tokens[0]);
-  }
-
-  String toString() => '$level $typeName';
-}
-
-/// Dart SDK which contains a mock implementation of the SDK libraries. May be
-/// used to speed up execution when most of the core libraries is not needed.
-class MockDartSdk implements DartSdk {
-  final Map<Uri, _MockSdkSource> _sources = {};
-  final bool reportMissing;
-  final Map<String, SdkLibrary> _libs = {};
-  final String sdkVersion = '0';
-  List<String> get uris => _sources.keys.map((uri) => '$uri').toList();
-  final AnalysisContext context = new SdkAnalysisContext();
-  DartUriResolver _resolver;
-  DartUriResolver get resolver => _resolver;
-
-  MockDartSdk(Map<String, String> sources, {this.reportMissing}) {
-    sources.forEach((uriString, contents) {
-      var uri = Uri.parse(uriString);
-      _sources[uri] = new _MockSdkSource(uri, contents);
-      _libs[uriString] = new SdkLibraryImpl(uri.path)
-        ..setDart2JsLibrary()
-        ..setVmLibrary();
-    });
-    _resolver = new DartUriResolver(this);
-    context.sourceFactory = new SourceFactory([_resolver]);
-  }
-
-  List<SdkLibrary> get sdkLibraries => _libs.values.toList();
-  SdkLibrary getSdkLibrary(String dartUri) => _libs[dartUri];
-  Source mapDartUri(String dartUri) => _getSource(Uri.parse(dartUri));
-
-  Source fromEncoding(UriKind kind, Uri uri) {
-    if (kind != UriKind.DART_URI) {
-      throw new UnsupportedError('expected dart: uri kind, got $kind.');
-    }
-    return _getSource(uri);
-  }
-
-  Source _getSource(Uri uri) {
-    var src = _sources[uri];
-    if (src == null) {
-      if (reportMissing) print('warning: missing mock for $uri.');
-      _sources[uri] =
-          src = new _MockSdkSource(uri, 'library dart.${uri.path};');
-    }
-    return src;
-  }
-
-  @override
-  Source fromFileUri(Uri uri) {
-    throw new UnsupportedError('MockDartSdk.fromFileUri');
-  }
-}
-
-class _MockSdkSource implements Source {
-  /// Absolute URI which this source can be imported from.
-  final Uri uri;
-  final String _contents;
-
-  _MockSdkSource(this.uri, this._contents);
-
-  bool exists() => true;
-
-  int get hashCode => uri.hashCode;
-
-  final int modificationStamp = 1;
-
-  TimestampedData<String> get contents =>
-      new TimestampedData(modificationStamp, _contents);
-
-  String get encoding => "${uriKind.encoding}$uri";
-
-  Source get source => this;
-
-  String get fullName => shortName;
-
-  String get shortName => uri.path;
-
-  UriKind get uriKind => UriKind.DART_URI;
-
-  bool get isInSystemLibrary => true;
-
-  Source resolveRelative(Uri relativeUri) =>
-      throw new UnsupportedError('not expecting relative urls in dart: mocks');
-
-  Uri resolveRelativeUri(Uri relativeUri) =>
-      throw new UnsupportedError('not expecting relative urls in dart: mocks');
-}
-
-// TODO(jmesserly): can we reuse the same mock SDK as Analyzer tests?
 /// Sample mock SDK sources.
 final Map<String, String> mockSdkSources = {
   // The list of types below is derived from:
@@ -466,6 +118,58 @@
         ''',
 };
 
+/// Returns an ANSII color escape sequence corresponding to [levelName]. Colors
+/// are defined for: severe, error, warning, or info. Returns null if the level
+/// name is not recognized.
+String colorOf(String levelName) {
+  levelName = levelName.toLowerCase();
+  if (levelName == 'shout' || levelName == 'severe' || levelName == 'error') {
+    return _RED_COLOR;
+  }
+  if (levelName == 'warning') return _MAGENTA_COLOR;
+  if (levelName == 'info') return _CYAN_COLOR;
+  return null;
+}
+
+SourceSpanWithContext createSpanHelper(
+    LineInfo lineInfo, int start, int end, Source source, String content) {
+  var startLoc = locationForOffset(lineInfo, source.uri, start);
+  var endLoc = locationForOffset(lineInfo, source.uri, end);
+
+  var lineStart = startLoc.offset - startLoc.column;
+  // Find the end of the line. This is not exposed directly on LineInfo, but
+  // we can find it pretty easily.
+  // TODO(jmesserly): for now we do the simple linear scan. Ideally we can get
+  // some help from the LineInfo API.
+  int lineEnd = endLoc.offset;
+  int lineNum = lineInfo.getLocation(lineEnd).lineNumber;
+  while (lineEnd < content.length &&
+      lineInfo.getLocation(++lineEnd).lineNumber == lineNum);
+
+  var text = content.substring(start, end);
+  var lineText = content.substring(lineStart, lineEnd);
+  return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
+}
+
+String errorCodeName(ErrorCode errorCode) {
+  var name = errorCode.name;
+  final prefix = 'STRONG_MODE_';
+  if (name.startsWith(prefix)) {
+    return name.substring(prefix.length);
+  } else {
+    // TODO(jmesserly): this is for backwards compat, but not sure it's very
+    // useful to log this.
+    return 'AnalyzerMessage';
+  }
+}
+
+// TODO(jmesserly): can we reuse the same mock SDK as Analyzer tests?
+SourceLocation locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
+  var loc = lineInfo.getLocation(offset);
+  return new SourceLocation(offset,
+      sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
+}
+
 /// Returns all libraries transitively imported or exported from [start].
 List<LibraryElement> reachableLibraries(LibraryElement start) {
   var results = <LibraryElement>[];
@@ -481,33 +185,339 @@
   return results;
 }
 
-String errorCodeName(ErrorCode errorCode) {
-  var name = errorCode.name;
-  final prefix = 'STRONG_MODE_';
-  if (name.startsWith(prefix)) {
-    return name.substring(prefix.length);
-  } else {
-    // TODO(jmesserly): this is for backwards compat, but not sure it's very
-    // useful to log this.
-    return 'AnalyzerMessage';
+/// Run the checker on a program with files contents as indicated in
+/// [testFiles].
+///
+/// This function makes several assumptions to make it easier to describe error
+/// expectations:
+///
+///   * a file named `/main.dart` exists in [testFiles].
+///   * all expected failures are listed in the source code using comments
+///   immediately in front of the AST node that should contain the error.
+///   * errors are formatted as a token `level:Type`, where `level` is the
+///   logging level were the error would be reported at, and `Type` is the
+///   concrete subclass of [StaticInfo] that denotes the error.
+///
+/// For example, to check that an assignment produces a warning about a boxing
+/// conversion, you can describe the test as follows:
+///
+///     testChecker({
+///       '/main.dart': '''
+///           testMethod() {
+///             dynamic x = /*warning:Box*/3;
+///           }
+///       '''
+///     });
+///
+void testChecker(String name, Map<String, String> testFiles) {
+  test(name, () {
+    AnalysisEngine.instance.processRequiredPlugins();
+    expect(testFiles.containsKey('/main.dart'), isTrue,
+        reason: '`/main.dart` is missing in testFiles');
+
+    var provider = new MemoryResourceProvider();
+    testFiles.forEach((key, value) {
+      var scheme = 'package:';
+      if (key.startsWith(scheme)) {
+        key = '/packages/${key.substring(scheme.length)}';
+      }
+      provider.newFile(key, value);
+    });
+    var uriResolver = new TestUriResolver(provider);
+    // Enable task model strong mode
+    var context = AnalysisEngine.instance.createAnalysisContext();
+    context.analysisOptions.strongMode = true;
+    context.analysisOptions.strongModeHints = true;
+
+    context.sourceFactory = new SourceFactory([
+      new MockDartSdk(mockSdkSources, reportMissing: true).resolver,
+      uriResolver
+    ]);
+
+    // Run the checker on /main.dart.
+    Source mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart'));
+    var initialLibrary =
+        context.resolveCompilationUnit2(mainSource, mainSource);
+
+    var collector = new _ErrorCollector();
+    var checker = new CodeChecker(context.typeProvider,
+        new StrongTypeSystemImpl(), collector,
+        hints: true);
+
+    // Extract expectations from the comments in the test files, and
+    // check that all errors we emit are included in the expected map.
+    var allLibraries = reachableLibraries(initialLibrary.element.library);
+    for (var lib in allLibraries) {
+      for (var unit in lib.units) {
+        var errors = <AnalysisError>[];
+        collector.errors = errors;
+
+        var source = unit.source;
+        if (source.uri.scheme == 'dart') continue;
+
+        var librarySource = context.getLibrariesContaining(source).single;
+        var resolved = context.resolveCompilationUnit2(source, librarySource);
+        var analyzerErrors = context
+            .getErrors(source)
+            .errors
+            .where((error) =>
+                error.errorCode.name.startsWith('STRONG_MODE_INFERRED_TYPE'))
+            .toList();
+        errors.addAll(analyzerErrors);
+        checker.visitCompilationUnit(resolved);
+
+        new _ExpectedErrorVisitor(errors).validate(resolved);
+      }
+    }
+  });
+}
+
+/// Dart SDK which contains a mock implementation of the SDK libraries. May be
+/// used to speed up execution when most of the core libraries is not needed.
+class MockDartSdk implements DartSdk {
+  final Map<Uri, _MockSdkSource> _sources = {};
+  final bool reportMissing;
+  final Map<String, SdkLibrary> _libs = {};
+  final String sdkVersion = '0';
+  final AnalysisContext context = new SdkAnalysisContext();
+  DartUriResolver _resolver;
+  MockDartSdk(Map<String, String> sources, {this.reportMissing}) {
+    sources.forEach((uriString, contents) {
+      var uri = Uri.parse(uriString);
+      _sources[uri] = new _MockSdkSource(uri, contents);
+      _libs[uriString] = new SdkLibraryImpl(uri.path)
+        ..setDart2JsLibrary()
+        ..setVmLibrary();
+    });
+    _resolver = new DartUriResolver(this);
+    context.sourceFactory = new SourceFactory([_resolver]);
+  }
+  DartUriResolver get resolver => _resolver;
+
+  List<SdkLibrary> get sdkLibraries => _libs.values.toList();
+
+  List<String> get uris => _sources.keys.map((uri) => '$uri').toList();
+  Source fromEncoding(UriKind kind, Uri uri) {
+    if (kind != UriKind.DART_URI) {
+      throw new UnsupportedError('expected dart: uri kind, got $kind.');
+    }
+    return _getSource(uri);
+  }
+
+  @override
+  Source fromFileUri(Uri uri) {
+    throw new UnsupportedError('MockDartSdk.fromFileUri');
+  }
+
+  SdkLibrary getSdkLibrary(String dartUri) => _libs[dartUri];
+
+  Source mapDartUri(String dartUri) => _getSource(Uri.parse(dartUri));
+
+  Source _getSource(Uri uri) {
+    var src = _sources[uri];
+    if (src == null) {
+      if (reportMissing) print('warning: missing mock for $uri.');
+      _sources[uri] =
+          src = new _MockSdkSource(uri, 'library dart.${uri.path};');
+    }
+    return src;
   }
 }
 
-/// Returns an ANSII color escape sequence corresponding to [levelName]. Colors
-/// are defined for: severe, error, warning, or info. Returns null if the level
-/// name is not recognized.
-String colorOf(String levelName) {
-  levelName = levelName.toLowerCase();
-  if (levelName == 'shout' || levelName == 'severe' || levelName == 'error') {
-    return _RED_COLOR;
+class TestUriResolver extends ResourceUriResolver {
+  final MemoryResourceProvider provider;
+  TestUriResolver(provider)
+      : provider = provider,
+        super(provider);
+
+  @override
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    if (uri.scheme == 'package') {
+      return (provider.getResource('/packages/' + uri.path) as File)
+          .createSource(uri);
+    }
+    return super.resolveAbsolute(uri, actualUri);
   }
-  if (levelName == 'warning') return _MAGENTA_COLOR;
-  if (levelName == 'info') return _CYAN_COLOR;
-  return null;
 }
 
-const String _RED_COLOR = '\u001b[31m';
-const String _MAGENTA_COLOR = '\u001b[35m';
-const String _CYAN_COLOR = '\u001b[36m';
-const String GREEN_COLOR = '\u001b[32m';
-const String NO_COLOR = '\u001b[0m';
+class _ErrorCollector implements AnalysisErrorListener {
+  List<AnalysisError> errors;
+  final bool hints;
+  _ErrorCollector({this.hints: true});
+
+  void onError(AnalysisError error) {
+    // Unless DDC hints are requested, filter them out.
+    var HINT = ErrorSeverity.INFO.ordinal;
+    if (hints || error.errorCode.errorSeverity.ordinal > HINT) {
+      errors.add(error);
+    }
+  }
+}
+
+/// Describes an expected message that should be produced by the checker.
+class _ErrorExpectation {
+  final Level level;
+  final String typeName;
+  _ErrorExpectation(this.level, this.typeName);
+
+  String toString() => '$level $typeName';
+
+  static _ErrorExpectation parse(String descriptor) {
+    descriptor = descriptor.trim();
+    var tokens = descriptor.split(' ');
+    if (tokens.length == 1) return _parse(tokens[0]);
+    expect(tokens.length, 4, reason: 'invalid error descriptor');
+    expect(tokens[1], "should", reason: 'invalid error descriptor');
+    expect(tokens[2], "be", reason: 'invalid error descriptor');
+    if (tokens[0] == "pass") return null;
+    // TODO(leafp) For now, we just use whatever the current expectation is,
+    // eventually we could do more automated reporting here.
+    return _parse(tokens[0]);
+  }
+
+  static _ErrorExpectation _parse(String descriptor) {
+    var tokens = descriptor.split(':');
+    expect(tokens.length, 2, reason: 'invalid error descriptor');
+    var name = tokens[0].toUpperCase();
+    var typeName = tokens[1];
+
+    var level =
+        Level.LEVELS.firstWhere((l) => l.name == name, orElse: () => null);
+    expect(level, isNotNull,
+        reason: 'invalid level in error descriptor: `${tokens[0]}`');
+    expect(typeName, isNotNull,
+        reason: 'invalid type in error descriptor: ${tokens[1]}');
+    return new _ErrorExpectation(level, typeName);
+  }
+}
+
+class _ExpectedErrorVisitor extends UnifyingAstVisitor {
+  final Set<AnalysisError> _actualErrors;
+  CompilationUnit _unit;
+  String _unitSourceCode;
+
+  _ExpectedErrorVisitor(List<AnalysisError> actualErrors)
+      : _actualErrors = new Set.from(actualErrors);
+
+  validate(CompilationUnit unit) {
+    _unit = unit;
+    // This reads the file. Only safe because tests use MemoryFileSystem.
+    _unitSourceCode = unit.element.source.contents.data;
+
+    // Visit the compilation unit.
+    unit.accept(this);
+
+    if (_actualErrors.isNotEmpty) {
+      var actualMsgs = _actualErrors.map(_formatActualError).join('\n');
+      fail('Unexpected errors reported by checker:\n\n$actualMsgs');
+    }
+  }
+
+  visitNode(AstNode node) {
+    var token = node.beginToken;
+    var comment = token.precedingComments;
+    // Use error marker found in an immediately preceding comment,
+    // and attach it to the outermost expression that starts at that token.
+    if (comment != null) {
+      while (comment.next != null) {
+        comment = comment.next;
+      }
+      if (comment.end == token.offset && node.parent.beginToken != token) {
+        var commentText = '$comment';
+        var start = commentText.lastIndexOf('/*');
+        var end = commentText.lastIndexOf('*/');
+        if (start != -1 &&
+            end != -1 &&
+            !commentText.startsWith('/*<', start) &&
+            !commentText.startsWith('/*=', start)) {
+          expect(start, lessThan(end));
+          var errors = commentText.substring(start + 2, end).split(',');
+          var expectations =
+              errors.map(_ErrorExpectation.parse).where((x) => x != null);
+
+          for (var e in expectations) {
+            _expectError(node, e);
+          }
+        }
+      }
+    }
+    return super.visitNode(node);
+  }
+
+  Level _actualErrorLevel(AnalysisError actual) {
+    return const <ErrorSeverity, Level>{
+      ErrorSeverity.ERROR: Level.SEVERE,
+      ErrorSeverity.WARNING: Level.WARNING,
+      ErrorSeverity.INFO: Level.INFO
+    }[actual.errorCode.errorSeverity];
+  }
+
+  SourceSpan _createSpan(int offset, int len) {
+    return createSpanHelper(_unit.lineInfo, offset, offset + len,
+        _unit.element.source, _unitSourceCode);
+  }
+
+  void _expectError(AstNode node, _ErrorExpectation expected) {
+    // See if we can find the expected error in our actual errors
+    for (var actual in _actualErrors) {
+      if (actual.offset == node.offset && actual.length == node.length) {
+        var actualMsg = _formatActualError(actual);
+        expect(_actualErrorLevel(actual), expected.level,
+            reason: 'expected different error code at:\n\n$actualMsg');
+        expect(errorCodeName(actual.errorCode), expected.typeName,
+            reason: 'expected different error type at:\n\n$actualMsg');
+
+        // We found it. Stop the search.
+        _actualErrors.remove(actual);
+        return;
+      }
+    }
+
+    var span = _createSpan(node.offset, node.length);
+    var levelName = expected.level.name.toLowerCase();
+    var msg = span.message(expected.typeName, color: colorOf(levelName));
+    fail('expected error was not reported at:\n\n$levelName: $msg');
+  }
+
+  String _formatActualError(AnalysisError actual) {
+    var span = _createSpan(actual.offset, actual.length);
+    var levelName = _actualErrorLevel(actual).name.toLowerCase();
+    var msg = span.message(actual.message, color: colorOf(levelName));
+    return '$levelName: [${errorCodeName(actual.errorCode)}] $msg';
+  }
+}
+
+class _MockSdkSource implements Source {
+  /// Absolute URI which this source can be imported from.
+  final Uri uri;
+  final String _contents;
+
+  final int modificationStamp = 1;
+
+  _MockSdkSource(this.uri, this._contents);
+
+  TimestampedData<String> get contents =>
+      new TimestampedData(modificationStamp, _contents);
+
+  String get encoding => "${uriKind.encoding}$uri";
+
+  String get fullName => shortName;
+
+  int get hashCode => uri.hashCode;
+
+  bool get isInSystemLibrary => true;
+
+  String get shortName => uri.path;
+
+  Source get source => this;
+
+  UriKind get uriKind => UriKind.DART_URI;
+
+  bool exists() => true;
+
+  Source resolveRelative(Uri relativeUri) =>
+      throw new UnsupportedError('not expecting relative urls in dart: mocks');
+
+  Uri resolveRelativeUri(Uri relativeUri) =>
+      throw new UnsupportedError('not expecting relative urls in dart: mocks');
+}
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index ff87d92..64db1a5 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.strong_mode_test;
+library analyzer.test.src.task.strong_mode_test;
 
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index ffe976c..41e568e 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.src.task.test_all;
+library analyzer.test.src.task.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/task/test_support.dart b/pkg/analyzer/test/src/task/test_support.dart
index e68952b..6db9c95 100644
--- a/pkg/analyzer/test/src/task/test_support.dart
+++ b/pkg/analyzer/test/src/task/test_support.dart
@@ -2,9 +2,9 @@
 // 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 test.src.task.test_support;
+library analyzer.test.src.task.test_support;
 
-import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/task/model.dart';
 
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index f9ad08a..b97bc81 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.src.test_all;
+library analyzer.test.src.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/util/absolute_path_test.dart b/pkg/analyzer/test/src/util/absolute_path_test.dart
index 0f195c2..98b38c5 100644
--- a/pkg/analyzer/test/src/util/absolute_path_test.dart
+++ b/pkg/analyzer/test/src/util/absolute_path_test.dart
@@ -2,7 +2,7 @@
 // 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 test.analyzer.src.util.absolute_path;
+library analyzer.test.src.util.absolute_path_test;
 
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:unittest/unittest.dart';
@@ -18,7 +18,7 @@
 
 @reflectiveTest
 class AbsolutePathContextPosixTest {
-  AbsolutePathContext context = new AbsolutePathContext(r'/');
+  AbsolutePathContext context = new AbsolutePathContext(false);
 
   void test_append() {
     expect(context.append(r'/path/to', r'foo.dart'), r'/path/to/foo.dart');
@@ -38,6 +38,28 @@
     expect(context.dirname(r'/'), r'/');
   }
 
+  void test_isValid_absolute() {
+    expect(context.isValid(r'/foo/bar'), isTrue);
+    expect(context.isValid(r'/foo'), isTrue);
+    expect(context.isValid(r'/'), isTrue);
+    expect(context.isValid(r''), isFalse);
+    expect(context.isValid(r'foo/bar'), isFalse);
+  }
+
+  void test_isValid_normalized() {
+    expect(context.isValid(r'/foo/bar'), isTrue);
+    expect(context.isValid(r'/foo/..bar'), isTrue);
+    expect(context.isValid(r'/foo/.bar/baz'), isTrue);
+    expect(context.isValid(r'/foo/...'), isTrue);
+    expect(context.isValid(r'/foo/bar..'), isTrue);
+    expect(context.isValid(r'/foo/.../bar'), isTrue);
+    expect(context.isValid(r'/foo/.bar/.'), isFalse);
+    expect(context.isValid(r'/foo/bar/../baz'), isFalse);
+    expect(context.isValid(r'/foo/bar/..'), isFalse);
+    expect(context.isValid(r'/foo/./bar'), isFalse);
+    expect(context.isValid(r'/.'), isFalse);
+  }
+
   void test_isWithin() {
     expect(context.isWithin(r'/root/path', r'/root/path/a'), isTrue);
     expect(context.isWithin(r'/root/path', r'/root/other'), isFalse);
@@ -57,7 +79,7 @@
 
 @reflectiveTest
 class AbsolutePathContextWindowsTest {
-  AbsolutePathContext context = new AbsolutePathContext(r'\');
+  AbsolutePathContext context = new AbsolutePathContext(true);
 
   void test_append() {
     expect(context.append(r'C:\path\to', r'foo.dart'), r'C:\path\to\foo.dart');
@@ -77,6 +99,30 @@
     expect(context.dirname(r'C:\'), r'C:\');
   }
 
+  void test_isValid_absolute() {
+    expect(context.isValid(r'C:\foo\bar'), isTrue);
+    expect(context.isValid(r'c:\foo\bar'), isTrue);
+    expect(context.isValid(r'D:\foo\bar'), isTrue);
+    expect(context.isValid(r'C:\foo'), isTrue);
+    expect(context.isValid(r'C:\'), isTrue);
+    expect(context.isValid(r''), isFalse);
+    expect(context.isValid(r'foo\bar'), isFalse);
+  }
+
+  void test_isValid_normalized() {
+    expect(context.isValid(r'C:\foo\bar'), isTrue);
+    expect(context.isValid(r'C:\foo\..bar'), isTrue);
+    expect(context.isValid(r'C:\foo\.bar\baz'), isTrue);
+    expect(context.isValid(r'C:\foo\...'), isTrue);
+    expect(context.isValid(r'C:\foo\bar..'), isTrue);
+    expect(context.isValid(r'C:\foo\...\bar'), isTrue);
+    expect(context.isValid(r'C:\foo\.bar\.'), isFalse);
+    expect(context.isValid(r'C:\foo\bar\..\baz'), isFalse);
+    expect(context.isValid(r'C:\foo\bar\..'), isFalse);
+    expect(context.isValid(r'C:\foo\.\bar'), isFalse);
+    expect(context.isValid(r'C:\.'), isFalse);
+  }
+
   void test_isWithin() {
     expect(context.isWithin(r'C:\root\path', r'C:\root\path\a'), isTrue);
     expect(context.isWithin(r'C:\root\path', r'C:\root\other'), isFalse);
diff --git a/pkg/analyzer/test/src/util/asserts_test.dart b/pkg/analyzer/test/src/util/asserts_test.dart
index a504e43..a3587d3 100644
--- a/pkg/analyzer/test/src/util/asserts_test.dart
+++ b/pkg/analyzer/test/src/util/asserts_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.util.asserts;
+library analyzer.test.src.util.asserts_test;
 
 import 'package:analyzer/src/util/asserts.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/glob_test.dart b/pkg/analyzer/test/src/util/glob_test.dart
index 8ebc04f..c27ff7e 100644
--- a/pkg/analyzer/test/src/util/glob_test.dart
+++ b/pkg/analyzer/test/src/util/glob_test.dart
@@ -2,7 +2,7 @@
 // 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 test.analyzer.src.util.glob;
+library analyzer.test.src.util.glob_test;
 
 import 'package:analyzer/src/util/glob.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/lru_map_test.dart b/pkg/analyzer/test/src/util/lru_map_test.dart
index ef580a0..f460b10 100644
--- a/pkg/analyzer/test/src/util/lru_map_test.dart
+++ b/pkg/analyzer/test/src/util/lru_map_test.dart
@@ -2,7 +2,7 @@
 // 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 test.src.util.lru_map;
+library analyzer.test.src.util.lru_map_test;
 
 import 'package:analyzer/src/util/lru_map.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/src/util/test_all.dart b/pkg/analyzer/test/src/util/test_all.dart
index 6d44df6..d992264 100644
--- a/pkg/analyzer/test/src/util/test_all.dart
+++ b/pkg/analyzer/test/src/util/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.src.util;
+library analyzer.test.src.util.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/test/src/util/yaml_test.dart b/pkg/analyzer/test/src/util/yaml_test.dart
index 6cf00cc..feb812b 100644
--- a/pkg/analyzer/test/src/util/yaml_test.dart
+++ b/pkg/analyzer/test/src/util/yaml_test.dart
@@ -2,7 +2,7 @@
 // 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.util.yaml;
+library analyzer.src.test.util.yaml_test;
 
 import 'package:analyzer/src/util/yaml.dart';
 import 'package:unittest/unittest.dart';
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index c21cc3f..8155789 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -2,7 +2,7 @@
 // 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 test.engine;
+library analyzer.test.test_all;
 
 import 'package:unittest/unittest.dart';
 
diff --git a/pkg/analyzer/tool/task_dependency_graph/check_test.dart b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
index 3d64a85..c689d63 100644
--- a/pkg/analyzer/tool/task_dependency_graph/check_test.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/check_test.dart
@@ -2,7 +2,7 @@
 // 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 task_dependency_graph.check_test;
+library analyzer.tool.task_dependency_graph.check_test;
 
 import 'dart:io';
 
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index daac102..2886352 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -15,7 +15,7 @@
  *   of exactly one task.
  * - Convert this tool to use package_config to find the package map.
  */
-library task_dependency_graph.generate;
+library analyzer.tool.task_dependency_graph.generate;
 
 import 'dart:io' hide File;
 import 'dart:io' as io;
@@ -120,6 +120,7 @@
    * Generate the task dependency graph and return it as a [String].
    */
   String generateFileContents() {
+    AnalysisEngine.instance.processRequiredPlugins();
     List<String> lines = <String>[];
     resourceProvider = PhysicalResourceProvider.INSTANCE;
     DartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
diff --git a/pkg/analyzer_cli/README.md b/pkg/analyzer_cli/README.md
index 1652184..947e730 100644
--- a/pkg/analyzer_cli/README.md
+++ b/pkg/analyzer_cli/README.md
@@ -6,10 +6,6 @@
 DartPad, code editors, and IDEs such as WebStorm use the same
 analysis engine that dartanalyzer uses.
 
-If you want to _contribute_ to the dartanalyzer project, see the
-[contributor docs](https://github.com/dart-lang/analyzer_cli/blob/master/CONTRIBUTOR.md).
-This page contains information about _using_ the dartanalyzer command-line tool.
-
 ## Basic usage
 
 Run the analyzer from the top directory of the package.
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 32d5f37..e48d78c 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -20,11 +20,11 @@
 import 'package:analyzer_cli/src/error_formatter.dart';
 import 'package:analyzer_cli/src/options.dart';
 
-DirectoryBasedDartSdk sdk;
-
 /// The maximum number of sources for which AST structures should be kept in the cache.
 const int _maxCacheSize = 512;
 
+DirectoryBasedDartSdk sdk;
+
 int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch;
 
 /// Analyzes single library [File].
@@ -278,26 +278,10 @@
   }
 
   @override
-  void logError2(String message, Object exception) {
-    errorSink.writeln(message);
-    if (exception != null) {
-      errorSink.writeln(exception.toString());
-    }
-  }
-
-  @override
   void logInformation(String message, [CaughtException exception]) {
     outSink.writeln(message);
     if (exception != null) {
       outSink.writeln(exception);
     }
   }
-
-  @override
-  void logInformation2(String message, Object exception) {
-    outSink.writeln(message);
-    if (exception != null) {
-      outSink.writeln(exception.toString());
-    }
-  }
 }
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 752cb1e..f69e935 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -35,6 +35,7 @@
 import 'package:package_config/packages_file.dart' as pkgfile show parse;
 import 'package:package_config/src/packages_impl.dart' show MapPackages;
 import 'package:path/path.dart' as path;
+import 'package:plugin/manager.dart';
 import 'package:plugin/plugin.dart';
 import 'package:yaml/yaml.dart';
 
@@ -500,12 +501,14 @@
 
   void _processPlugins() {
     List<Plugin> plugins = <Plugin>[];
+    plugins.addAll(AnalysisEngine.instance.requiredPlugins);
+    plugins.add(AnalysisEngine.instance.commandLinePlugin);
+    plugins.add(AnalysisEngine.instance.optionsPlugin);
     plugins.add(linterPlugin);
     plugins.addAll(_userDefinedPlugins);
-    AnalysisEngine.instance.userDefinedPlugins = plugins;
 
-    // This ensures that AE extension manager processes plugins.
-    AnalysisEngine.instance.taskManager;
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins(plugins);
   }
 
   /// Analyze a single source.
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index 5b08f58..03f1b14 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -2,14 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'driver_test.dart' as driver;
 import 'error_test.dart' as error;
 import 'options_test.dart' as options;
 import 'plugin_manager_test.dart' as plugin_manager;
 import 'reporter_test.dart' as reporter;
-import 'sdk_ext_test.dart' as sdk_ext;
-import 'strong_mode_test.dart' as strong_mode;
 import 'super_mixin_test.dart' as super_mixin;
+//import 'driver_test.dart' as driver;
+//import 'sdk_ext_test.dart' as sdk_ext;
+//import 'strong_mode_test.dart' as strong_mode;
 
 main() {
   // TODO(pq): fix tests to run safely on the bots
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index f313355..e6bd812 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -24,7 +24,18 @@
 // TODO(pq): fix tests to run safely on the bots
 // https://github.com/dart-lang/sdk/issues/25001
 main() {}
-_main() {
+const emptyOptionsFile = 'test/data/empty_options.yaml';
+
+/// Start a driver for the given [source], optionally providing additional
+/// [args] and an [options] file path.  The value of [options] defaults to
+/// an empty options file to avoid unwanted configuration from an otherwise
+/// discovered options file.
+void drive(String source,
+        {String options: emptyOptionsFile,
+        List<String> args: const <String>[]}) =>
+    new Driver().start(['--options', options, source]..addAll(args));
+
+not_main() {
   group('Driver', () {
     StringSink savedOutSink, savedErrorSink;
     int savedExitCode;
@@ -286,15 +297,18 @@
         });
 
         test('filters', () {
-          var filters =
-              driver.context.getConfigurationData(CONFIGURED_ERROR_FILTERS);
-          expect(filters, hasLength(1));
+          var processors =
+              driver.context.getConfigurationData(CONFIGURED_ERROR_PROCESSORS);
+          expect(processors, hasLength(1));
 
-          var unused_error = new AnalysisError(
+          var unused_local_variable = new AnalysisError(
               new TestSource(), 0, 1, HintCode.UNUSED_LOCAL_VARIABLE, [
             ['x']
           ]);
-          expect(filters.any((filter) => filter(unused_error)), isTrue);
+
+          var unusedLocalVariable =
+              processors.firstWhere((p) => p.appliesTo(unused_local_variable));
+          expect(unusedLocalVariable.severity, isNull);
         });
 
         test('language config', () {
@@ -430,17 +444,6 @@
   });
 }
 
-const emptyOptionsFile = 'test/data/empty_options.yaml';
-
-/// Start a driver for the given [source], optionally providing additional
-/// [args] and an [options] file path.  The value of [options] defaults to
-/// an empty options file to avoid unwanted configuration from an otherwise
-/// discovered options file.
-void drive(String source,
-        {String options: emptyOptionsFile,
-        List<String> args: const <String>[]}) =>
-    new Driver().start(['--options', options, source]..addAll(args));
-
 Map<String, YamlNode> parseOptions(String src) =>
     new AnalysisOptionsProvider().getOptionsFromString(src);
 
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 794521c..7a62bda 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -10,42 +10,18 @@
 import 'package:analyzer_cli/src/options.dart';
 import 'package:typed_mock/typed_mock.dart';
 
-class MockAnalysisError extends TypedMock implements AnalysisError {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockAnalysisError extends TypedMock implements AnalysisError {}
 
-class MockAnalysisErrorInfo extends TypedMock implements AnalysisErrorInfo {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockAnalysisErrorInfo extends TypedMock implements AnalysisErrorInfo {}
 
-class MockCommandLineOptions extends TypedMock implements CommandLineOptions {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockCommandLineOptions extends TypedMock implements CommandLineOptions {}
 
-class MockErrorCode extends TypedMock implements ErrorCode {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockErrorCode extends TypedMock implements ErrorCode {}
 
-class MockErrorType extends TypedMock implements ErrorType {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockErrorType extends TypedMock implements ErrorType {}
 
-class MockLineInfo extends TypedMock implements LineInfo {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLineInfo extends TypedMock implements LineInfo {}
 
-class MockLineInfo_Location extends TypedMock implements LineInfo_Location {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockLineInfo_Location extends TypedMock implements LineInfo_Location {}
 
-class MockSource extends TypedMock implements Source {
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
+class MockSource extends TypedMock implements Source {}
diff --git a/pkg/analyzer_cli/test/sdk_ext_test.dart b/pkg/analyzer_cli/test/sdk_ext_test.dart
index 6aa793d..e7aa5ce 100644
--- a/pkg/analyzer_cli/test/sdk_ext_test.dart
+++ b/pkg/analyzer_cli/test/sdk_ext_test.dart
@@ -2,7 +2,6 @@
 // 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.
 
-
 /// Test that sdk extensions are properly detected in various scenarios.
 library analyzer_cli.test.sdk_ext;
 
@@ -17,7 +16,7 @@
 // TODO(pq): fix tests to run safely on the bots
 // https://github.com/dart-lang/sdk/issues/25001
 main() {}
-_main() {
+not_main() {
   group('Sdk extensions', () {
     StringSink savedOutSink, savedErrorSink;
     int savedExitCode;
diff --git a/pkg/analyzer_cli/test/strong_mode_test.dart b/pkg/analyzer_cli/test/strong_mode_test.dart
index 763205a..7060fa8 100644
--- a/pkg/analyzer_cli/test/strong_mode_test.dart
+++ b/pkg/analyzer_cli/test/strong_mode_test.dart
@@ -23,8 +23,8 @@
 ///
 // TODO(pq): fix tests to run safely on the bots
 // https://github.com/dart-lang/sdk/issues/25001
-main () {}
-_main() {
+main() {}
+not_main() {
   group('--strong', () {
     StringSink savedOutSink, savedErrorSink;
     int savedExitCode;
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 556006a..71a2d67 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -116,6 +116,8 @@
             useContentSecurityPolicy:
               hasOption(options, Flags.useContentSecurityPolicy),
             useStartupEmitter: hasOption(options, Flags.fastStartup),
+            enableConditionalDirectives:
+                hasOption(options, Flags.conditionalDirectives),
             hasIncrementalSupport:
                 forceIncrementalSupport ||
                 hasOption(options, Flags.incrementalSupport),
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 03f274e..f200ebc 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -46,4 +46,7 @@
   static const String useCpsIr = '--use-cps-ir';
   static const String verbose = '--verbose';
   static const String version = '--version';
+
+  // Experimental flags.
+  static const String conditionalDirectives = '--conditional-directives';
 }
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 79389f5..27b844f 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -112,13 +112,15 @@
   static final Selector codeUnitAt =
       new Selector.call(const PublicName('codeUnitAt'), CallStructure.ONE_ARG);
 
+  static final Selector index = new Selector.index();
+
   /// List of all the selectors held in static fields.
   ///
   /// These objects are shared between different runs in batch-mode and must
   /// thus remain in the [Selector.canonicalizedValues] map.
   static final List<Selector> ALL = <Selector>[
       cancel, current, iterator, moveNext, noSuchMethod_, toString_,
-      hashCode_, compareTo, equals, length, codeUnitAt];
+      hashCode_, compareTo, equals, length, codeUnitAt, index];
 }
 
 /// [Uri]s commonly used.
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index fa655c5..3b98b92 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -454,6 +454,7 @@
             this.deferredMapUri: null,
             this.dumpInfo: false,
             bool useStartupEmitter: false,
+            bool enableConditionalDirectives: false,
             this.useContentSecurityPolicy: false,
             bool hasIncrementalSupport: false,
             this.enableExperimentalMirrors: false,
@@ -515,9 +516,12 @@
       libraryLoader = new LibraryLoaderTask(this),
       serialization = new SerializationTask(this),
       scanner = new ScannerTask(this),
-      dietParser = new DietParserTask(this),
-      parser = new ParserTask(this),
-      patchParser = new PatchParserTask(this),
+      dietParser = new DietParserTask(
+          this, enableConditionalDirectives: enableConditionalDirectives),
+      parser = new ParserTask(
+          this, enableConditionalDirectives: enableConditionalDirectives),
+      patchParser = new PatchParserTask(
+          this, enableConditionalDirectives: enableConditionalDirectives),
       resolver = new ResolverTask(this, backend.constantCompilerTask),
       closureToClassMapper = new closureMapping.ClosureTask(this),
       checker = new TypeCheckerTask(this),
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 2a7c5c4..945aaba 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -502,6 +502,7 @@
   final List<ConstantValue> keys;
   final List<ConstantValue> values;
   final int hashCode;
+  Map<ConstantValue, ConstantValue> _lookupMap;
 
   MapConstantValue(InterfaceType type,
                    List<ConstantValue> keys,
@@ -539,6 +540,12 @@
 
   int get length => keys.length;
 
+  ConstantValue lookup(ConstantValue key) {
+    var lookupMap = _lookupMap ??=
+        new Map<ConstantValue, ConstantValue>.fromIterables(keys, values);
+    return lookupMap[key];
+  }
+
   accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg);
 
   String unparse() {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index b75af81..a80f2f7 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -702,6 +702,19 @@
         target, selector, mask, arguments, sourceInformation);
   }
 
+  ir.Primitive buildStaticNoSuchMethod(Selector selector,
+                                       List<ir.Primitive> arguments) {
+    Element thrower = program.throwNoSuchMethod;
+    ir.Primitive receiver = buildStringConstant('');
+    ir.Primitive name = buildStringConstant(selector.name);
+    ir.Primitive argumentList = buildListLiteral(null, arguments);
+    ir.Primitive expectedArgumentNames = buildNullConstant();
+    return buildStaticFunctionInvocation(
+        thrower,
+        new CallStructure.unnamed(4),
+        [receiver, name, argumentList, expectedArgumentNames]);
+  }
+
 
   /// Create a [ir.Constant] from [value] and add it to the CPS term.
   ir.Constant buildConstant(ConstantValue value,
@@ -1433,11 +1446,18 @@
     // TODO(johnniwinther): Extract this as a provided strategy.
     if (Elements.isLocal(variableElement)) {
       bodyBuilder.buildLocalVariableSet(variableElement, currentValue);
-    } else if (Elements.isMalformed(variableElement)) {
-      bodyBuilder.buildErroneousInvocation(variableElement,
-          new Selector.setter(
-              new Name(variableElement.name, variableElement.library)),
-          <ir.Primitive>[currentValue]);
+    } else if (Elements.isError(variableElement) ||
+               Elements.isMalformed(variableElement)) {
+      Selector selector = new Selector.setter(
+          new Name(variableElement.name, variableElement.library));
+      List<ir.Primitive> value = <ir.Primitive>[currentValue];
+      // Note the order of the comparisons below.  It can be the case that an
+      // element isError and isMalformed.
+      if (Elements.isError(variableElement)) {
+        bodyBuilder.buildStaticNoSuchMethod(selector, value);
+      } else {
+        bodyBuilder.buildErroneousInvocation(variableElement, selector, value);
+      }
     } else if (Elements.isStaticOrTopLevel(variableElement)) {
       if (variableElement.isField) {
         bodyBuilder.buildStaticFieldSet(variableElement, currentValue);
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index 829f942..e4fb1fd 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -185,25 +185,25 @@
   ClosureScope getClosureScopeForNode(ast.Node node);
   ClosureEnvironment getClosureEnvironment();
 
-  /// Normalizes the argument list to a static invocation (i.e. where the target
-  /// element is known).
+  /// Normalizes the argument list of a static invocation.
   ///
-  /// For the JS backend, inserts default arguments and normalizes order of
-  /// named arguments.
-  ///
-  /// For the Dart backend, returns [arguments].
-  List<ir.Primitive> normalizeStaticArguments(
+  /// A static invocation is one where the target is known.  The argument list
+  /// [arguments] is normalized by adding default values for optional arguments
+  /// that are not passed, and by sorting it in place so that named arguments
+  /// appear in a canonical order.  A [CallStructure] reflecting this order
+  /// is returned.
+  CallStructure normalizeStaticArguments(
       CallStructure callStructure,
       FunctionElement target,
       List<ir.Primitive> arguments);
 
-  /// Normalizes the argument list of a dynamic invocation (i.e. where the
-  /// target element is unknown).
+  /// Normalizes the argument list of a dynamic invocation.
   ///
-  /// For the JS backend, normalizes order of named arguments.
-  ///
-  /// For the Dart backend, returns [arguments].
-  List<ir.Primitive> normalizeDynamicArguments(
+  /// A dynamic invocation is one where the target is not known.  The argument
+  /// list [arguments] is normalized by sorting it in place so that the named
+  /// arguments appear in a canonical order.  A [CallStructure] reflecting this
+  /// order is returned.
+  CallStructure normalizeDynamicArguments(
       CallStructure callStructure,
       List<ir.Primitive> arguments);
 
@@ -316,8 +316,8 @@
     CallStructure callStructure = new CallStructure(
         redirectingSignature.parameterCount,
         namedParameters);
-    arguments = normalizeStaticArguments(callStructure, targetConstructor,
-        arguments);
+    callStructure =
+        normalizeStaticArguments(callStructure, targetConstructor, arguments);
     ir.Primitive instance = irBuilder.buildConstructorInvocation(
         targetConstructor,
         callStructure,
@@ -719,10 +719,9 @@
                                      ast.NodeList argumentsNode,
                                      CallStructure callStructure, _) {
     ir.Primitive receiver = visit(expression);
-    List<ir.Primitive> arguments = node.arguments.mapToList(visit);
-    arguments = normalizeDynamicArguments(callStructure, arguments);
-    return irBuilder.buildCallInvocation(
-        receiver, callStructure, arguments,
+    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+    callStructure = normalizeDynamicArguments(callStructure, arguments);
+    return irBuilder.buildCallInvocation(receiver, callStructure, arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, argumentsNode));
   }
@@ -950,12 +949,16 @@
                                ast.Node left,
                                op.BinaryOperator operator,
                                ast.Node right) {
-    Selector selector = new Selector.binaryOperator(operator.selectorName);
     ir.Primitive receiver = visit(left);
+    Selector selector = new Selector.binaryOperator(operator.selectorName);
     List<ir.Primitive> arguments = <ir.Primitive>[visit(right)];
-    arguments = normalizeDynamicArguments(selector.callStructure, arguments);
+    CallStructure callStructure =
+        normalizeDynamicArguments(selector.callStructure, arguments);
     return irBuilder.buildDynamicInvocation(
-        receiver, selector, elements.getTypeMask(node), arguments,
+        receiver,
+        new Selector(selector.kind, selector.memberName, callStructure),
+        elements.getTypeMask(node),
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, node.selector));
   }
@@ -972,12 +975,16 @@
   ir.Primitive visitIndex(ast.Send node,
                           ast.Node receiver,
                           ast.Node index, _) {
-    Selector selector = new Selector.index();
     ir.Primitive target = visit(receiver);
+    Selector selector = new Selector.index();
     List<ir.Primitive> arguments = <ir.Primitive>[visit(index)];
-    arguments = normalizeDynamicArguments(selector.callStructure, arguments);
+    CallStructure callStructure =
+        normalizeDynamicArguments(selector.callStructure, arguments);
     return irBuilder.buildDynamicInvocation(
-        target, selector, elements.getTypeMask(node), arguments,
+        target,
+        new Selector(selector.kind, selector.memberName, callStructure),
+        elements.getTypeMask(node),
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(receiver, node.selector));
   }
@@ -985,11 +992,9 @@
   ir.Primitive translateSuperBinary(FunctionElement function,
                                     op.BinaryOperator operator,
                                     ast.Node argument) {
-    CallStructure callStructure = CallStructure.ONE_ARG;
     List<ir.Primitive> arguments = <ir.Primitive>[visit(argument)];
-    arguments = normalizeDynamicArguments(callStructure, arguments);
-    return irBuilder.buildSuperMethodInvocation(
-        function, callStructure, arguments);
+    return irBuilder.buildSuperMethodInvocation(function,
+        CallStructure.ONE_ARG, arguments);
   }
 
   @override
@@ -1081,28 +1086,33 @@
 
   // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
   // semantic correlation between arguments and invocation.
-  List<ir.Primitive> translateDynamicArguments(ast.NodeList nodeList,
-                                               CallStructure callStructure) {
-    List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+  CallStructure translateDynamicArguments(ast.NodeList nodeList,
+                                          CallStructure callStructure,
+                                          List<ir.Primitive> arguments) {
+    assert(arguments.isEmpty);
+    for (ast.Node node in nodeList) arguments.add(visit(node));
     return normalizeDynamicArguments(callStructure, arguments);
   }
 
   // TODO(johnniwinther): Handle this in the [IrBuilder] to ensure the correct
   // semantic correlation between arguments and invocation.
-  List<ir.Primitive> translateStaticArguments(ast.NodeList nodeList,
-                                              Element element,
-                                              CallStructure callStructure) {
-    List<ir.Primitive> arguments = nodeList.nodes.mapToList(visit);
+  CallStructure translateStaticArguments(ast.NodeList nodeList,
+                                         Element element,
+                                         CallStructure callStructure,
+                                         List<ir.Primitive> arguments) {
+    assert(arguments.isEmpty);
+    for (ast.Node node in nodeList) arguments.add(visit(node));
     return normalizeStaticArguments(callStructure, element, arguments);
   }
 
   ir.Primitive translateCallInvoke(ir.Primitive target,
-                                   ast.NodeList arguments,
+                                   ast.NodeList argumentsNode,
                                    CallStructure callStructure,
                                    SourceInformation sourceInformation) {
-
-    return irBuilder.buildCallInvocation(target, callStructure,
-        translateDynamicArguments(arguments, callStructure),
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(target, callStructure, arguments,
         sourceInformation: sourceInformation);
   }
 
@@ -1123,12 +1133,18 @@
   ir.Primitive handleDynamicInvoke(
       ast.Send node,
       ast.Node receiver,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector,
       _) {
+    ir.Primitive target = translateReceiver(receiver);
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    CallStructure callStructure = translateDynamicArguments(
+        argumentsNode, selector.callStructure, arguments);
     return irBuilder.buildDynamicInvocation(
-        translateReceiver(receiver), selector, elements.getTypeMask(node),
-        translateDynamicArguments(arguments, selector.callStructure),
+        target,
+        new Selector(selector.kind, selector.memberName, callStructure),
+        elements.getTypeMask(node),
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, node.selector));
   }
@@ -1137,39 +1153,56 @@
   ir.Primitive visitIfNotNullDynamicPropertyInvoke(
       ast.Send node,
       ast.Node receiver,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector,
       _) {
     ir.Primitive target = visit(receiver);
     return irBuilder.buildIfNotNullSend(
         target,
-        nested(() => irBuilder.buildDynamicInvocation(
-            target, selector, elements.getTypeMask(node),
-            translateDynamicArguments(arguments, selector.callStructure))));
+        nested(() {
+          List<ir.Primitive> arguments = <ir.Primitive>[];
+          CallStructure callStructure = translateDynamicArguments(
+              argumentsNode, selector.callStructure, arguments);
+          return irBuilder.buildDynamicInvocation(
+              target,
+              new Selector(selector.kind, selector.memberName, callStructure),
+              elements.getTypeMask(node),
+              arguments);
+        }));
   }
 
   ir.Primitive handleLocalInvoke(
       ast.Send node,
       LocalElement element,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    return irBuilder.buildLocalVariableInvocation(element, callStructure,
-        translateDynamicArguments(arguments, callStructure),
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildLocalVariableInvocation(
+        element,
+        callStructure,
+        arguments,
         callSourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
   ir.Primitive visitLocalFunctionInvoke(
       ast.Send node,
       LocalFunctionElement function,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    return irBuilder.buildLocalFunctionInvocation(function, callStructure,
-        translateDynamicArguments(arguments, callStructure),
-        sourceInformationBuilder.buildCall(node, arguments));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildLocalFunctionInvocation(
+        function,
+        callStructure,
+        arguments,
+        sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
@@ -1181,16 +1214,20 @@
   ir.Primitive handleStaticFieldInvoke(
       ast.Send node,
       FieldElement field,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
     SourceInformation src = sourceInformationBuilder.buildGet(node);
     ir.Primitive target = buildStaticFieldGet(field, src);
-    return irBuilder.buildCallInvocation(target,
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
@@ -1207,7 +1244,7 @@
       MethodElement function,
       ast.NodeList arguments,
       CallStructure callStructure, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         elements.getSelector(node),
         arguments.nodes.mapToList(visit));
   }
@@ -1216,58 +1253,75 @@
   ir.Primitive handleStaticGetterInvoke(
       ast.Send node,
       FunctionElement getter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    ir.Primitive target = irBuilder.buildStaticGetterGet(
-        getter, sourceInformationBuilder.buildGet(node));
-    return irBuilder.buildCallInvocation(target,
+    ir.Primitive target = irBuilder.buildStaticGetterGet(getter,
+        sourceInformationBuilder.buildGet(node));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
   ir.Primitive visitSuperFieldInvoke(
       ast.Send node,
       FieldElement field,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
     ir.Primitive target = irBuilder.buildSuperFieldGet(field);
-    return irBuilder.buildCallInvocation(target,
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
   ir.Primitive visitSuperGetterInvoke(
       ast.Send node,
       FunctionElement getter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    ir.Primitive target = irBuilder.buildSuperGetterGet(
-        getter, sourceInformationBuilder.buildGet(node));
-    return irBuilder.buildCallInvocation(target,
+    ir.Primitive target = irBuilder.buildSuperGetterGet(getter,
+        sourceInformationBuilder.buildGet(node));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildCallInvocation(
+        target,
         callStructure,
-        translateDynamicArguments(arguments, callStructure),
+        arguments,
         sourceInformation:
-            sourceInformationBuilder.buildCall(node, arguments));
+            sourceInformationBuilder.buildCall(node, argumentsNode));
   }
 
   @override
   ir.Primitive visitSuperMethodInvoke(
       ast.Send node,
       MethodElement method,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    return irBuilder.buildSuperMethodInvocation(method, callStructure,
-        translateDynamicArguments(arguments, callStructure),
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure = translateStaticArguments(argumentsNode, method,
+        callStructure, arguments);
+    return irBuilder.buildSuperMethodInvocation(
+        method,
+        callStructure,
+        arguments,
         sourceInformation:
             sourceInformationBuilder.buildCall(node, node.selector));
   }
@@ -1278,22 +1332,30 @@
       MethodElement method,
       ast.NodeList arguments,
       CallStructure callStructure, _) {
+    List<ir.Primitive> normalizedArguments = <ir.Primitive>[];
+    CallStructure normalizedCallStructure =
+      translateDynamicArguments(arguments, callStructure, normalizedArguments);
     return buildInstanceNoSuchMethod(
-        elements.getSelector(node),
+        new Selector.call(method.memberName, normalizedCallStructure),
         elements.getTypeMask(node),
-        translateDynamicArguments(arguments, callStructure));
+        normalizedArguments);
   }
 
   @override
   ir.Primitive visitUnresolvedSuperInvoke(
       ast.Send node,
       Element element,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector, _) {
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    CallStructure callStructure = translateDynamicArguments(
+        argumentsNode, selector.callStructure, arguments);
+    // TODO(johnniwinther): Supply a member name to the visit function instead
+    // of looking it up in elements.
     return buildInstanceNoSuchMethod(
-        elements.getSelector(node),
+        new Selector.call(elements.getSelector(node).memberName, callStructure),
         elements.getTypeMask(node),
-        translateDynamicArguments(arguments, selector.callStructure));
+        arguments);
   }
 
   @override
@@ -1371,15 +1433,19 @@
       rhsValue = irBuilder.buildIntegerConstant(1);
     }
     List<ir.Primitive> arguments = <ir.Primitive>[rhsValue];
-    arguments = normalizeDynamicArguments(
-        operatorSelector.callStructure, arguments);
+    CallStructure callStructure =
+        normalizeDynamicArguments(operatorSelector.callStructure, arguments);
     TypeMask operatorTypeMask =
         elements.getOperatorTypeMaskInComplexSendSet(node);
     SourceInformation operatorSourceInformation =
         sourceInformationBuilder.buildCall(node, node.assignmentOperator);
     ir.Primitive result = irBuilder.buildDynamicInvocation(
-        value, operatorSelector, operatorTypeMask, arguments,
-            sourceInformation: operatorSourceInformation);
+        value,
+        new Selector(operatorSelector.kind, operatorSelector.memberName,
+            callStructure),
+        operatorTypeMask,
+        arguments,
+        sourceInformation: operatorSourceInformation);
     setValue(result);
     return rhs.kind == CompoundKind.POSTFIX ? value : result;
   }
@@ -1577,7 +1643,7 @@
   ir.Primitive buildLocalNoSuchSetter(LocalElement local, ir.Primitive value) {
     Selector selector = new Selector.setter(
         new Name(local.name, local.library, isSetter: true));
-    return buildStaticNoSuchMethod(selector, [value]);
+    return irBuilder.buildStaticNoSuchMethod(selector, [value]);
   }
 
   @override
@@ -1633,13 +1699,13 @@
   }
 
   ir.Primitive buildStaticNoSuchGetter(Element element) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.getter(new Name(element.name, element.library)),
         const <ir.Primitive>[]);
   }
 
   ir.Primitive buildStaticNoSuchSetter(Element element, ir.Primitive value) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(new Name(element.name, element.library)),
         <ir.Primitive>[value]);
   }
@@ -1858,11 +1924,11 @@
         getValue: () {
           Selector selector = new Selector.index();
           List<ir.Primitive> arguments = <ir.Primitive>[indexValue];
-          arguments =
+          CallStructure callStructure =
               normalizeDynamicArguments(selector.callStructure, arguments);
           return irBuilder.buildDynamicInvocation(
               target,
-              selector,
+              new Selector(selector.kind, selector.memberName, callStructure),
               elements.getGetterTypeMaskInComplexSendSet(node),
               arguments,
               sourceInformation:
@@ -1968,10 +2034,6 @@
     return irBuilder.buildNonTailThrow(visit(node.expression));
   }
 
-  ir.Primitive buildStaticNoSuchMethod(
-      Selector selector,
-      List<ir.Primitive> arguments);
-
   ir.Primitive buildInstanceNoSuchMethod(
       Selector selector,
       TypeMask mask,
@@ -1989,7 +2051,7 @@
       ast.Node rhs, _) {
     // TODO(asgerf): What is unresolved? The getter and/or the setter?
     //               If it was the setter, we must evaluate the right-hand side.
-    return buildStaticNoSuchMethod(elements.getSelector(node), []);
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
   }
 
   @override
@@ -2008,29 +2070,36 @@
       ast.NewExpression node,
       Element constructor,
       DartType type,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       Selector selector, _) {
     // If the class is there but the constructor is missing, it's an NSM error.
-    return buildStaticNoSuchMethod(selector,
-        translateDynamicArguments(arguments, selector.callStructure));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    CallStructure callStructure = translateDynamicArguments(
+        argumentsNode, selector.callStructure, arguments);
+    return irBuilder.buildStaticNoSuchMethod(
+        new Selector(selector.kind, selector.memberName, callStructure),
+        arguments);
   }
 
   @override
   ir.Primitive visitConstructorIncompatibleInvoke(
       ast.NewExpression node,
-      Element constructor,
+      ConstructorElement constructor,
       DartType type,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node.send),
-        translateDynamicArguments(arguments, callStructure));
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildStaticNoSuchMethod(
+        new Selector.call(constructor.memberName, callStructure), arguments);
   }
 
   @override
   ir.Primitive visitUnresolvedGet(
       ast.Send node,
       Element element, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node), []);
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node), []);
   }
 
   @override
@@ -2039,7 +2108,7 @@
       Element element,
       ast.NodeList arguments,
       Selector selector, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node),
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
         arguments.nodes.mapToList(visit));
   }
 
@@ -2048,13 +2117,16 @@
        ast.NewExpression node,
        ConstructorElement constructor,
        InterfaceType type,
-       ast.NodeList arguments,
+       ast.NodeList argumentsNode,
        CallStructure callStructure, _) {
     String nameString = Elements.reconstructConstructorName(constructor);
     Name name = new Name(nameString, constructor.library);
-    return buildStaticNoSuchMethod(
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.call(name, callStructure),
-        translateDynamicArguments(arguments, callStructure));
+        arguments);
   }
 
   @override
@@ -2062,7 +2134,8 @@
       ast.Send node,
       Element element,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(elements.getSelector(node), [visit(rhs)]);
+    return irBuilder.buildStaticNoSuchMethod(elements.getSelector(node),
+        [visit(rhs)]);
   }
 
   @override
@@ -2113,7 +2186,7 @@
       ast.Node rhs, _) {
     InterfaceType type = constant.type;
     ClassElement element = type.element;
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(element.memberName),
         [visit(rhs)]);
   }
@@ -2125,7 +2198,7 @@
       ast.Node rhs, _) {
     TypedefType type = constant.type;
     TypedefElement element = type.element;
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(element.memberName),
         [visit(rhs)]);
   }
@@ -2135,7 +2208,7 @@
       ast.SendSet node,
       TypeVariableElement element,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(element.memberName), [visit(rhs)]);
   }
 
@@ -2144,7 +2217,7 @@
       ast.SendSet node,
       ConstantExpression constant,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(Names.dynamic_), [visit(rhs)]);
   }
 
@@ -2155,6 +2228,7 @@
       InterfaceType type,
       ast.NodeList arguments,
       CallStructure callStructure, _) {
+    for (ast.Node argument in arguments) visit(argument);
     return buildAbstractClassInstantiationError(element.enclosingClass);
   }
 
@@ -2164,7 +2238,7 @@
       FieldElement field,
       ast.Node rhs, _) {
     // TODO(asgerf): Include class name somehow for static class members?
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(field.memberName),
         [visit(rhs)]);
   }
@@ -2185,7 +2259,7 @@
       ast.SendSet node,
       LocalElement local,
       ast.Node rhs, _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(new Name(local.name, local.library)),
         [visit(rhs)]);
   }
@@ -2196,7 +2270,7 @@
       MethodElement function,
       ast.Node rhs,
       _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(function.memberName),
         [visit(rhs)]);
   }
@@ -2207,7 +2281,7 @@
       GetterElement getter,
       ast.Node rhs,
       _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.setter(getter.memberName),
         [visit(rhs)]);
   }
@@ -2217,7 +2291,7 @@
       ast.Send node,
       SetterElement setter,
       _) {
-    return buildStaticNoSuchMethod(
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.getter(setter.memberName),
         []);
   }
@@ -2226,13 +2300,13 @@
   ir.Primitive handleStaticSetterInvoke(
       ast.Send node,
       SetterElement setter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure, _) {
     // Translate as a method call.
-    List<ir.Primitive> args = arguments.nodes.mapToList(visit);
-    return buildStaticNoSuchMethod(
+    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
+    return irBuilder.buildStaticNoSuchMethod(
         new Selector.call(setter.memberName, callStructure),
-        args);
+        arguments);
   }
 
   @override
@@ -2273,14 +2347,15 @@
   ir.Primitive visitSuperSetterInvoke(
       ast.Send node,
       SetterElement setter,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure, _) {
-    List<ir.Primitive> args =
-        translateDynamicArguments(arguments, callStructure);
+    List<ir.Primitive> arguments = <ir.Primitive>[];
+    callStructure =
+        translateDynamicArguments(argumentsNode, callStructure, arguments);
     return buildInstanceNoSuchMethod(
         new Selector.call(setter.memberName, callStructure),
         elements.getTypeMask(node),
-        args);
+        arguments);
   }
 
   ir.FunctionDefinition nullIfGiveup(ir.FunctionDefinition action()) {
@@ -2501,6 +2576,7 @@
   }
 
   FunctionElement get throwTypeErrorHelper => _backend.helpers.throwTypeError;
+  Element get throwNoSuchMethod => _backend.helpers.throwNoSuchMethod;
 
   ClassElement get nullClass => _compiler.coreClasses.nullClass;
 
@@ -3207,70 +3283,56 @@
     }
   }
 
-  /// Inserts default arguments and normalizes order of named arguments.
-  List<ir.Primitive> normalizeStaticArguments(
-      CallStructure callStructure,
-      FunctionElement target,
-      List<ir.Primitive> arguments) {
+  CallStructure normalizeStaticArguments(CallStructure callStructure,
+                                         FunctionElement target,
+                                         List<ir.Primitive> arguments) {
     target = target.implementation;
     FunctionSignature signature = target.functionSignature;
     if (!signature.optionalParametersAreNamed &&
         signature.parameterCount == arguments.length) {
-      // Optimization: don't copy the argument list for trivial cases.
-      return arguments;
+      return callStructure;
     }
 
-    List<ir.Primitive> result = <ir.Primitive>[];
-    int i = 0;
-    signature.forEachRequiredParameter((ParameterElement element) {
-      result.add(arguments[i]);
-      ++i;
-    });
-
     if (!signature.optionalParametersAreNamed) {
+      int i = signature.requiredParameterCount;
       signature.forEachOptionalParameter((ParameterElement element) {
-        if (i < arguments.length) {
-          result.add(arguments[i]);
+        if (i < callStructure.positionalArgumentCount) {
           ++i;
         } else {
-          result.add(translateDefaultValue(element));
+          arguments.add(translateDefaultValue(element));
         }
       });
-    } else {
-      int offset = i;
-      // Iterate over the optional parameters of the signature, and try to
-      // find them in [compiledNamedArguments]. If found, we use the
-      // value in the temporary list, otherwise the default value.
-      signature.orderedOptionalParameters.forEach((ParameterElement element) {
-        int nameIndex = callStructure.namedArguments.indexOf(element.name);
-        if (nameIndex != -1) {
-          int translatedIndex = offset + nameIndex;
-          result.add(arguments[translatedIndex]);
-        } else {
-          result.add(translateDefaultValue(element));
-        }
-      });
+      return new CallStructure(signature.parameterCount);
     }
-    return result;
+
+    int offset = signature.requiredParameterCount;
+    List<ir.Primitive> namedArguments = arguments.sublist(offset);
+    arguments.length = offset;
+    List<String> normalizedNames = <String>[];
+    // Iterate over the optional parameters of the signature, and try to
+    // find them in the callStructure's named arguments. If found, we use the
+    // value in the temporary list, otherwise the default value.
+    signature.orderedOptionalParameters.forEach((ParameterElement element) {
+      int nameIndex = callStructure.namedArguments.indexOf(element.name);
+      arguments.add(nameIndex == -1 ? translateDefaultValue(element)
+                                    : namedArguments[nameIndex]);
+      normalizedNames.add(element.name);
+    });
+    return new CallStructure(signature.parameterCount, normalizedNames);
   }
 
-  /// Normalizes order of named arguments.
-  List<ir.Primitive> normalizeDynamicArguments(
-      CallStructure callStructure,
-      List<ir.Primitive> arguments) {
+  CallStructure normalizeDynamicArguments(CallStructure callStructure,
+                                          List<ir.Primitive> arguments) {
     assert(arguments.length == callStructure.argumentCount);
-    // Optimization: don't copy the argument list for trivial cases.
-    if (callStructure.namedArguments.isEmpty) return arguments;
-    List<ir.Primitive> result = <ir.Primitive>[];
-    for (int i=0; i < callStructure.positionalArgumentCount; i++) {
-      result.add(arguments[i]);
-    }
+    if (callStructure.namedArguments.isEmpty) return callStructure;
+    int destinationIndex = callStructure.positionalArgumentCount;
+    List<ir.Primitive> namedArguments = arguments.sublist(destinationIndex);
     for (String argName in callStructure.getOrderedNamedArguments()) {
-      int nameIndex = callStructure.namedArguments.indexOf(argName);
-      int translatedIndex = callStructure.positionalArgumentCount + nameIndex;
-      result.add(arguments[translatedIndex]);
+      int sourceIndex = callStructure.namedArguments.indexOf(argName);
+      arguments[destinationIndex++] = namedArguments[sourceIndex];
     }
-    return result;
+    return new CallStructure(callStructure.argumentCount,
+                             callStructure.getOrderedNamedArguments());
   }
 
   @override
@@ -3278,14 +3340,14 @@
       ast.NewExpression node,
       ConstructorElement constructor,
       DartType type,
-      ast.NodeList arguments,
+      ast.NodeList argumentsNode,
       CallStructure callStructure,
       _) {
-    List<ir.Primitive> arguments =
-        node.send.arguments.mapToList(visit, growable:false);
+    List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
     // Use default values from the effective target, not the immediate target.
     ConstructorElement target = constructor.effectiveTarget;
-    arguments = normalizeStaticArguments(callStructure, target, arguments);
+    callStructure =
+        normalizeStaticArguments(callStructure, target, arguments);
     TypeMask allocationSiteType;
     ast.Node send = node.send;
     if (Elements.isFixedListConstructorCall(constructor, send, compiler) ||
@@ -3304,20 +3366,6 @@
   }
 
   @override
-  ir.Primitive buildStaticNoSuchMethod(Selector selector,
-                                       List<ir.Primitive> arguments) {
-    Element thrower = backend.helpers.throwNoSuchMethod;
-    ir.Primitive receiver = irBuilder.buildStringConstant('');
-    ir.Primitive name = irBuilder.buildStringConstant(selector.name);
-    ir.Primitive argumentList = irBuilder.buildListLiteral(null, arguments);
-    ir.Primitive expectedArgumentNames = irBuilder.buildNullConstant();
-    return irBuilder.buildStaticFunctionInvocation(
-        thrower,
-        new CallStructure.unnamed(4),
-        [receiver, name, argumentList, expectedArgumentNames]);
-  }
-
-  @override
   ir.Primitive buildInstanceNoSuchMethod(Selector selector,
                                          TypeMask mask,
                                          List<ir.Primitive> arguments) {
@@ -3396,12 +3444,15 @@
         reporter.internalError(node,
             'Isolate library and compiler mismatch.');
       }
-      List<ir.Primitive> arguments = translateStaticArguments(argumentList,
-          element, callStructure);
-      return irBuilder.buildStaticFunctionInvocation(element,
-          callStructure, arguments,
+      List<ir.Primitive> arguments = <ir.Primitive>[];
+      callStructure = translateStaticArguments(argumentList, element,
+          callStructure, arguments);
+      return irBuilder.buildStaticFunctionInvocation(
+          element,
+          callStructure,
+          arguments,
           sourceInformation:
-                sourceInformationBuilder.buildCall(node, node.selector));
+              sourceInformationBuilder.buildCall(node, node.selector));
     }
 
     /// Lookup the value of the enum described by [node].
@@ -3591,14 +3642,18 @@
   @override
   ir.Primitive handleStaticFunctionInvoke(ast.Send node,
                                           MethodElement function,
-                                          ast.NodeList argumentList,
+                                          ast.NodeList argumentsNode,
                                           CallStructure callStructure,
                                           _) {
     if (compiler.backend.isForeign(function)) {
-      return handleForeignCode(node, function, argumentList, callStructure);
+      return handleForeignCode(node, function, argumentsNode, callStructure);
     } else {
-      return irBuilder.buildStaticFunctionInvocation(function, callStructure,
-          translateStaticArguments(argumentList, function, callStructure),
+      List<ir.Primitive> arguments = <ir.Primitive>[];
+      callStructure = translateStaticArguments(argumentsNode, function,
+          callStructure, arguments);
+      return irBuilder.buildStaticFunctionInvocation(function,
+          callStructure,
+          arguments,
           sourceInformation:
               sourceInformationBuilder.buildCall(node, node.selector));
     }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
index 78b976f..12262e13 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
@@ -148,24 +148,18 @@
   }
 
   String visitInvokeConstructor(InvokeConstructor node) {
-    String className;
     // TODO(karlklose): for illegal nodes constructed for tests or unresolved
     // constructor calls in the DartBackend, we get an element with no enclosing
     // class.  Clean this up by introducing a name field to the node and
     // removing [ErroneousElement]s from the IR.
-    if (node.dartType != null) {
-      className = node.dartType.toString();
-    } else {
-      className = node.target.enclosingClass.name;
-    }
-    String callName;
-    if (node.target.name.isEmpty) {
-      callName = '${className}';
-    } else {
-      callName = '${className}.${node.target.name}';
+    String name = node.dartType != null
+        ? node.dartType.toString()
+        : node.target.enclosingClass.name;
+    if (!node.target.name.isEmpty) {
+      name = '${name}.${node.target.name}';
     }
     String args = formatArguments(node.selector.callStructure, node.arguments);
-    return '(InvokeConstructor $callName $args)';
+    return '(InvokeConstructor $name $args)';
   }
 
   String visitInvokeContinuation(InvokeContinuation node) {
diff --git a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
index 2329144..25fb1c9 100644
--- a/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_mask_system.dart
@@ -579,4 +579,19 @@
       return null;
     }
   }
+
+  /// Returns the type of the entry at a given index, `null` if unknown.
+  TypeMask indexWithConstant(TypeMask container, ConstantValue indexValue) {
+    if (container is DictionaryTypeMask) {
+      if (indexValue is StringConstantValue) {
+        String key = indexValue.primitiveValue.slowToString();
+        TypeMask result = container.typeMap[key];
+        if (result != null) return result;
+      }
+    }
+    if (container is ContainerTypeMask) {
+      return container.elementType;
+    }
+    return null;
+  }
 }
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 8a4daba..f716f05 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -591,6 +591,46 @@
     return constant(new StringConstantValue(new ast.DartString.literal(value)));
   }
 
+  AbstractConstantValue indexSpecial(AbstractConstantValue left,
+                                     AbstractConstantValue right) {
+    if (left.isNothing || right.isNothing) return nothing;
+    if (right.isConstant) {
+      ConstantValue index = right.constant;
+      if (left.isConstant) {
+        ConstantValue receiver = left.constant;
+        if (receiver is StringConstantValue) {
+          if (index is IntConstantValue) {
+            String stringValue = receiver.primitiveValue.slowToString();
+            int indexValue = index.primitiveValue;
+            if (0 <= indexValue && indexValue < stringValue.length) {
+              return stringConstant(stringValue[indexValue]);
+            } else {
+              return nothing;  // Will throw.
+            }
+          }
+        } else if (receiver is ListConstantValue) {
+          if (index is IntConstantValue) {
+            int indexValue = index.primitiveValue;
+            if (0 <= indexValue && indexValue < receiver.length) {
+              return constant(receiver.entries[indexValue]);
+            } else {
+              return nothing;  // Will throw.
+            }
+          }
+        } else if (receiver is MapConstantValue) {
+          ConstantValue result = receiver.lookup(index);
+          if (result != null) {
+            return constant(result);
+          }
+          return constant(new NullConstantValue());
+        }
+      }
+      TypeMask type = typeSystem.indexWithConstant(left.type, index);
+      if (type != null) return nonConstant(type);
+    }
+    return null;  // The caller will use return type from type inference.
+  }
+
   AbstractConstantValue stringify(AbstractConstantValue value) {
     if (value.isNothing) return nothing;
     if (value.isNonConst) return nonConstant(typeSystem.stringType);
@@ -2603,8 +2643,15 @@
     AbstractConstantValue receiver = getValue(node.receiver.definition);
     node.receiverIsNotNull = receiver.isDefinitelyNotNull;
     if (receiver.isNothing) {
-      setResult(node, lattice.nothing);
-      return;  // And come back later.
+      return setResult(node, lattice.nothing);
+    }
+
+    void finish(AbstractConstantValue result, {bool canReplace: false}) {
+      if (result == null) {
+        canReplace = false;
+        result = lattice.getInvokeReturnType(node.selector, node.mask);
+      }
+      setResult(node, result, canReplace: canReplace);
     }
 
     if (node.selector.isGetter) {
@@ -2613,37 +2660,34 @@
         AbstractConstantValue object = getValue(node.dartReceiver);
         if (typeSystem.isDefinitelyIndexable(object.type, allowNull: true)) {
           AbstractConstantValue length = lattice.lengthSpecial(object);
-          if (length != null) {
-            setResult(node, length, canReplace: !object.isNullable);
-          }
+          return finish(length, canReplace: !object.isNullable);
         }
       }
-      setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
-      return;
+      return finish(null);
     }
 
     if (node.selector.isCall) {
-      AbstractConstantValue result;
       if (node.selector == Selectors.codeUnitAt) {
         AbstractConstantValue object = getValue(node.dartReceiver);
         AbstractConstantValue right = getValue(node.dartArgument(0));
-        result = lattice.codeUnitAtSpecial(object, right);
+        AbstractConstantValue result = lattice.codeUnitAtSpecial(object, right);
+        return finish(result, canReplace: !object.isNullable);
       }
-      if (result == null) {
-        setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
-      } else {
-        setResult(node, result, canReplace: true);
-      }
-      return;
+      return finish(null);
+    }
+
+    if (node.selector == Selectors.index) {
+      AbstractConstantValue object = getValue(node.dartReceiver);
+      AbstractConstantValue right = getValue(node.dartArgument(0));
+      AbstractConstantValue result = lattice.indexSpecial(object, right);
+      return finish(result, canReplace: !object.isNullable);
     }
 
     if (!node.selector.isOperator) {
-      setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
-      return;
+      return finish(null);
     }
 
     // Calculate the resulting constant if possible.
-    AbstractConstantValue result;
     String opname = node.selector.name;
     if (node.arguments.length == 1) {
       AbstractConstantValue argument = getValue(node.dartReceiver);
@@ -2652,22 +2696,17 @@
         opname = "-";
       }
       UnaryOperator operator = UnaryOperator.parse(opname);
-      result = lattice.unaryOp(operator, argument);
+      AbstractConstantValue result = lattice.unaryOp(operator, argument);
+      return finish(result, canReplace: !argument.isNullable);
     } else if (node.arguments.length == 2) {
       // Binary operator.
       AbstractConstantValue left = getValue(node.dartReceiver);
       AbstractConstantValue right = getValue(node.dartArgument(0));
       BinaryOperator operator = BinaryOperator.parse(opname);
-      result = lattice.binaryOp(operator, left, right);
+      AbstractConstantValue result = lattice.binaryOp(operator, left, right);
+      return finish(result, canReplace: !left.isNullable);
     }
-
-    // Update value of the continuation parameter. Again, this is effectively
-    // a phi.
-    if (result == null) {
-      setResult(node, lattice.getInvokeReturnType(node.selector, node.mask));
-    } else {
-      setResult(node, result, canReplace: true);
-    }
+    return finish(null);
   }
 
   void visitApplyBuiltinOperator(ApplyBuiltinOperator node) {
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 662316b..0e2c63f 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -317,6 +317,7 @@
     new OptionHandler('--out=.+|-o.*', setOutput, multipleArguments: true),
     new OptionHandler(Flags.allowMockCompilation, passThrough),
     new OptionHandler(Flags.fastStartup, passThrough),
+    new OptionHandler(Flags.conditionalDirectives, passThrough),
     new OptionHandler('${Flags.minify}|-m', implyCompilation),
     new OptionHandler(Flags.preserveUris, passThrough),
     new OptionHandler('--force-strip=.*', setStrip),
diff --git a/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
new file mode 100644
index 0000000..0f4e624
--- /dev/null
+++ b/pkg/compiler/lib/src/diagnostics/dart2js_messages.dart
@@ -0,0 +1,3715 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// The messages in this file should meet the following guide lines:
+//
+// 1. The message should be a complete sentence starting with an uppercase
+// letter, and ending with a period.
+//
+// 2. Reserved words and embedded identifiers should be in single quotes, so
+// prefer double quotes for the complete message. For example, "The
+// class '#{className}' can't use 'super'." Notice that the word 'class' in the
+// preceding message is not quoted as it refers to the concept 'class', not the
+// reserved word. On the other hand, 'super' refers to the reserved word. Do
+// not quote 'null' and numeric literals.
+//
+// 3. Do not try to compose messages, as it can make translating them hard.
+//
+// 4. Try to keep the error messages short, but informative.
+//
+// 5. Use simple words and terminology, assume the reader of the message
+// doesn't have an advanced degree in math, and that English is not the
+// reader's native language. Do not assume any formal computer science
+// training. For example, do not use Latin abbreviations (prefer "that is" over
+// "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
+// only if" and "iff", that level of precision is unnecessary.
+//
+// 6. Prefer contractions when they are in common use, for example, prefer
+// "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
+// off-putting to people new to programming.
+//
+// 7. Use common terminology, preferably from the Dart Language
+// Specification. This increases the user's chance of finding a good
+// explanation on the web.
+//
+// 8. Do not try to be cute or funny. It is extremely frustrating to work on a
+// product that crashes with a "tongue-in-cheek" message, especially if you did
+// not want to use this product to begin with.
+//
+// 9. Do not lie, that is, do not write error messages containing phrases like
+// "can't happen".  If the user ever saw this message, it would be a
+// lie. Prefer messages like: "Internal error: This function should not be
+// called when 'x' is null.".
+//
+// 10. Prefer to not use imperative tone. That is, the message should not sound
+// accusing or like it is ordering the user around. The computer should
+// describe the problem, not criticize for violating the specification.
+//
+// Other things to keep in mind:
+//
+// An INFO message should always be preceded by a non-INFO message, and the
+// INFO messages are additional details about the preceding non-INFO
+// message. For example, consider duplicated elements. First report a WARNING
+// or ERROR about the duplicated element, and then report an INFO about the
+// location of the existing element.
+//
+// Generally, we want to provide messages that consists of three sentences:
+// 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
+// combine the first two in [template] and the last in [howToFix].
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
+const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n*   ';
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
+const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n   ';
+
+/// Padding used before and between import chains in the message for
+/// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
+const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n  ';
+
+const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
+
+final Map<String, Map> MESSAGES = {
+  /// Do not use this. It is here for legacy and debugging. It violates item
+  /// 4 of the guide lines for error messages in the beginning of the file.
+  'GENERIC': {'id': 'SOWPSL', 'template': "#{text}",},
+
+  'NOT_ASSIGNABLE': {
+    'id': 'VYNMAP',
+    'template': "'#{fromType}' is not assignable to '#{toType}'.",
+  },
+
+  'FORIN_NOT_ASSIGNABLE': {
+    'id': 'XQSRXO',
+    'template': "The element type '#{currentType}' of '#{expressionType}' "
+        "is not assignable to '#{elementType}'.",
+  },
+
+  'VOID_EXPRESSION': {
+    'id': 'QHEVSC',
+    'template': "Expression does not yield a value.",
+  },
+
+  'VOID_VARIABLE': {
+    'id': 'RFEURK',
+    'template': "Variable cannot be of type void.",
+  },
+
+  'RETURN_VALUE_IN_VOID': {
+    'id': 'FUNYDS',
+    'template': "Cannot return value from void function.",
+  },
+
+  'RETURN_NOTHING': {
+    'id': 'HPPODJ',
+    'template': "Value of type '#{returnType}' expected.",
+  },
+
+  'MISSING_ARGUMENT': {
+    'id': 'LHMCIK',
+    'template': "Missing argument of type '#{argumentType}'.",
+  },
+
+  'ADDITIONAL_ARGUMENT': {'id': 'GMITMA', 'template': "Additional argument.",},
+
+  'NAMED_ARGUMENT_NOT_FOUND': {
+    'id': 'UCEARQ',
+    'template': "No named argument '#{argumentName}' found on method.",
+  },
+
+  'MEMBER_NOT_FOUND': {
+    'id': 'MMQODC',
+    'template': "No member named '#{memberName}' in class '#{className}'.",
+  },
+
+  'AWAIT_MEMBER_NOT_FOUND': {
+    'id': 'XIDLIP',
+    'template': "No member named 'await' in class '#{className}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to '#{functionName}'?",
+    'examples': [
+      """
+class A {
+m() => await -3;
+}
+main() => new A().m();
+"""
+    ],
+  },
+
+  'AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE': {
+    'id': 'HBIYGN',
+    'template': "No member named 'await' in class '#{className}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to the enclosing function?",
+    'examples': [
+      """
+class A {
+m() => () => await -3;
+}
+main() => new A().m();
+"""
+    ],
+  },
+
+  'METHOD_NOT_FOUND': {
+    'id': 'QYYHBU',
+    'template': "No method named '#{memberName}' in class '#{className}'.",
+  },
+
+  'OPERATOR_NOT_FOUND': {
+    'id': 'SXGOYS',
+    'template': "No operator '#{memberName}' in class '#{className}'.",
+  },
+
+  'SETTER_NOT_FOUND': {
+    'id': 'ADFRVF',
+    'template': "No setter named '#{memberName}' in class '#{className}'.",
+  },
+
+  'SETTER_NOT_FOUND_IN_SUPER': {
+    'id': 'OCVRNJ',
+    'template': "No setter named '#{name}' in superclass of '#{className}'.",
+  },
+
+  'GETTER_NOT_FOUND': {
+    'id': 'PBNXAC',
+    'template': "No getter named '#{memberName}' in class '#{className}'.",
+  },
+
+  'NOT_CALLABLE': {
+    'id': 'SEMKJO',
+    'template': "'#{elementName}' is not callable.",
+  },
+
+  'MEMBER_NOT_STATIC': {
+    'id': 'QIOISX',
+    'template': "'#{className}.#{memberName}' is not static.",
+  },
+
+  'NO_INSTANCE_AVAILABLE': {
+    'id': 'FQPYLR',
+    'template': "'#{name}' is only available in instance methods.",
+  },
+
+  'NO_THIS_AVAILABLE': {
+    'id': 'LXPXKG',
+    'template': "'this' is only available in instance methods.",
+  },
+
+  'PRIVATE_ACCESS': {
+    'id': 'DIMHCR',
+    'template': "'#{name}' is declared private within library "
+        "'#{libraryName}'.",
+  },
+
+  'THIS_IS_THE_DECLARATION': {
+    'id': 'YIJWTO',
+    'template': "This is the declaration of '#{name}'.",
+  },
+
+  'THIS_IS_THE_METHOD': {
+    'id': 'PYXWLF',
+    'template': "This is the method declaration.",
+  },
+
+  'CANNOT_RESOLVE': {'id': 'SPVJYO', 'template': "Cannot resolve '#{name}'.",},
+
+  'CANNOT_RESOLVE_AWAIT': {
+    'id': 'YQYLRS',
+    'template': "Cannot resolve '#{name}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to '#{functionName}'?",
+    'examples': ["main() => await -3;", "foo() => await -3; main() => foo();"],
+  },
+
+  'CANNOT_RESOLVE_AWAIT_IN_CLOSURE': {
+    'id': 'SIXRAA',
+    'template': "Cannot resolve '#{name}'.",
+    'howToFix': "Did you mean to add the 'async' marker "
+        "to the enclosing function?",
+    'examples': ["main() { (() => await -3)(); }",],
+  },
+
+  'CANNOT_RESOLVE_IN_INITIALIZER': {
+    'id': 'VVEQFD',
+    'template':
+        "Cannot resolve '#{name}'. It would be implicitly looked up on this "
+        "instance, but instances are not available in initializers.",
+    'howToFix': "Try correcting the unresolved reference or move the "
+        "initialization to a constructor body.",
+    'examples': [
+      """
+class A {
+var test = unresolvedName;
+}
+main() => new A();
+"""
+    ],
+  },
+
+  'CANNOT_RESOLVE_CONSTRUCTOR': {
+    'id': 'QRPATN',
+    'template': "Cannot resolve constructor '#{constructorName}'.",
+  },
+
+  'CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT': {
+    'id': 'IFKCHF',
+    'template': "cannot resolve constructor '#{constructorName}' "
+        "for implicit super call.",
+    'howToFix': "Try explicitly invoking a constructor of the super class",
+    'examples': [
+      """
+class A {
+A.foo() {}
+}
+class B extends A {
+B();
+}
+main() => new B();
+"""
+    ],
+  },
+
+  'INVALID_UNNAMED_CONSTRUCTOR_NAME': {
+    'id': 'VPJLVI',
+    'template': "Unnamed constructor name must be '#{name}'.",
+  },
+
+  'INVALID_CONSTRUCTOR_NAME': {
+    'id': 'LMDCAS',
+    'template': "Constructor name must start with '#{name}'.",
+  },
+
+  'CANNOT_RESOLVE_TYPE': {
+    'id': 'PQIAPG',
+    'template': "Cannot resolve type '#{typeName}'.",
+  },
+
+  'DUPLICATE_DEFINITION': {
+    'id': 'LVTYNW',
+    'template': "Duplicate definition of '#{name}'.",
+    'howToFix': "Try to rename or remove this definition.",
+    'examples': [
+      """
+class C {
+void f() {}
+int get f => 1;
+}
+
+main() {
+new C();
+}
+
+"""
+    ],
+  },
+
+  'EXISTING_DEFINITION': {
+    'id': 'DAUYKK',
+    'template': "Existing definition of '#{name}'.",
+  },
+
+  'DUPLICATE_IMPORT': {
+    'id': 'KYJFJN',
+    'template': "Duplicate import of '#{name}'.",
+  },
+
+  'HIDDEN_IMPORT': {
+    'id': 'ACRDPR',
+    'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+        "from library '#{hidingUri}'.",
+    'howToFix': "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
+    'examples': [
+      {
+        'main.dart': """
+import 'dart:async'; // This imports a class Future.
+import 'future.dart';
+
+void main() => new Future();""",
+        'future.dart': """
+library future;
+
+class Future {}"""
+      },
+      {
+        'main.dart': """
+import 'future.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+        'future.dart': """
+library future;
+
+class Future {}"""
+      },
+      {
+        'main.dart': """
+import 'export.dart';
+import 'dart:async'; // This imports a class Future.
+
+void main() => new Future();""",
+        'future.dart': """
+library future;
+
+class Future {}""",
+        'export.dart': """
+library export;
+
+export 'future.dart';"""
+      },
+      {
+        'main.dart': """
+import 'future.dart' as prefix;
+import 'dart:async' as prefix; // This imports a class Future.
+
+void main() => new prefix.Future();""",
+        'future.dart': """
+library future;
+
+class Future {}"""
+      }
+    ],
+  },
+
+  'HIDDEN_IMPLICIT_IMPORT': {
+    'id': 'WDNFSI',
+    'template': "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
+        "from library '#{hidingUri}'.",
+    'howToFix': "Try adding an explicit "
+        "'import \"#{hiddenUri}\" hide #{name}'.",
+    'examples': [
+      {
+        'main.dart': """
+// This hides the implicit import of class Type from dart:core.
+import 'type.dart';
+
+void main() => new Type();""",
+        'type.dart': """
+library type;
+
+class Type {}"""
+      },
+      {
+        'conflictsWithDart.dart': """
+library conflictsWithDart;
+
+class Duration {
+static var x = 100;
+}
+""",
+        'conflictsWithDartAsWell.dart': """
+library conflictsWithDartAsWell;
+
+class Duration {
+static var x = 100;
+}
+""",
+        'main.dart': r"""
+library testDartConflicts;
+
+import 'conflictsWithDart.dart';
+import 'conflictsWithDartAsWell.dart';
+
+main() {
+print("Hail Caesar ${Duration.x}");
+}
+"""
+      }
+    ],
+  },
+
+  'DUPLICATE_EXPORT': {
+    'id': 'XGNOCL',
+    'template': "Duplicate export of '#{name}'.",
+    'howToFix': "Try adding 'hide #{name}' to one of the exports.",
+    'examples': [
+      {
+        'main.dart': """
+export 'decl1.dart';
+export 'decl2.dart';
+
+main() {}""",
+        'decl1.dart': "class Class {}",
+        'decl2.dart': "class Class {}"
+      }
+    ],
+  },
+
+  'DUPLICATE_EXPORT_CONT': {
+    'id': 'BDROED',
+    'template': "This is another export of '#{name}'.",
+  },
+
+  'DUPLICATE_EXPORT_DECL': {
+    'id': 'GFFLMA',
+    'template':
+        "The exported '#{name}' from export #{uriString} is defined here.",
+  },
+
+  'EMPTY_HIDE': {
+    'id': 'ODFAOC',
+    'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
+    'howToFix': "Try removing '#{name}' the 'hide' clause.",
+    'examples': [
+      {
+        'main.dart': """
+import 'dart:core' hide Foo;
+
+main() {}"""
+      },
+      {
+        'main.dart': """
+export 'dart:core' hide Foo;
+
+main() {}"""
+      },
+    ],
+  },
+
+  'EMPTY_SHOW': {
+    'id': 'EXONIK',
+    'template': "Library '#{uri}' doesn't export a '#{name}' declaration.",
+    'howToFix': "Try removing '#{name}' from the 'show' clause.",
+    'examples': [
+      {
+        'main.dart': """
+import 'dart:core' show Foo;
+
+main() {}"""
+      },
+      {
+        'main.dart': """
+export 'dart:core' show Foo;
+
+main() {}"""
+      },
+    ],
+  },
+
+  'NOT_A_TYPE': {'id': 'CTTAXD', 'template': "'#{node}' is not a type.",},
+
+  'NOT_A_PREFIX': {'id': 'LKEUMI', 'template': "'#{node}' is not a prefix.",},
+
+  'PREFIX_AS_EXPRESSION': {
+    'id': 'CYIMBJ',
+    'template': "Library prefix '#{prefix}' is not a valid expression.",
+  },
+
+  'CANNOT_FIND_CONSTRUCTOR': {
+    'id': 'DROVNH',
+    'template': "Cannot find constructor '#{constructorName}' in class "
+        "'#{className}'.",
+  },
+
+  'CANNOT_FIND_UNNAMED_CONSTRUCTOR': {
+    'id': 'GDCTGB',
+    'template': "Cannot find unnamed constructor in class "
+        "'#{className}'.",
+  },
+
+  'CYCLIC_CLASS_HIERARCHY': {
+    'id': 'HKFYOA',
+    'template': "'#{className}' creates a cycle in the class hierarchy.",
+  },
+
+  'CYCLIC_REDIRECTING_FACTORY': {
+    'id': 'QGETJC',
+    'template': "Redirecting factory leads to a cyclic redirection.",
+  },
+
+  'INVALID_RECEIVER_IN_INITIALIZER': {
+    'id': 'SYUTHA',
+    'template': "Field initializer expected.",
+  },
+
+  'NO_SUPER_IN_STATIC': {
+    'id': 'HSCESG',
+    'template': "'super' is only available in instance methods.",
+  },
+
+  'DUPLICATE_INITIALIZER': {
+    'id': 'GKVFEP',
+    'template': "Field '#{fieldName}' is initialized more than once.",
+  },
+
+  'ALREADY_INITIALIZED': {
+    'id': 'NCRMVD',
+    'template': "'#{fieldName}' was already initialized here.",
+  },
+
+  'INIT_STATIC_FIELD': {
+    'id': 'DBSRHA',
+    'template': "Cannot initialize static field '#{fieldName}'.",
+  },
+
+  'NOT_A_FIELD': {
+    'id': 'FYEPLC',
+    'template': "'#{fieldName}' is not a field.",
+  },
+
+  'CONSTRUCTOR_CALL_EXPECTED': {
+    'id': 'GEJCDX',
+    'template': "only call to 'this' or 'super' constructor allowed.",
+  },
+
+  'INVALID_FOR_IN': {
+    'id': 'AUQJBG',
+    'template': "Invalid for-in variable declaration.",
+  },
+
+  'INVALID_INITIALIZER': {'id': 'JKUKSA', 'template': "Invalid initializer.",},
+
+  'FUNCTION_WITH_INITIALIZER': {
+    'id': 'BNRDDK',
+    'template': "Only constructors can have initializers.",
+  },
+
+  'REDIRECTING_CONSTRUCTOR_CYCLE': {
+    'id': 'CQTMEP',
+    'template': "Cyclic constructor redirection.",
+  },
+
+  'REDIRECTING_CONSTRUCTOR_HAS_BODY': {
+    'id': 'WXJQNE',
+    'template': "Redirecting constructor can't have a body.",
+  },
+
+  'CONST_CONSTRUCTOR_HAS_BODY': {
+    'id': 'GNEFQG',
+    'template': "Const constructor or factory can't have a body.",
+    'howToFix': "Remove the 'const' keyword or the body",
+    'examples': [
+      """
+class C {
+const C() {}
+}
+
+main() => new C();"""
+    ],
+  },
+
+  'REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER': {
+    'id': 'NUIDSF',
+    'template': "Redirecting constructor cannot have other initializers.",
+  },
+
+  'SUPER_INITIALIZER_IN_OBJECT': {
+    'id': 'DXYGND',
+    'template': "'Object' cannot have a super initializer.",
+  },
+
+  'DUPLICATE_SUPER_INITIALIZER': {
+    'id': 'FFKOWP',
+    'template': "Cannot have more than one super initializer.",
+  },
+
+  'SUPER_CALL_TO_FACTORY': {
+    'id': 'YTOWGV',
+    'template': "The target of the superinitializer must be a generative "
+        "constructor.",
+    'howToFix': "Try calling another constructor on the superclass.",
+    'examples': [
+      """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {}
+main() => new Class();
+""",
+      """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {
+Class();
+}
+main() => new Class();
+""",
+      """
+class Super {
+factory Super() => null;
+}
+class Class extends Super {
+Class() : super();
+}
+main() => new Class();
+""",
+      """
+class Super {
+factory Super.foo() => null;
+}
+class Class extends Super {
+Class() : super.foo();
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'THIS_CALL_TO_FACTORY': {
+    'id': 'JLATDB',
+    'template': "The target of the redirection clause must be a generative "
+        "constructor",
+    'howToFix': "Try redirecting to another constructor.",
+    'examples': [
+      """
+class Class {
+factory Class() => null;
+Class.foo() : this();
+}
+main() => new Class.foo();
+""",
+      """
+class Class {
+factory Class.foo() => null;
+Class() : this.foo();
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'INVALID_CONSTRUCTOR_ARGUMENTS': {
+    'id': 'WVPLKL',
+    'template': "Arguments do not match the expected parameters of constructor "
+        "'#{constructorName}'.",
+  },
+
+  'NO_MATCHING_CONSTRUCTOR': {
+    'id': 'OJQQLE',
+    'template':
+        "'super' call arguments and constructor parameters do not match.",
+  },
+
+  'NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT': {
+    'id': 'WHCVID',
+    'template': "Implicit 'super' call arguments and constructor parameters "
+        "do not match.",
+  },
+
+  'CONST_CALLS_NON_CONST': {
+    'id': 'CQFHXC',
+    'template': "'const' constructor cannot call a non-const constructor.",
+  },
+
+  'CONST_CALLS_NON_CONST_FOR_IMPLICIT': {
+    'id': 'SFCEXS',
+    'template': "'const' constructor cannot call a non-const constructor. "
+        "This constructor has an implicit call to a "
+        "super non-const constructor.",
+    'howToFix': "Try making the super constructor const.",
+    'examples': [
+      """
+class C {
+C(); // missing const
+}
+class D extends C {
+final d;
+const D(this.d);
+}
+main() => new D(0);"""
+    ],
+  },
+
+  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS': {
+    'id': 'XBHUDL',
+    'template': "Can't declare constructor 'const' on class #{className} "
+        "because the class contains non-final instance fields.",
+    'howToFix': "Try making all fields final.",
+    'examples': [
+      """
+class C {
+// 'a' must be declared final to allow for the const constructor.
+var a;
+const C(this.a);
+}
+
+main() => new C(0);"""
+    ],
+  },
+
+  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD': {
+    'id': 'YYAHVD',
+    'template': "This non-final field prevents using const constructors.",
+  },
+
+  'CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR': {
+    'id': 'FROWJB',
+    'template': "This const constructor is not allowed due to "
+        "non-final fields.",
+  },
+
+  'INITIALIZING_FORMAL_NOT_ALLOWED': {
+    'id': 'YIPXYP',
+    'template': "Initializing formal parameter only allowed in generative "
+        "constructor.",
+  },
+
+  'INVALID_PARAMETER': {
+    'id': 'OWWLIX',
+    'template': "Cannot resolve parameter.",
+  },
+
+  'NOT_INSTANCE_FIELD': {
+    'id': 'VSPKMU',
+    'template': "'#{fieldName}' is not an instance field.",
+  },
+
+  'THIS_PROPERTY': {'id': 'MWFIGH', 'template': "Expected an identifier.",},
+
+  'NO_CATCH_NOR_FINALLY': {
+    'id': 'OPJXPP',
+    'template': "Expected 'catch' or 'finally'.",
+  },
+
+  'EMPTY_CATCH_DECLARATION': {
+    'id': 'UNHCPY',
+    'template': "Expected an identifier in catch declaration.",
+  },
+
+  'EXTRA_CATCH_DECLARATION': {
+    'id': 'YGGRAK',
+    'template': "Extra parameter in catch declaration.",
+  },
+
+  'PARAMETER_WITH_TYPE_IN_CATCH': {
+    'id': 'EXQVDU',
+    'template': "Cannot use type annotations in catch.",
+  },
+
+  'PARAMETER_WITH_MODIFIER_IN_CATCH': {
+    'id': 'BQLKRF',
+    'template': "Cannot use modifiers in catch.",
+  },
+
+  'OPTIONAL_PARAMETER_IN_CATCH': {
+    'id': 'DAICPP',
+    'template': "Cannot use optional parameters in catch.",
+  },
+
+  'THROW_WITHOUT_EXPRESSION': {
+    'id': 'YHACYV',
+    'template': "Cannot use re-throw outside of catch block "
+        "(expression expected after 'throw').",
+  },
+
+  'UNBOUND_LABEL': {
+    'id': 'GLDXHY',
+    'template': "Cannot resolve label '#{labelName}'.",
+  },
+
+  'NO_BREAK_TARGET': {
+    'id': 'VBXXBE',
+    'template': "'break' statement not inside switch or loop.",
+  },
+
+  'NO_CONTINUE_TARGET': {
+    'id': 'JTTHHM',
+    'template': "'continue' statement not inside loop.",
+  },
+
+  'EXISTING_LABEL': {
+    'id': 'AHCSXF',
+    'template': "Original declaration of duplicate label '#{labelName}'.",
+  },
+
+  'DUPLICATE_LABEL': {
+    'id': 'HPULLI',
+    'template': "Duplicate declaration of label '#{labelName}'.",
+  },
+
+  'UNUSED_LABEL': {'id': 'KFREJO', 'template': "Unused label '#{labelName}'.",},
+
+  'INVALID_CONTINUE': {
+    'id': 'DSKTPX',
+    'template': "Target of continue is not a loop or switch case.",
+  },
+
+  'INVALID_BREAK': {
+    'id': 'MFCCWX',
+    'template': "Target of break is not a statement.",
+  },
+
+  'DUPLICATE_TYPE_VARIABLE_NAME': {
+    'id': 'BAYCCM',
+    'template': "Type variable '#{typeVariableName}' already declared.",
+  },
+
+  'TYPE_VARIABLE_WITHIN_STATIC_MEMBER': {
+    'id': 'XQLXRL',
+    'template': "Cannot refer to type variable '#{typeVariableName}' "
+        "within a static member.",
+  },
+
+  'TYPE_VARIABLE_IN_CONSTANT': {
+    'id': 'ANDEVG',
+    'template': "Constant expressions can't refer to type variables.",
+    'howToFix': "Try removing the type variable or replacing it with a "
+        "concrete type.",
+    'examples': [
+      """
+class C<T> {
+const C();
+
+m(T t) => const C<T>();
+}
+
+void main() => new C().m(null);
+"""
+    ],
+  },
+
+  'INVALID_TYPE_VARIABLE_BOUND': {
+    'id': 'WQAEDK',
+    'template': "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
+        "type variable '#{typeVariable}' of type '#{thisType}'.",
+    'howToFix': "Try to change or remove the type argument.",
+    'examples': [
+      """
+class C<T extends num> {}
+
+// 'String' is not a valid instantiation of T with bound num.'.
+main() => new C<String>();
+"""
+    ],
+  },
+
+  'INVALID_USE_OF_SUPER': {
+    'id': 'JKYYSN',
+    'template': "'super' not allowed here.",
+  },
+
+  'INVALID_CASE_DEFAULT': {
+    'id': 'ABSPBM',
+    'template': "'default' only allowed on last case of a switch.",
+  },
+
+  'SWITCH_CASE_TYPES_NOT_EQUAL': {
+    'id': 'UFQPBC',
+    'template': "'case' expressions do not all have type '#{type}'.",
+  },
+
+  'SWITCH_CASE_TYPES_NOT_EQUAL_CASE': {
+    'id': 'RDMVAC',
+    'template': "'case' expression of type '#{type}'.",
+  },
+
+  'SWITCH_CASE_FORBIDDEN': {
+    'id': 'UHSCSU',
+    'template': "'case' expression may not be of type '#{type}'.",
+  },
+
+  'SWITCH_CASE_VALUE_OVERRIDES_EQUALS': {
+    'id': 'NRTWXL',
+    'template': "'case' expression type '#{type}' overrides 'operator =='.",
+  },
+
+  'INVALID_ARGUMENT_AFTER_NAMED': {
+    'id': 'WAJURC',
+    'template': "Unnamed argument after named argument.",
+  },
+
+  'NOT_A_COMPILE_TIME_CONSTANT': {
+    'id': 'SBCHWL',
+    'template': "Not a compile-time constant.",
+  },
+
+  'DEFERRED_COMPILE_TIME_CONSTANT': {
+    'id': 'FHXTCK',
+    'template': "A deferred value cannot be used as a compile-time constant.",
+  },
+
+  'DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION': {
+    'id': 'TSBXLG',
+    'template': "A deferred class cannot be used to create a "
+        "compile-time constant.",
+  },
+
+  'CYCLIC_COMPILE_TIME_CONSTANTS': {
+    'id': 'JJWJYE',
+    'template': "Cycle in the compile-time constant computation.",
+  },
+
+  'CONSTRUCTOR_IS_NOT_CONST': {
+    'id': 'DOJCUX',
+    'template': "Constructor is not a 'const' constructor.",
+  },
+
+  'CONST_MAP_KEY_OVERRIDES_EQUALS': {
+    'id': 'VJNWEL',
+    'template': "Const-map key type '#{type}' overrides 'operator =='.",
+  },
+
+  'NO_SUCH_LIBRARY_MEMBER': {
+    'id': 'IOXVBA',
+    'template': "'#{libraryName}' has no member named '#{memberName}'.",
+  },
+
+  'CANNOT_INSTANTIATE_TYPEDEF': {
+    'id': 'KOYNMU',
+    'template': "Cannot instantiate typedef '#{typedefName}'.",
+  },
+
+  'REQUIRED_PARAMETER_WITH_DEFAULT': {
+    'id': 'CJWECI',
+    'template': "Non-optional parameters can't have a default value.",
+    'howToFix':
+        "Try removing the default value or making the parameter optional.",
+    'examples': [
+      """
+main() {
+foo(a: 1) => print(a);
+foo(2);
+}""",
+      """
+main() {
+foo(a = 1) => print(a);
+foo(2);
+}"""
+    ],
+  },
+
+  'NAMED_PARAMETER_WITH_EQUALS': {
+    'id': 'RPJDXD',
+    'template': "Named optional parameters can't use '=' to specify a default "
+        "value.",
+    'howToFix': "Try replacing '=' with ':'.",
+    'examples': [
+      """
+main() {
+foo({a = 1}) => print(a);
+foo(a: 2);
+}"""
+    ],
+  },
+
+  'POSITIONAL_PARAMETER_WITH_EQUALS': {
+    'id': 'JMSSDX',
+    'template': "Positional optional parameters can't use ':' to specify a "
+        "default value.",
+    'howToFix': "Try replacing ':' with '='.",
+    'examples': [
+      """
+main() {
+foo([a: 1]) => print(a);
+foo(2);
+}"""
+    ],
+  },
+
+  'TYPEDEF_FORMAL_WITH_DEFAULT': {
+    'id': 'NABHHS',
+    'template': "A parameter of a typedef can't specify a default value.",
+    'howToFix': "Try removing the default value.",
+    'examples': [
+      """
+typedef void F([int arg = 0]);
+
+main() {
+F f;
+}""",
+      """
+typedef void F({int arg: 0});
+
+main() {
+F f;
+}"""
+    ],
+  },
+
+  'FUNCTION_TYPE_FORMAL_WITH_DEFAULT': {
+    'id': 'APKYLU',
+    'template': "A function type parameter can't specify a default value.",
+    'howToFix': "Try removing the default value.",
+    'examples': [
+      """
+foo(f(int i, [a = 1])) {}
+
+main() {
+foo(1, 2);
+}""",
+      """
+foo(f(int i, {a: 1})) {}
+
+main() {
+foo(1, a: 2);
+}"""
+    ],
+  },
+
+  'REDIRECTING_FACTORY_WITH_DEFAULT': {
+    'id': 'AWSSEY',
+    'template':
+        "A parameter of a redirecting factory constructor can't specify a "
+        "default value.",
+    'howToFix': "Try removing the default value.",
+    'examples': [
+      """
+class A {
+A([a]);
+factory A.foo([a = 1]) = A;
+}
+
+main() {
+new A.foo(1);
+}""",
+      """
+class A {
+A({a});
+factory A.foo({a: 1}) = A;
+}
+
+main() {
+new A.foo(a: 1);
+}"""
+    ],
+  },
+
+  'FORMAL_DECLARED_CONST': {
+    'id': 'AVPRDK',
+    'template': "A formal parameter can't be declared const.",
+    'howToFix': "Try removing 'const'.",
+    'examples': [
+      """
+foo(const x) {}
+main() => foo(42);
+""",
+      """
+foo({const x}) {}
+main() => foo(42);
+""",
+      """
+foo([const x]) {}
+main() => foo(42);
+"""
+    ],
+  },
+
+  'FORMAL_DECLARED_STATIC': {
+    'id': 'PJKDMX',
+    'template': "A formal parameter can't be declared static.",
+    'howToFix': "Try removing 'static'.",
+    'examples': [
+      """
+foo(static x) {}
+main() => foo(42);
+""",
+      """
+foo({static x}) {}
+main() => foo(42);
+""",
+      """
+foo([static x]) {}
+main() => foo(42);
+"""
+    ],
+  },
+
+  'FINAL_FUNCTION_TYPE_PARAMETER': {
+    'id': 'JIOPIQ',
+    'template': "A function type parameter can't be declared final.",
+    'howToFix': "Try removing 'final'.",
+    'examples': [
+      """
+foo(final int x(int a)) {}
+main() => foo((y) => 42);
+""",
+      """
+foo({final int x(int a)}) {}
+main() => foo((y) => 42);
+""",
+      """
+foo([final int x(int a)]) {}
+main() => foo((y) => 42);
+"""
+    ],
+  },
+
+  'VAR_FUNCTION_TYPE_PARAMETER': {
+    'id': 'FOQOHK',
+    'template': "A function type parameter can't be declared with 'var'.",
+    'howToFix': "Try removing 'var'.",
+    'examples': [
+      """
+foo(var int x(int a)) {}
+main() => foo((y) => 42);
+""",
+      """
+foo({var int x(int a)}) {}
+main() => foo((y) => 42);
+""",
+      """
+foo([var int x(int a)]) {}
+main() => foo((y) => 42);
+"""
+    ],
+  },
+
+  'CANNOT_INSTANTIATE_TYPE_VARIABLE': {
+    'id': 'JAYHCH',
+    'template': "Cannot instantiate type variable '#{typeVariableName}'.",
+  },
+
+  'CYCLIC_TYPE_VARIABLE': {
+    'id': 'RQMPSO',
+    'template': "Type variable '#{typeVariableName}' is a supertype of itself.",
+  },
+
+  'CYCLIC_TYPEDEF': {
+    'id': 'VFERCQ',
+    'template': "A typedef can't refer to itself.",
+    'howToFix': "Try removing all references to '#{typedefName}' "
+        "in the definition of '#{typedefName}'.",
+    'examples': [
+      """
+typedef F F(); // The return type 'F' is a self-reference.
+main() { F f = null; }"""
+    ],
+  },
+
+  'CYCLIC_TYPEDEF_ONE': {
+    'id': 'ASWLWR',
+    'template': "A typedef can't refer to itself through another typedef.",
+    'howToFix': "Try removing all references to "
+        "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
+    'examples': [
+      """
+typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
+typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
+main() { F f = null; }""",
+      """
+typedef G F(); // The return type 'G' creates a self-reference.
+typedef H G(); // The return type 'H' creates a self-reference.
+typedef H(F f); // The argument type 'F' creates a self-reference.
+main() { F f = null; }"""
+    ],
+  },
+
+  'CLASS_NAME_EXPECTED': {'id': 'DPKNHY', 'template': "Class name expected.",},
+
+  'CANNOT_EXTEND': {
+    'id': 'GCIQXD',
+    'template': "'#{type}' cannot be extended.",
+  },
+
+  'CANNOT_IMPLEMENT': {
+    'id': 'IBOQKV',
+    'template': "'#{type}' cannot be implemented.",
+  },
+
+  // TODO(johnnwinther): Split messages into reasons for malformedness.
+  'CANNOT_EXTEND_MALFORMED': {
+    'id': 'YPFJBD',
+    'template': "Class '#{className}' can't extend the type '#{malformedType}' "
+        "because it is malformed.",
+    'howToFix': "Try correcting the malformed type annotation or removing the "
+        "'extends' clause.",
+    'examples': [
+      """
+class A extends Malformed {}
+main() => new A();"""
+    ],
+  },
+
+  'CANNOT_IMPLEMENT_MALFORMED': {
+    'id': 'XJUIAQ',
+    'template':
+        "Class '#{className}' can't implement the type '#{malformedType}' "
+        "because it is malformed.",
+    'howToFix': "Try correcting the malformed type annotation or removing the "
+        "type from the 'implements' clause.",
+    'examples': [
+      """
+class A implements Malformed {}
+main() => new A();"""
+    ],
+  },
+
+  'CANNOT_MIXIN_MALFORMED': {
+    'id': 'SSMNXN',
+    'template': "Class '#{className}' can't mixin the type '#{malformedType}' "
+        "because it is malformed.",
+    'howToFix': "Try correcting the malformed type annotation or removing the "
+        "type from the 'with' clause.",
+    'examples': [
+      """
+class A extends Object with Malformed {}
+main() => new A();"""
+    ],
+  },
+
+  'CANNOT_MIXIN': {
+    'id': 'KLSXDQ',
+    'template': "The type '#{type}' can't be mixed in.",
+    'howToFix': "Try removing '#{type}' from the 'with' clause.",
+    'examples': [
+      """
+class C extends Object with String {}
+
+main() => new C();
+""",
+      """
+typedef C = Object with String;
+
+main() => new C();
+"""
+    ],
+  },
+
+  'CANNOT_EXTEND_ENUM': {
+    'id': 'JEPRST',
+    'template':
+        "Class '#{className}' can't extend the type '#{enumType}' because "
+        "it is declared by an enum.",
+    'howToFix': "Try making '#{enumType}' a normal class or removing the "
+        "'extends' clause.",
+    'examples': [
+      """
+enum Enum { A }
+class B extends Enum {}
+main() => new B();"""
+    ],
+  },
+
+  'CANNOT_IMPLEMENT_ENUM': {
+    'id': 'JMJMSH',
+    'template': "Class '#{className}' can't implement the type '#{enumType}' "
+        "because it is declared by an enum.",
+    'howToFix': "Try making '#{enumType}' a normal class or removing the "
+        "type from the 'implements' clause.",
+    'examples': [
+      """
+enum Enum { A }
+class B implements Enum {}
+main() => new B();"""
+    ],
+  },
+
+  'CANNOT_MIXIN_ENUM': {
+    'id': 'YSYDIM',
+    'template':
+        "Class '#{className}' can't mixin the type '#{enumType}' because it "
+        "is declared by an enum.",
+    'howToFix': "Try making '#{enumType}' a normal class or removing the "
+        "type from the 'with' clause.",
+    'examples': [
+      """
+enum Enum { A }
+class B extends Object with Enum {}
+main() => new B();"""
+    ],
+  },
+
+  'CANNOT_INSTANTIATE_ENUM': {
+    'id': 'CQYIFU',
+    'template': "Enum type '#{enumName}' cannot be instantiated.",
+    'howToFix': "Try making '#{enumType}' a normal class or use an enum "
+        "constant.",
+    'examples': [
+      """
+enum Enum { A }
+main() => new Enum(0);""",
+      """
+enum Enum { A }
+main() => const Enum(0);"""
+    ],
+  },
+
+  'EMPTY_ENUM_DECLARATION': {
+    'id': 'JFPDOH',
+    'template': "Enum '#{enumName}' must contain at least one value.",
+    'howToFix': "Try adding an enum constant or making #{enumName} a "
+        "normal class.",
+    'examples': [
+      """
+enum Enum {}
+main() { Enum e; }"""
+    ],
+  },
+
+  'MISSING_ENUM_CASES': {
+    'id': 'HHEOIW',
+    'template': "Missing enum constants in switch statement: #{enumValues}.",
+    'howToFix': "Try adding the missing constants or a default case.",
+    'examples': [
+      """
+enum Enum { A, B }
+main() {
+switch (Enum.A) {
+case Enum.B: break;
+}
+}""",
+      """
+enum Enum { A, B, C }
+main() {
+switch (Enum.A) {
+case Enum.B: break;
+}
+}"""
+    ],
+  },
+
+  'DUPLICATE_EXTENDS_IMPLEMENTS': {
+    'id': 'BKRKEO',
+    'template': "'#{type}' can not be both extended and implemented.",
+  },
+
+  'DUPLICATE_IMPLEMENTS': {
+    'id': 'IWJFTU',
+    'template': "'#{type}' must not occur more than once "
+        "in the implements clause.",
+  },
+
+  'MULTI_INHERITANCE': {
+    'id': 'NWXGOI',
+    'template':
+        "Dart2js does not currently support inheritance of the same class "
+        "with different type arguments: Both #{firstType} and #{secondType} "
+        "are supertypes of #{thisType}.",
+  },
+
+  'ILLEGAL_SUPER_SEND': {
+    'id': 'LDRGIU',
+    'template': "'#{name}' cannot be called on super.",
+  },
+
+  'NO_SUCH_SUPER_MEMBER': {
+    'id': 'HIJJVG',
+    'template':
+        "Cannot resolve '#{memberName}' in a superclass of '#{className}'.",
+  },
+
+  'ADDITIONAL_TYPE_ARGUMENT': {
+    'id': 'HWYHWH',
+    'template': "Additional type argument.",
+  },
+
+  'MISSING_TYPE_ARGUMENT': {
+    'id': 'KYTQWA',
+    'template': "Missing type argument.",
+  },
+
+  // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
+  // MISSING_TYPE_ARGUMENT instead.
+  'TYPE_ARGUMENT_COUNT_MISMATCH': {
+    'id': 'ECXGRM',
+    'template': "Incorrect number of type arguments on '#{type}'.",
+  },
+
+  'GETTER_MISMATCH': {
+    'id': 'MNODFW',
+    'template': "Setter disagrees on: '#{modifiers}'.",
+  },
+
+  'SETTER_MISMATCH': {
+    'id': 'FMNHPL',
+    'template': "Getter disagrees on: '#{modifiers}'.",
+  },
+
+  'ILLEGAL_SETTER_FORMALS': {
+    'id': 'COTPVN',
+    'template': "A setter must have exactly one argument.",
+  },
+
+  'NO_STATIC_OVERRIDE': {
+    'id': 'EHINXB',
+    'template':
+        "Static member cannot override instance member '#{memberName}' of "
+        "'#{className}'.",
+  },
+
+  'NO_STATIC_OVERRIDE_CONT': {
+    'id': 'TEVJMA',
+    'template': "This is the instance member that cannot be overridden "
+        "by a static member.",
+  },
+
+  'INSTANCE_STATIC_SAME_NAME': {
+    'id': 'LTBFBO',
+    'template': "Instance member '#{memberName}' and static member of "
+        "superclass '#{className}' have the same name.",
+  },
+
+  'INSTANCE_STATIC_SAME_NAME_CONT': {
+    'id': 'CHSUCQ',
+    'template': "This is the static member with the same name.",
+  },
+
+  'INVALID_OVERRIDE_METHOD': {
+    'id': 'NINKPI',
+    'template': "The type '#{declaredType}' of method '#{name}' declared in "
+        "'#{class}' is not a subtype of the overridden method type "
+        "'#{inheritedType}' inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_METHOD': {
+    'id': 'BQHUPY',
+    'template': "This is the overridden method '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'INVALID_OVERRIDE_GETTER': {
+    'id': 'KLMPWO',
+    'template': "The type '#{declaredType}' of getter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden getter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_GETTER': {
+    'id': 'ASSKCT',
+    'template': "This is the overridden getter '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'INVALID_OVERRIDE_GETTER_WITH_FIELD': {
+    'id': 'TCCGXU',
+    'template': "The type '#{declaredType}' of field '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden getter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_FIELD_WITH_GETTER': {
+    'id': 'UMMEXO',
+    'template': "The type '#{declaredType}' of getter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden field inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_SETTER': {
+    'id': 'BWRGEC',
+    'template': "The type '#{declaredType}' of setter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden setter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_SETTER': {
+    'id': 'XQUOLL',
+    'template': "This is the overridden setter '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'INVALID_OVERRIDE_SETTER_WITH_FIELD': {
+    'id': 'GKGOFA',
+    'template': "The type '#{declaredType}' of field '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden setter inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_FIELD_WITH_SETTER': {
+    'id': 'OOXKHQ',
+    'template': "The type '#{declaredType}' of setter '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden field inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDE_FIELD': {
+    'id': 'LDPKOL',
+    'template': "The type '#{declaredType}' of field '#{name}' declared in "
+        "'#{class}' is not assignable to the type '#{inheritedType}' of the "
+        "overridden field inherited from '#{inheritedClass}'.",
+  },
+
+  'INVALID_OVERRIDDEN_FIELD': {
+    'id': 'UNQFWX',
+    'template': "This is the overridden field '#{name}' declared in class "
+        "'#{class}'.",
+  },
+
+  'CANNOT_OVERRIDE_FIELD_WITH_METHOD': {
+    'id': 'SYKCSK',
+    'template': "Method '#{name}' in '#{class}' can't override field from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT': {
+    'id': 'HYHQSO',
+    'template': "This is the field that cannot be overridden by a method.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_FIELD': {
+    'id': 'UROMAS',
+    'template': "Field '#{name}' in '#{class}' can't override method from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT': {
+    'id': 'NSORYS',
+    'template': "This is the method that cannot be overridden by a field.",
+  },
+
+  'CANNOT_OVERRIDE_GETTER_WITH_METHOD': {
+    'id': 'MMFIOH',
+    'template': "Method '#{name}' in '#{class}' can't override getter from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT': {
+    'id': 'YGWPDH',
+    'template': "This is the getter that cannot be overridden by a method.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_GETTER': {
+    'id': 'BNKNXO',
+    'template': "Getter '#{name}' in '#{class}' can't override method from "
+        "'#{inheritedClass}'.",
+  },
+
+  'CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT': {
+    'id': 'KFBCYX',
+    'template': "This is the method that cannot be overridden by a getter.",
+  },
+
+  'MISSING_FORMALS': {
+    'id': 'BOERAF',
+    'template': "Formal parameters are missing.",
+  },
+
+  'EXTRA_FORMALS': {
+    'id': 'UTWRIU',
+    'template': "Formal parameters are not allowed here.",
+  },
+
+  'UNARY_OPERATOR_BAD_ARITY': {
+    'id': 'TNHLAL',
+    'template': "Operator '#{operatorName}' must have no parameters.",
+  },
+
+  'MINUS_OPERATOR_BAD_ARITY': {
+    'id': 'SXDRRU',
+    'template': "Operator '-' must have 0 or 1 parameters.",
+  },
+
+  'BINARY_OPERATOR_BAD_ARITY': {
+    'id': 'QKWAUM',
+    'template': "Operator '#{operatorName}' must have exactly 1 parameter.",
+  },
+
+  'TERNARY_OPERATOR_BAD_ARITY': {
+    'id': 'LSMQGF',
+    'template': "Operator '#{operatorName}' must have exactly 2 parameters.",
+  },
+
+  'OPERATOR_OPTIONAL_PARAMETERS': {
+    'id': 'HSGRBV',
+    'template': "Operator '#{operatorName}' cannot have optional parameters.",
+  },
+
+  'OPERATOR_NAMED_PARAMETERS': {
+    'id': 'EACWGS',
+    'template': "Operator '#{operatorName}' cannot have named parameters.",
+  },
+
+  'CONSTRUCTOR_WITH_RETURN_TYPE': {
+    'id': 'OPMBHF',
+    'template': "Cannot have return type for constructor.",
+  },
+
+  'CANNOT_RETURN_FROM_CONSTRUCTOR': {
+    'id': 'NFUGNH',
+    'template': "Constructors can't return values.",
+    'howToFix': "Remove the return statement or use a factory constructor.",
+    'examples': [
+      """
+class C {
+C() {
+  return 1;
+}
+}
+
+main() => new C();"""
+    ],
+  },
+
+  'ILLEGAL_FINAL_METHOD_MODIFIER': {
+    'id': 'YUKCVU',
+    'template': "Cannot have final modifier on method.",
+  },
+
+  'ILLEGAL_CONST_FIELD_MODIFIER': {
+    'id': 'JGFAGV',
+    'template': "Cannot have const modifier on non-static field.",
+    'howToFix': "Try adding a static modifier, or removing the const modifier.",
+    'examples': [
+      """
+class C {
+const int a = 1;
+}
+
+main() => new C();"""
+    ],
+  },
+
+  'ILLEGAL_CONSTRUCTOR_MODIFIERS': {
+    'id': 'WODRHN',
+    'template': "Illegal constructor modifiers: '#{modifiers}'.",
+  },
+
+  'ILLEGAL_MIXIN_APPLICATION_MODIFIERS': {
+    'id': 'OFLFHN',
+    'template': "Illegal mixin application modifiers: '#{modifiers}'.",
+  },
+
+  'ILLEGAL_MIXIN_SUPERCLASS': {
+    'id': 'TPVVYN',
+    'template': "Class used as mixin must have Object as superclass.",
+  },
+
+  'ILLEGAL_MIXIN_OBJECT': {
+    'id': 'CMVTLF',
+    'template': "Cannot use Object as mixin.",
+  },
+
+  'ILLEGAL_MIXIN_CONSTRUCTOR': {
+    'id': 'HXBUIB',
+    'template': "Class used as mixin cannot have non-factory constructor.",
+  },
+
+  'ILLEGAL_MIXIN_CYCLE': {
+    'id': 'ANXAMU',
+    'template': "Class used as mixin introduces mixin cycle: "
+        "'#{mixinName1}' <-> '#{mixinName2}'.",
+  },
+
+  'ILLEGAL_MIXIN_WITH_SUPER': {
+    'id': 'KIEUGK',
+    'template': "Cannot use class '#{className}' as a mixin because it uses "
+        "'super'.",
+  },
+
+  'ILLEGAL_MIXIN_SUPER_USE': {
+    'id': 'QKUPLH',
+    'template': "Use of 'super' in class used as mixin.",
+  },
+
+  'PARAMETER_NAME_EXPECTED': {
+    'id': 'JOUOBT',
+    'template': "parameter name expected.",
+  },
+
+  'CANNOT_RESOLVE_GETTER': {
+    'id': 'TDHKSW',
+    'template': "Cannot resolve getter.",
+  },
+
+  'CANNOT_RESOLVE_SETTER': {
+    'id': 'QQFANP',
+    'template': "Cannot resolve setter.",
+  },
+
+  'ASSIGNING_FINAL_FIELD_IN_SUPER': {
+    'id': 'LXUPCC',
+    'template': "Cannot assign a value to final field '#{name}' "
+        "in superclass '#{superclassName}'.",
+  },
+
+  'ASSIGNING_METHOD': {
+    'id': 'JUVMYC',
+    'template': "Cannot assign a value to a method.",
+  },
+
+  'ASSIGNING_METHOD_IN_SUPER': {
+    'id': 'AGMAXN',
+    'template': "Cannot assign a value to method '#{name}' "
+        "in superclass '#{superclassName}'.",
+  },
+
+  'ASSIGNING_TYPE': {
+    'id': 'VXTPWE',
+    'template': "Cannot assign a value to a type.",
+  },
+
+  'IF_NULL_ASSIGNING_TYPE': {
+    'id': 'XBRHGK',
+    'template':
+        "Cannot assign a value to a type. Note that types are never null, "
+        "so this ??= assignment has no effect.",
+    'howToFix': "Try removing the '??=' assignment.",
+    'examples': ["class A {} main() { print(A ??= 3);}",],
+  },
+
+  'VOID_NOT_ALLOWED': {
+    'id': 'DMMDXT',
+    'template':
+        "Type 'void' can't be used here because it isn't a return type.",
+    'howToFix':
+        "Try removing 'void' keyword or replace it with 'var', 'final', "
+        "or a type.",
+    'examples': ["void x; main() {}", "foo(void x) {} main() { foo(null); }",],
+  },
+
+  'NULL_NOT_ALLOWED': {
+    'id': 'STYNSK',
+    'template': "`null` can't be used here.",
+  },
+
+  'BEFORE_TOP_LEVEL': {
+    'id': 'GRCXQF',
+    'template': "Part header must come before top-level definitions.",
+  },
+
+  'IMPORT_PART_OF': {
+    'id': 'VANCWE',
+    'template': "The imported library must not have a 'part-of' directive.",
+    'howToFix': "Try removing the 'part-of' directive or replacing the "
+        "import of the library with a 'part' directive.",
+    'examples': [
+      {
+        'main.dart': """
+library library;
+
+import 'part.dart';
+
+main() {}
+""",
+        'part.dart': """
+part of library;
+"""
+      }
+    ],
+  },
+
+  'IMPORT_PART_OF_HERE': {
+    'id': 'TRSZOJ',
+    'template': 'The library is imported here.',
+  },
+
+  'LIBRARY_NAME_MISMATCH': {
+    'id': 'AXGYPQ',
+    'template': "Expected part of library name '#{libraryName}'.",
+    'howToFix': "Try changing the directive to 'part of #{libraryName};'.",
+    'examples': [
+      {
+        'main.dart': """
+library lib.foo;
+
+part 'part.dart';
+
+main() {}
+""",
+        'part.dart': """
+part of lib.bar;
+"""
+      }
+    ],
+  },
+
+  'MISSING_LIBRARY_NAME': {
+    'id': 'NYQNCA',
+    'template': "Library has no name. Part directive expected library name "
+        "to be '#{libraryName}'.",
+    'howToFix': "Try adding 'library #{libraryName};' to the library.",
+    'examples': [
+      {
+        'main.dart': """
+part 'part.dart';
+
+main() {}
+""",
+        'part.dart': """
+part of lib.foo;
+"""
+      }
+    ],
+  },
+
+  'THIS_IS_THE_PART_OF_TAG': {
+    'id': 'RPSJRS',
+    'template': "This is the part of directive.",
+  },
+
+  'MISSING_PART_OF_TAG': {
+    'id': 'QNYCMV',
+    'template': "This file has no part-of tag, but it is being used as a part.",
+  },
+
+  'DUPLICATED_PART_OF': {
+    'id': 'UJDYHF',
+    'template': "Duplicated part-of directive.",
+  },
+
+  'DUPLICATED_LIBRARY_NAME': {
+    'id': 'OSEHXI',
+    'template': "Duplicated library name '#{libraryName}'.",
+  },
+
+  'DUPLICATED_RESOURCE': {
+    'id': 'UFWKBY',
+    'template': "The resource '#{resourceUri}' is loaded through both "
+        "'#{canonicalUri1}' and '#{canonicalUri2}'.",
+  },
+
+  'DUPLICATED_LIBRARY_RESOURCE': {
+    'id': 'KYGYTT',
+    'template':
+        "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
+        "both '#{canonicalUri1}' and '#{canonicalUri2}'.",
+  },
+
+  // This is used as an exception.
+  'INVALID_SOURCE_FILE_LOCATION': {
+    'id': 'WIGJFG',
+    'template': """
+Invalid offset (#{offset}) in source map.
+File: #{fileName}
+Length: #{length}""",
+  },
+
+  'TOP_LEVEL_VARIABLE_DECLARED_STATIC': {
+    'id': 'IVNDML',
+    'template': "Top-level variable cannot be declared static.",
+  },
+
+  'REFERENCE_IN_INITIALIZATION': {
+    'id': 'OVWTEU',
+    'template': "Variable '#{variableName}' is referenced during its "
+        "initialization.",
+    'howToFix': "If you are trying to reference a shadowed variable, rename "
+        "one of the variables.",
+    'examples': [
+      """
+foo(t) {
+var t = t;
+return t;
+}
+
+main() => foo(1);
+"""
+    ],
+  },
+
+  'CONST_WITHOUT_INITIALIZER': {
+    'id': 'UDWCNH',
+    'template': "A constant variable must be initialized.",
+    'howToFix': "Try adding an initializer or "
+        "removing the 'const' modifier.",
+    'examples': [
+      """
+void main() {
+const c; // This constant variable must be initialized.
+}"""
+    ],
+  },
+
+  'FINAL_WITHOUT_INITIALIZER': {
+    'id': 'YMESFI',
+    'template': "A final variable must be initialized.",
+    'howToFix': "Try adding an initializer or "
+        "removing the 'final' modifier.",
+    'examples': ["class C { static final field; } main() => C.field;"],
+  },
+
+  'CONST_LOOP_VARIABLE': {
+    'id': 'WUSKMG',
+    'template': "A loop variable cannot be constant.",
+    'howToFix': "Try remove the 'const' modifier or "
+        "replacing it with a 'final' modifier.",
+    'examples': [
+      """
+void main() {
+  for (const c in []) {}
+}"""
+    ],
+  },
+
+  'MEMBER_USES_CLASS_NAME': {
+    'id': 'TVFYRK',
+    'template': "Member variable can't have the same name as the class it is "
+        "declared in.",
+    'howToFix': "Try renaming the variable.",
+    'examples': [
+      """
+class A { var A; }
+main() {
+var a = new A();
+a.A = 1;
+}
+""",
+      """
+class A { static var A; }
+main() => A.A = 1;
+"""
+    ],
+  },
+
+  'WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT': {
+    'id': 'IXYNUF',
+    'template': "Wrong number of arguments to assert. Should be 1, but given "
+        "#{argumentCount}.",
+  },
+
+  'ASSERT_IS_GIVEN_NAMED_ARGUMENTS': {
+    'id': 'EJFDTO',
+    'template':
+        "'assert' takes no named arguments, but given #{argumentCount}.",
+  },
+
+  'FACTORY_REDIRECTION_IN_NON_FACTORY': {
+    'id': 'DTBWEX',
+    'template': "Factory redirection only allowed in factories.",
+  },
+
+  'MISSING_FACTORY_KEYWORD': {
+    'id': 'HOQYYA',
+    'template': "Did you forget a factory keyword here?",
+  },
+
+  'NO_SUCH_METHOD_IN_NATIVE': {
+    'id': 'MSDDBX',
+    'template':
+        "'NoSuchMethod' is not supported for classes that extend native "
+        "classes.",
+  },
+
+  'DEFERRED_LIBRARY_DART_2_DART': {
+    'id': 'RIRQAH',
+    'template': "Deferred loading is not supported by the dart backend yet. "
+        "The output will not be split.",
+  },
+
+  'DEFERRED_LIBRARY_WITHOUT_PREFIX': {
+    'id': 'CARRII',
+    'template': "This import is deferred but there is no prefix keyword.",
+    'howToFix': "Try adding a prefix to the import."
+  },
+
+  'DEFERRED_OLD_SYNTAX': {
+    'id': 'QCBRAE',
+    'template': "The DeferredLibrary annotation is obsolete.",
+    'howToFix':
+        "Use the \"import 'lib.dart' deferred as prefix\" syntax instead.",
+  },
+
+  'DEFERRED_LIBRARY_DUPLICATE_PREFIX': {
+    'id': 'BBMJTD',
+    'template': "The prefix of this deferred import is not unique.",
+    'howToFix': "Try changing the import prefix."
+  },
+
+  'DEFERRED_TYPE_ANNOTATION': {
+    'id': 'JOUEFD',
+    'template': "The type #{node} is deferred. "
+        "Deferred types are not valid as type annotations.",
+    'howToFix': "Try using a non-deferred abstract class as an interface.",
+  },
+
+  'ILLEGAL_STATIC': {
+    'id': 'HFBHVE',
+    'template': "Modifier static is only allowed on functions declared in "
+        "a class.",
+  },
+
+  'STATIC_FUNCTION_BLOAT': {
+    'id': 'SJHTKF',
+    'template': "Using '#{class}.#{name}' may lead to unnecessarily large "
+        "generated code.",
+    'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
+        "https://goo.gl/Akrrog.",
+  },
+
+  'NON_CONST_BLOAT': {
+    'id': 'RDRSHO',
+    'template': "Using 'new #{name}' may lead to unnecessarily large generated "
+        "code.",
+    'howToFix': "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
+        "described at https://goo.gl/Akrrog.",
+  },
+
+  'STRING_EXPECTED': {
+    'id': 'OEJOOI',
+    'template': "Expected a 'String', but got an instance of '#{type}'.",
+  },
+
+  'PRIVATE_IDENTIFIER': {
+    'id': 'XAHVWI',
+    'template': "'#{value}' is not a valid Symbol name because it starts with "
+        "'_'.",
+  },
+
+  'PRIVATE_NAMED_PARAMETER': {
+    'id': 'VFGCLK',
+    'template': "Named optional parameter can't have a library private name.",
+    'howToFix': "Try removing the '_' or making the parameter positional or "
+        "required.",
+    'examples': ["""foo({int _p}) {} main() => foo();"""],
+  },
+
+  'UNSUPPORTED_LITERAL_SYMBOL': {
+    'id': 'OYCDII',
+    'template':
+        "Symbol literal '##{value}' is currently unsupported by dart2js.",
+  },
+
+  'INVALID_SYMBOL': {
+    'id': 'RUXMBL',
+    'template': '''
+'#{value}' is not a valid Symbol name because is not:
+* an empty String,
+* a user defined operator,
+* a qualified non-private identifier optionally followed by '=', or
+* a qualified non-private identifier followed by '.' and a user-defined '''
+        "operator.",
+  },
+
+  'AMBIGUOUS_REEXPORT': {
+    'id': 'YNTOND',
+    'template': "'#{name}' is (re)exported by multiple libraries.",
+  },
+
+  'AMBIGUOUS_LOCATION': {
+    'id': 'SKLTYA',
+    'template': "'#{name}' is defined here.",
+  },
+
+  'IMPORTED_HERE': {'id': 'IMUXAE', 'template': "'#{name}' is imported here.",},
+
+  'OVERRIDE_EQUALS_NOT_HASH_CODE': {
+    'id': 'MUHYXI',
+    'template': "The class '#{class}' overrides 'operator==', "
+        "but not 'get hashCode'.",
+  },
+
+  'INTERNAL_LIBRARY_FROM': {
+    'id': 'RXOCLX',
+    'template': "Internal library '#{resolvedUri}' is not accessible from "
+        "'#{importingUri}'.",
+  },
+
+  'INTERNAL_LIBRARY': {
+    'id': 'SYLJAV',
+    'template': "Internal library '#{resolvedUri}' is not accessible.",
+  },
+
+  'JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS': {
+    'id': 'LSHKJK',
+    'template':
+        "Js-interop class '#{cls}' cannot extend from the non js-interop "
+        "class '#{superclass}'.",
+    'howToFix': "Annotate the superclass with @JS.",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            class Foo { }
+
+            @JS()
+            class Bar extends Foo { }
+
+            main() {
+              new Bar();
+            }
+            """
+    ],
+  },
+
+  'JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER': {
+    'id': 'QLLLEE',
+    'template':
+        "Member '#{member}' in js-interop class '#{cls}' is not external.",
+    'howToFix': "Mark all interop methods external",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            @JS()
+            class Foo {
+              bar() {}
+            }
+
+            main() {
+              new Foo().bar();
+            }
+            """
+    ],
+  },
+
+  'JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS': {
+    'id': 'TDQHRY',
+    'template': "Js-interop method '#{method}' has named arguments but is not "
+        "a factory constructor of an @anonymous @JS class.",
+    'howToFix': "Remove all named arguments from js-interop method or "
+        "in the case of a factory constructor annotate the class "
+        "as @anonymous.",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            @JS()
+            class Foo {
+              external bar(foo, {baz});
+            }
+
+            main() {
+              new Foo().bar(4, baz: 5);
+            }
+            """
+    ],
+  },
+
+  'JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS': {
+    'id': 'EHEKUY',
+    'template':
+        "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
+        "object literal constructor is positional instead of named."
+        ".",
+    'howToFix': "Make all arguments in external factory object literal "
+        "constructors named.",
+    'examples': [
+      """
+            import 'package:js/js.dart';
+
+            @anonymous
+            @JS()
+            class Foo {
+              external factory Foo(foo, {baz});
+            }
+
+            main() {
+              new Foo(5, baz: 5);
+            }
+            """
+    ],
+  },
+
+  'LIBRARY_NOT_FOUND': {
+    'id': 'BARPSL',
+    'template': "Library not found '#{resolvedUri}'.",
+  },
+
+  'LIBRARY_NOT_SUPPORTED': {
+    'id': 'GDXUNS',
+    'template': "Library not supported '#{resolvedUri}'.",
+    'howToFix': "Try removing the dependency or enabling support using "
+        "the '--categories' option.",
+    'examples': [
+//            """
+//            import 'dart:io';
+//            main() {}
+//            """
+    ],
+    // TODO(johnniwinther): Enable example when message_kind_test.dart
+    // supports library loader callbacks.
+  },
+
+  'UNSUPPORTED_EQ_EQ_EQ': {
+    'id': 'GPOVNO',
+    'template': "'===' is not an operator. "
+        "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?",
+  },
+
+  'UNSUPPORTED_BANG_EQ_EQ': {
+    'id': 'HDYKMV',
+    'template': "'!==' is not an operator. "
+        "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?",
+  },
+
+  'UNSUPPORTED_PREFIX_PLUS': {
+    'id': 'LSQTHP',
+    'template': "'+' is not a prefix operator. ",
+    'howToFix': "Try removing '+'.",
+    'examples': ["main() => +2;  // No longer a valid way to write '2'"],
+  },
+
+  'UNSUPPORTED_THROW_WITHOUT_EXP': {
+    'id': 'QOAKGE',
+    'template': "No expression after 'throw'. "
+        "Did you mean 'rethrow'?",
+  },
+
+  'DEPRECATED_TYPEDEF_MIXIN_SYNTAX': {
+    'id': 'BBGGFE',
+    'template': "'typedef' not allowed here. ",
+    'howToFix': "Try replacing 'typedef' with 'class'.",
+    'examples': [
+      """
+class B { }
+class M1 {  }
+typedef C = B with M1;  // Need to replace 'typedef' with 'class'.
+main() { new C(); }
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING': {
+    'id': 'XSKTIB',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "and a 'String' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// 'Foo' is a type literal, not a string.
+@MirrorsUsed(symbols: const [Foo])
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING_OR_TYPE': {
+    'id': 'JQDJPL',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "and a 'String' or 'Type' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// 'main' is a method, not a class.
+@MirrorsUsed(targets: const [main])
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING_OR_LIST': {
+    'id': 'UVYCOE',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "and a 'String' or 'List' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// 'Foo' is not a string.
+@MirrorsUsed(symbols: Foo)
+import 'dart:mirrors';
+
+class Foo {}
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_EXPECTED_STRING_TYPE_OR_LIST': {
+    'id': 'WSYDFL',
+    'template':
+        "Can't use '#{name}' here because it's an instance of '#{type}' "
+        "but a 'String', 'Type', or 'List' value is expected.",
+    'howToFix': "Did you forget to add quotes?",
+    'examples': [
+      """
+// '1' is not a string.
+@MirrorsUsed(targets: 1)
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY': {
+    'id': 'VDBBNE',
+    'template': "Can't find '#{name}' in the current library.",
+    // TODO(ahe): The closest identifiers in edit distance would be nice.
+    'howToFix': "Did you forget to add an import?",
+    'examples': [
+      """
+// 'window' is not in scope because dart:html isn't imported.
+@MirrorsUsed(targets: 'window')
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_CANNOT_RESOLVE_IN_LIBRARY': {
+    'id': 'RUEKXE',
+    'template': "Can't find '#{name}' in the library '#{library}'.",
+    // TODO(ahe): The closest identifiers in edit distance would be nice.
+    'howToFix': "Is '#{name}' spelled right?",
+    'examples': [
+      """
+// 'List' is misspelled.
+@MirrorsUsed(targets: 'dart.core.Lsit')
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'MIRRORS_CANNOT_FIND_IN_ELEMENT': {
+    'id': 'ACPDCS',
+    'template': "Can't find '#{name}' in '#{element}'.",
+    // TODO(ahe): The closest identifiers in edit distance would be nice.
+    'howToFix': "Is '#{name}' spelled right?",
+    'examples': [
+      """
+// 'addAll' is misspelled.
+@MirrorsUsed(targets: 'dart.core.List.addAl')
+import 'dart:mirrors';
+
+main() {}
+"""
+    ],
+  },
+
+  'INVALID_URI': {
+    'id': 'QQEQMK',
+    'template': "'#{uri}' is not a valid URI.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+// can't have a '[' in a URI
+import '../../Udyn[mic ils/expect.dart';
+
+main() {}
+"""
+    ],
+  },
+
+  'INVALID_PACKAGE_CONFIG': {
+    'id': 'XKFAJO',
+    'template': """Package config file '#{uri}' is invalid.
+#{exception}""",
+    'howToFix': DONT_KNOW_HOW_TO_FIX
+  },
+
+  'INVALID_PACKAGE_URI': {
+    'id': 'MFVNNJ',
+    'template': "'#{uri}' is not a valid package URI (#{exception}).",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+// can't have a 'top level' package URI
+import 'package:foo.dart';
+
+main() {}
+""",
+      """
+// can't have 2 slashes
+import 'package://foo/foo.dart';
+
+main() {}
+""",
+      """
+// package name must be valid
+import 'package:not\valid/foo.dart';
+
+main() {}
+"""
+    ],
+  },
+
+  'READ_SCRIPT_ERROR': {
+    'id': 'JDDYLH',
+    'template': "Can't read '#{uri}' (#{exception}).",
+    // Don't know how to fix since the underlying error is unknown.
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+// 'foo.dart' does not exist.
+import 'foo.dart';
+
+main() {}
+"""
+    ],
+  },
+
+  'READ_SELF_ERROR': {
+    'id': 'CRJUAV',
+    'template': "#{exception}",
+    // Don't know how to fix since the underlying error is unknown.
+    'howToFix': DONT_KNOW_HOW_TO_FIX
+  },
+
+  'EXTRANEOUS_MODIFIER': {
+    'id': 'DPLVJG',
+    'template': "Can't have modifier '#{modifier}' here.",
+    'howToFix': "Try removing '#{modifier}'.",
+    'examples': [
+      "var String foo; main(){}",
+      // "var get foo; main(){}",
+      "var set foo; main(){}",
+      "var final foo; main(){}",
+      "var var foo; main(){}",
+      "var const foo; main(){}",
+      "var abstract foo; main(){}",
+      "var static foo; main(){}",
+      "var external foo; main(){}",
+      "get var foo; main(){}",
+      "set var foo; main(){}",
+      "final var foo; main(){}",
+      "var var foo; main(){}",
+      "const var foo; main(){}",
+      "abstract var foo; main(){}",
+      "static var foo; main(){}",
+      "external var foo; main(){}"
+    ],
+  },
+
+  'EXTRANEOUS_MODIFIER_REPLACE': {
+    'id': 'SSXDLN',
+    'template': "Can't have modifier '#{modifier}' here.",
+    'howToFix': "Try replacing modifier '#{modifier}' with 'var', 'final', "
+        "or a type.",
+    'examples': [
+      // "get foo; main(){}",
+      "set foo; main(){}",
+      "abstract foo; main(){}",
+      "static foo; main(){}",
+      "external foo; main(){}"
+    ],
+  },
+
+  'ABSTRACT_CLASS_INSTANTIATION': {
+    'id': 'KOBCRO',
+    'template': "Can't instantiate abstract class.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': ["abstract class A {} main() { new A(); }"],
+  },
+
+  'BODY_EXPECTED': {
+    'id': 'YXCAHO',
+    'template': "Expected a function body or '=>'.",
+    // TODO(ahe): In some scenarios, we can suggest removing the 'static'
+    // keyword.
+    'howToFix': "Try adding {}.",
+    'examples': ["main();"],
+  },
+
+  'MIRROR_BLOAT': {
+    'id': 'BSEAIT',
+    'template':
+        "#{count} methods retained for use by dart:mirrors out of #{total}"
+        " total methods (#{percentage}%).",
+  },
+
+  'MIRROR_IMPORT': {'id': 'BDAETE', 'template': "Import of 'dart:mirrors'.",},
+
+  'MIRROR_IMPORT_NO_USAGE': {
+    'id': 'OJOHTR',
+    'template':
+        "This import is not annotated with @MirrorsUsed, which may lead to "
+        "unnecessarily large generated code.",
+    'howToFix': "Try adding '@MirrorsUsed(...)' as described at "
+        "https://goo.gl/Akrrog.",
+  },
+
+  'JS_PLACEHOLDER_CAPTURE': {
+    'id': 'EJXEGQ',
+    'template': "JS code must not use '#' placeholders inside functions.",
+    'howToFix': "Use an immediately called JavaScript function to capture the"
+        " the placeholder values as JavaScript function parameters.",
+  },
+
+  'WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT': {
+    'id': 'JHRISO',
+    'template':
+        "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant.",
+  },
+
+  'EXPECTED_IDENTIFIER_NOT_RESERVED_WORD': {
+    'id': 'FEJXJF',
+    'template': "'#{keyword}' is a reserved word and can't be used here.",
+    'howToFix': "Try using a different name.",
+    'examples': ["do() {} main() {}"],
+  },
+
+  'NAMED_FUNCTION_EXPRESSION': {
+    'id': 'CTHFPI',
+    'template': "Function expression '#{name}' cannot be named.",
+    'howToFix': "Try removing the name.",
+    'examples': ["main() { var f = func() {}; }"],
+  },
+
+  'UNUSED_METHOD': {
+    'id': 'PKLRQL',
+    'template': "The method '#{name}' is never called.",
+    'howToFix': "Consider deleting it.",
+    'examples': ["deadCode() {} main() {}"],
+  },
+
+  'UNUSED_CLASS': {
+    'id': 'TBIECC',
+    'template': "The class '#{name}' is never used.",
+    'howToFix': "Consider deleting it.",
+    'examples': ["class DeadCode {} main() {}"],
+  },
+
+  'UNUSED_TYPEDEF': {
+    'id': 'JBIPCN',
+    'template': "The typedef '#{name}' is never used.",
+    'howToFix': "Consider deleting it.",
+    'examples': ["typedef DeadCode(); main() {}"],
+  },
+
+  'ABSTRACT_METHOD': {
+    'id': 'HOKOBG',
+    'template': "The method '#{name}' has no implementation in "
+        "class '#{class}'.",
+    'howToFix': "Try adding a body to '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+class Class {
+method();
+}
+main() => new Class().method();
+"""
+    ],
+  },
+
+  'ABSTRACT_GETTER': {
+    'id': 'VKTRNK',
+    'template': "The getter '#{name}' has no implementation in "
+        "class '#{class}'.",
+    'howToFix': "Try adding a body to '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+class Class {
+get getter;
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'ABSTRACT_SETTER': {
+    'id': 'XGDGKK',
+    'template': "The setter '#{name}' has no implementation in "
+        "class '#{class}'.",
+    'howToFix': "Try adding a body to '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+class Class {
+set setter(_);
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'INHERIT_GETTER_AND_METHOD': {
+    'id': 'UMEUEG',
+    'template': "The class '#{class}' can't inherit both getters and methods "
+        "by the named '#{name}'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+class A {
+get member => null;
+}
+class B {
+member() {}
+}
+class Class implements A, B {
+}
+main() => new Class();
+"""
+    ],
+  },
+
+  'INHERITED_METHOD': {
+    'id': 'GMSVBM',
+    'template': "The inherited method '#{name}' is declared here in class "
+        "'#{class}'.",
+  },
+
+  'INHERITED_EXPLICIT_GETTER': {
+    'id': 'KKAVRS',
+    'template': "The inherited getter '#{name}' is declared here in class "
+        "'#{class}'.",
+  },
+
+  'INHERITED_IMPLICIT_GETTER': {
+    'id': 'JBAMEJ',
+    'template': "The inherited getter '#{name}' is implicitly declared by this "
+        "field in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_METHOD_ONE': {
+    'id': 'CMCLWO',
+    'template': "'#{class}' doesn't implement '#{method}' "
+        "declared in '#{declarer}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+m();
+}
+class C implements I {}
+main() => new C();
+""",
+      """
+abstract class I {
+m();
+}
+class C extends I {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_METHOD': {
+    'id': 'IJSNQB',
+    'template': "'#{class}' doesn't implement '#{method}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+m();
+}
+
+abstract class J {
+m();
+}
+
+class C implements I, J {}
+
+main() {
+new C();
+}
+""",
+      """
+abstract class I {
+m();
+}
+
+abstract class J {
+m();
+}
+
+class C extends I implements J {}
+
+main() {
+new C();
+}
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_METHOD_CONT': {
+    'id': 'KFBKPO',
+    'template': "The method '#{name}' is declared here in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_SETTER_ONE': {
+    'id': 'QGKTEA',
+    'template': "'#{class}' doesn't implement the setter '#{name}' "
+        "declared in '#{declarer}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+set m(_);
+}
+class C implements I {}
+class D implements I {
+set m(_) {}
+}
+main() {
+new D().m = 0;
+new C();
+}
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_SETTER': {
+    'id': 'VEEGJQ',
+    'template': "'#{class}' doesn't implement the setter '#{name}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+set m(_);
+}
+abstract class J {
+set m(_);
+}
+class C implements I, J {}
+main() => new C();
+""",
+      """
+abstract class I {
+set m(_);
+}
+abstract class J {
+set m(_);
+}
+class C extends I implements J {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_EXPLICIT_SETTER': {
+    'id': 'SABABA',
+    'template': "The setter '#{name}' is declared here in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_IMPLICIT_SETTER': {
+    'id': 'SWESAQ',
+    'template': "The setter '#{name}' is implicitly declared by this field "
+        "in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_GETTER_ONE': {
+    'id': 'ODEPFW',
+    'template': "'#{class}' doesn't implement the getter '#{name}' "
+        "declared in '#{declarer}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+get m;
+}
+class C implements I {}
+main() => new C();
+""",
+      """
+abstract class I {
+get m;
+}
+class C extends I {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_GETTER': {
+    'id': 'VHSECG',
+    'template': "'#{class}' doesn't implement the getter '#{name}'.",
+    'howToFix': "Try adding an implementation of '#{name}' or declaring "
+        "'#{class}' to be 'abstract'.",
+    'examples': [
+      """
+abstract class I {
+get m;
+}
+abstract class J {
+get m;
+}
+class C implements I, J {}
+main() => new C();
+""",
+      """
+abstract class I {
+get m;
+}
+abstract class J {
+get m;
+}
+class C extends I implements J {}
+main() => new C();
+"""
+    ],
+  },
+
+  'UNIMPLEMENTED_EXPLICIT_GETTER': {
+    'id': 'HFDJPP',
+    'template': "The getter '#{name}' is declared here in class '#{class}'.",
+  },
+
+  'UNIMPLEMENTED_IMPLICIT_GETTER': {
+    'id': 'BSCQNO',
+    'template': "The getter '#{name}' is implicitly declared by this field "
+        "in class '#{class}'.",
+  },
+
+  'INVALID_METADATA': {
+    'id': 'RKJGDE',
+    'template':
+        "A metadata annotation must be either a reference to a compile-time "
+        "constant variable or a call to a constant constructor.",
+    'howToFix':
+        "Try using a different constant value or referencing it through a "
+        "constant variable.",
+    'examples': [
+'@Object main() {}',
+'@print main() {}']
+  },
+
+  'INVALID_METADATA_GENERIC': {
+    'id': 'WEEDQD',
+    'template':
+        "A metadata annotation using a constant constructor cannot use type "
+        "arguments.",
+    'howToFix':
+        "Try removing the type arguments or referencing the constant "
+        "through a constant variable.",
+    'examples': [
+      '''
+class C<T> {
+  const C();
+}
+@C<int>() main() {}
+'''],
+  },
+
+  'EQUAL_MAP_ENTRY_KEY': {
+    'id': 'KIDLPM',
+    'template': "An entry with the same key already exists in the map.",
+    'howToFix': "Try removing the previous entry or changing the key in one "
+        "of the entries.",
+    'examples': [
+      """
+main() {
+var m = const {'foo': 1, 'foo': 2};
+}"""
+    ],
+  },
+
+  'BAD_INPUT_CHARACTER': {
+    'id': 'SHQWJY',
+    'template': "Character U+#{characterHex} isn't allowed here.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+main() {
+String x = ç;
+}
+"""
+    ],
+  },
+
+  'UNTERMINATED_STRING': {
+    'id': 'TRLTHK',
+    'template': "String must end with #{quote}.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      """
+main() {
+return '
+;
+}
+""",
+      """
+main() {
+return \"
+;
+}
+""",
+      """
+main() {
+return r'
+;
+}
+""",
+      """
+main() {
+return r\"
+;
+}
+""",
+      """
+main() => '''
+""",
+      """
+main() => \"\"\"
+""",
+      """
+main() => r'''
+""",
+      """
+main() => r\"\"\"
+"""
+    ],
+  },
+
+  'UNMATCHED_TOKEN': {
+    'id': 'AGJKMQ',
+    'template': "Can't find '#{end}' to match '#{begin}'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': ["main(", "main(){", "main(){]}",],
+  },
+
+  'UNTERMINATED_TOKEN': {
+    'id': 'VIIXHQ',
+    'template':
+        // This is a fall-back message that shouldn't happen.
+        "Incomplete token.",
+  },
+
+  'EXPONENT_MISSING': {
+    'id': 'CXPLCR',
+    'template':
+        "Numbers in exponential notation should always contain an exponent"
+        " (an integer number with an optional sign).",
+    'howToFix': "Make sure there is an exponent, and remove any whitespace "
+        "before it.",
+    'examples': [
+      """
+main() {
+var i = 1e;
+}
+"""
+    ],
+  },
+
+  'HEX_DIGIT_EXPECTED': {
+    'id': 'GKCAGV',
+    'template': "A hex digit (0-9 or A-F) must follow '0x'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
+    'examples': [
+      """
+main() {
+var i = 0x;
+}
+"""
+    ],
+  },
+
+  'MALFORMED_STRING_LITERAL': {
+    'id': 'DULNSD',
+    'template':
+        r"A '$' has special meaning inside a string, and must be followed by "
+        "an identifier or an expression in curly braces ({}).",
+    'howToFix': r"Try adding a backslash (\) to escape the '$'.",
+    'examples': [
+      r"""
+main() {
+return '$';
+}
+""",
+      r'''
+main() {
+return "$";
+}
+''',
+      r"""
+main() {
+return '''$''';
+}
+""",
+      r'''
+main() {
+return """$""";
+}
+'''
+    ],
+  },
+
+  'UNTERMINATED_COMMENT': {
+    'id': 'NECJNM',
+    'template': "Comment starting with '/*' must end with '*/'.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      r"""
+main() {
+}
+/*"""
+    ],
+  },
+
+  'MISSING_TOKEN_BEFORE_THIS': {
+    'id': 'AFKXGU',
+    'template': "Expected '#{token}' before this.",
+    // Consider the second example below: the parser expects a ')' before
+    // 'y', but a ',' would also have worked. We don't have enough
+    // information to give a good suggestion.
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': ["main() => true ? 1;", "main() => foo(x: 1 y: 2);",],
+  },
+
+  'MISSING_TOKEN_AFTER_THIS': {
+    'id': 'FMUFJL',
+    'template': "Expected '#{token}' after this.",
+    // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
+    // to give a good suggestion.
+    'howToFix': DONT_KNOW_HOW_TO_FIX,
+    'examples': [
+      "main(x) {x}",
+      """
+class S1 {}
+class S2 {}
+class S3 {}
+class A = S1 with S2, S3
+main() => new A();
+"""
+    ],
+  },
+
+  'CONSIDER_ANALYZE_ALL': {
+    'id': 'HHILSH',
+    'template': "Could not find '#{main}'.  Nothing will be analyzed.",
+    'howToFix': "Try using '--analyze-all' to analyze everything.",
+    'examples': [''],
+  },
+
+  'MISSING_MAIN': {
+    'id': 'HNAOPV',
+    'template': "Could not find '#{main}'.",
+    // No example, test uses '--analyze-only' which will produce the above
+    // message [CONSIDER_ANALYZE_ALL].  An example for a human operator
+    // would be an empty file.
+    'howToFix': "Try adding a method named '#{main}' to your program."
+  },
+
+  'MAIN_NOT_A_FUNCTION': {
+    'id': 'PIURPA',
+    'template': "'#{main}' is not a function.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
+    'examples': ['var main;'],
+  },
+
+  'MAIN_WITH_EXTRA_PARAMETER': {
+    'id': 'ONOGQB',
+    'template': "'#{main}' cannot have more than two parameters.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX, // Don't state the obvious.
+    'examples': ['main(a, b, c) {}'],
+  },
+
+  'COMPILER_CRASHED': {
+    'id': 'MHDWAV',
+    'template': "The compiler crashed when compiling this element.",
+  },
+
+  'PLEASE_REPORT_THE_CRASH': {
+    'id': 'UUTHXX',
+    'template': '''
+The compiler is broken.
+
+When compiling the above element, the compiler crashed. It is not
+possible to tell if this is caused by a problem in your program or
+not. Regardless, the compiler should not crash.
+
+The Dart team would greatly appreciate if you would take a moment to
+report this problem at http://dartbug.com/new.
+
+Please include the following information:
+
+* the name and version of your operating system,
+
+* the Dart SDK build number (#{buildId}), and
+
+* the entire message you see here (including the full stack trace
+below as well as the source location above).
+''',
+  },
+
+  'POTENTIAL_MUTATION': {
+    'id': 'YGNLLB',
+    'template': "Variable '#{variableName}' is not known to be of type "
+        "'#{shownType}' because it is potentially mutated in the scope for "
+        "promotion.",
+  },
+
+  'POTENTIAL_MUTATION_HERE': {
+    'id': 'ATMSVX',
+    'template': "Variable '#{variableName}' is potentially mutated here.",
+  },
+
+  'POTENTIAL_MUTATION_IN_CLOSURE': {
+    'id': 'XUAHTW',
+    'template': "Variable '#{variableName}' is not known to be of type "
+        "'#{shownType}' because it is potentially mutated within a closure.",
+  },
+
+  'POTENTIAL_MUTATION_IN_CLOSURE_HERE': {
+    'id': 'UHFXLG',
+    'template': "Variable '#{variableName}' is potentially mutated in a "
+        "closure here.",
+  },
+
+  'ACCESSED_IN_CLOSURE': {
+    'id': 'JJHKSF',
+    'template': "Variable '#{variableName}' is not known to be of type "
+        "'#{shownType}' because it is accessed by a closure in the scope for "
+        "promotion and potentially mutated in the scope of "
+        "'#{variableName}'.",
+  },
+
+  'ACCESSED_IN_CLOSURE_HERE': {
+    'id': 'KMJVEA',
+    'template': "Variable '#{variableName}' is accessed in a closure here.",
+  },
+
+  'NOT_MORE_SPECIFIC': {
+    'id': 'EJHQAG',
+    'template': "Variable '#{variableName}' is not shown to have type "
+        "'#{shownType}' because '#{shownType}' is not more specific than the "
+        "known type '#{knownType}' of '#{variableName}'.",
+  },
+
+  'NOT_MORE_SPECIFIC_SUBTYPE': {
+    'id': 'APICDL',
+    'template': "Variable '#{variableName}' is not shown to have type "
+        "'#{shownType}' because '#{shownType}' is not a subtype of the "
+        "known type '#{knownType}' of '#{variableName}'.",
+  },
+
+  'NOT_MORE_SPECIFIC_SUGGESTION': {
+    'id': 'FFNCJX',
+    'template': "Variable '#{variableName}' is not shown to have type "
+        "'#{shownType}' because '#{shownType}' is not more specific than the "
+        "known type '#{knownType}' of '#{variableName}'.",
+    'howToFix': "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'.",
+  },
+
+  'NO_COMMON_SUBTYPES': {
+    'id': 'XKJOEC',
+    'template': "Types '#{left}' and '#{right}' have no common subtypes.",
+  },
+
+  'HIDDEN_WARNINGS_HINTS': {
+    'id': 'JBAWEK',
+    'template':
+        "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}.",
+  },
+
+  'HIDDEN_WARNINGS': {
+    'id': 'JIYWDC',
+    'template': "#{warnings} warning(s) suppressed in #{uri}.",
+  },
+
+  'HIDDEN_HINTS': {
+    'id': 'RHNXQT',
+    'template': "#{hints} hint(s) suppressed in #{uri}.",
+  },
+
+  'PREAMBLE': {
+    'id': 'GXGWIF',
+    'template': "When run on the command-line, the compiled output might"
+        " require a preamble file located in:\n"
+        "  <sdk>/lib/_internal/js_runtime/lib/preambles.",
+  },
+
+  'INVALID_SYNC_MODIFIER': {
+    'id': 'FNYUYU',
+    'template': "Invalid modifier 'sync'.",
+    'howToFix': "Try replacing 'sync' with 'sync*'.",
+    'examples': ["main() sync {}"],
+  },
+
+  'INVALID_AWAIT_FOR': {
+    'id': 'IEYGCY',
+    'template': "'await' is only supported on for-in loops.",
+    'howToFix': "Try rewriting the loop as a for-in loop or removing the "
+        "'await' keyword.",
+    'examples': [
+      """
+main() async* {
+await for (int i = 0; i < 10; i++) {}
+}
+"""
+    ],
+  },
+
+  'INVALID_AWAIT_FOR_IN': {
+    'id': 'FIEYGC',
+    'template': "'await' is only supported in methods with an 'async' or "
+                "'async*' body modifier.",
+    'howToFix': "Try adding 'async' or 'async*' to the method body or "
+                "removing the 'await' keyword.",
+    'examples': [
+      """
+main(o) sync* {
+  await for (var e in o) {}
+}
+"""
+    ],
+  },
+
+  'INVALID_AWAIT': {
+    'id': 'IEYHYD',
+    'template': "'await' is only supported in methods with an 'async' or "
+                "'async*' body modifier.",
+    'howToFix': "Try adding 'async' or 'async*' to the method body.",
+    'examples': [
+      """
+main() sync* {
+  await null;
+}
+"""
+    ],
+  },
+
+  'INVALID_YIELD': {
+    'id': 'IPGGCY',
+    'template': "'yield' is only supported in methods with a 'sync*' or "
+                "'async*' body modifier.",
+    'howToFix': "Try adding 'sync*' or 'async*' to the method body.",
+    'examples': [
+      """
+main() async {
+  yield 0;
+}
+"""
+    ],
+  },
+
+  'ASYNC_MODIFIER_ON_ABSTRACT_METHOD': {
+    'id': 'VRISLY',
+    'template':
+        "The modifier '#{modifier}' is not allowed on an abstract method.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier or adding a "
+        "body to the method.",
+    'examples': [
+      """
+abstract class A {
+method() async;
+}
+class B extends A {
+method() {}
+}
+main() {
+A a = new B();
+a.method();
+}
+"""
+    ],
+  },
+
+  'ASYNC_MODIFIER_ON_CONSTRUCTOR': {
+    'id': 'DHCFON',
+    'template': "The modifier '#{modifier}' is not allowed on constructors.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier.",
+    'examples': [
+      """
+class A {
+A() async;
+}
+main() => new A();""",
+      """
+class A {
+A();
+factory A.a() async* {}
+}
+main() => new A.a();"""
+    ],
+  },
+
+  'ASYNC_MODIFIER_ON_SETTER': {
+    'id': 'NMJLJE',
+    'template': "The modifier '#{modifier}' is not allowed on setters.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier.",
+    'examples': [
+      """
+class A {
+set foo(v) async {}
+}
+main() => new A().foo = 0;"""
+    ],
+  },
+
+  'YIELDING_MODIFIER_ON_ARROW_BODY': {
+    'id': 'UOGLUX',
+    'template':
+        "The modifier '#{modifier}' is not allowed on methods implemented "
+        "using '=>'.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier or implementing "
+        "the method body using a block: '{ ... }'.",
+    'examples': ["main() sync* => null;", "main() async* => null;"],
+  },
+
+  // TODO(johnniwinther): Check for 'async' as identifier.
+  'ASYNC_KEYWORD_AS_IDENTIFIER': {
+    'id': 'VTWSMA',
+    'template':
+        "'#{keyword}' cannot be used as an identifier in a function body "
+        "marked with '#{modifier}'.",
+    'options': ['--enable-async'],
+    'howToFix': "Try removing the '#{modifier}' modifier or renaming the "
+        "identifier.",
+    'examples': [
+      """
+main() async {
+var await;
+}""",
+      """
+main() async* {
+var yield;
+}""",
+      """
+main() sync* {
+var yield;
+}"""
+    ],
+  },
+
+  'RETURN_IN_GENERATOR': {
+    'id': 'AWGUVF',
+    'template':
+        "'return' with a value is not allowed in a method body using the "
+        "'#{modifier}' modifier.",
+    'howToFix': "Try removing the value, replacing 'return' with 'yield' "
+        "or changing the method body modifier.",
+    'examples': [
+      """
+foo() async* { return 0; }
+main() => foo();
+""",
+      """
+foo() sync* { return 0; }
+main() => foo();
+"""
+    ],
+  },
+
+  'NATIVE_NOT_SUPPORTED': {
+    'id': 'QMMLUT',
+    'template': "'native' modifier is not supported.",
+    'howToFix': "Try removing the 'native' implementation or analyzing the "
+        "code with the --allow-native-extensions option.",
+    'examples': [
+      """
+main() native "Main";
+"""
+    ],
+  },
+
+  'DART_EXT_NOT_SUPPORTED': {
+    'id': 'JLPQFJ',
+    'template': "The 'dart-ext' scheme is not supported.",
+    'howToFix': "Try analyzing the code with the --allow-native-extensions "
+        "option.",
+    'examples': [
+      """
+import 'dart-ext:main';
+
+main() {}
+"""
+    ],
+  },
+
+  'LIBRARY_TAG_MUST_BE_FIRST': {
+    'id': 'JFUSRX',
+    'template':
+        "The library declaration should come before other declarations.",
+    'howToFix': "Try moving the declaration to the top of the file.",
+    'examples': [
+      """
+import 'dart:core';
+library foo;
+main() {}
+""",
+    ],
+  },
+
+  'ONLY_ONE_LIBRARY_TAG': {
+    'id': 'CCXFMY',
+    'template': "There can only be one library declaration.",
+    'howToFix': "Try removing all other library declarations.",
+    'examples': [
+      """
+library foo;
+library bar;
+main() {}
+""",
+      """
+library foo;
+import 'dart:core';
+library bar;
+main() {}
+""",
+    ],
+  },
+
+  'IMPORT_BEFORE_PARTS': {
+    'id': 'NSMOQI',
+    'template': "Import declarations should come before parts.",
+    'howToFix': "Try moving this import further up in the file.",
+    'examples': [
+      {
+        'main.dart': """
+library test.main;
+part 'part.dart';
+import 'dart:core';
+main() {}
+""",
+        'part.dart': """
+part of test.main;
+""",
+      }
+    ],
+  },
+
+  'EXPORT_BEFORE_PARTS': {
+    'id': 'KYJTTC',
+    'template': "Export declarations should come before parts.",
+    'howToFix': "Try moving this export further up in the file.",
+    'examples': [
+      {
+        'main.dart': """
+library test.main;
+part 'part.dart';
+export 'dart:core';
+main() {}
+""",
+        'part.dart': """
+part of test.main;
+""",
+      }
+    ],
+
+//////////////////////////////////////////////////////////////////////////////
+// Patch errors start.
+//////////////////////////////////////////////////////////////////////////////
+  },
+
+  'PATCH_RETURN_TYPE_MISMATCH': {
+    'id': 'DTOQDU',
+    'template': "Patch return type '#{patchReturnType}' does not match "
+        "'#{originReturnType}' on origin method '#{methodName}'.",
+  },
+
+  'PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH': {
+    'id': 'KJUUYC',
+    'template': "Required parameter count of patch method "
+        "(#{patchParameterCount}) does not match parameter count on origin "
+        "method '#{methodName}' (#{originParameterCount}).",
+  },
+
+  'PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH': {
+    'id': 'GUTGTE',
+    'template': "Optional parameter count of patch method "
+        "(#{patchParameterCount}) does not match parameter count on origin "
+        "method '#{methodName}' (#{originParameterCount}).",
+  },
+
+  'PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH': {
+    'id': 'MCHEIC',
+    'template': "Optional parameters of origin and patch method "
+        "'#{methodName}' must both be either named or positional.",
+  },
+
+  'PATCH_PARAMETER_MISMATCH': {
+    'id': 'XISHPB',
+    'template': "Patch method parameter '#{patchParameter}' does not match "
+        "'#{originParameter}' on origin method '#{methodName}'.",
+  },
+
+  'PATCH_PARAMETER_TYPE_MISMATCH': {
+    'id': 'UGRBYD',
+    'template': "Patch method parameter '#{parameterName}' type "
+        "'#{patchParameterType}' does not match '#{originParameterType}' on "
+        "origin method '#{methodName}'.",
+  },
+
+  'PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION': {
+    'id': 'WSNMKD',
+    'template': "External method without an implementation.",
+  },
+
+  'PATCH_POINT_TO_FUNCTION': {
+    'id': 'CAVBPN',
+    'template': "This is the function patch '#{functionName}'.",
+  },
+
+  'PATCH_POINT_TO_CLASS': {
+    'id': 'TWDLDX',
+    'template': "This is the class patch '#{className}'.",
+  },
+
+  'PATCH_POINT_TO_GETTER': {
+    'id': 'TRBBNY',
+    'template': "This is the getter patch '#{getterName}'.",
+  },
+
+  'PATCH_POINT_TO_SETTER': {
+    'id': 'DAXDLW',
+    'template': "This is the setter patch '#{setterName}'.",
+  },
+
+  'PATCH_POINT_TO_CONSTRUCTOR': {
+    'id': 'VYQISY',
+    'template': "This is the constructor patch '#{constructorName}'.",
+  },
+
+  'PATCH_POINT_TO_PARAMETER': {
+    'id': 'TFPAGO',
+    'template': "This is the patch parameter '#{parameterName}'.",
+  },
+
+  'PATCH_NON_EXISTING': {
+    'id': 'AWOACF',
+    'template': "Origin does not exist for patch '#{name}'.",
+  },
+
+  // TODO(ahe): Eventually, this error should be removed as it will be
+  // handled by the regular parser.
+  'PATCH_NONPATCHABLE': {
+    'id': 'WQEPJI',
+    'template': "Only classes and functions can be patched.",
+  },
+
+  'PATCH_NON_EXTERNAL': {
+    'id': 'MHLXNK',
+    'template': "Only external functions can be patched.",
+  },
+
+  'PATCH_NON_CLASS': {
+    'id': 'UIALAB',
+    'template': "Patching non-class with class patch '#{className}'.",
+  },
+
+  'PATCH_NON_GETTER': {
+    'id': 'VTNQCJ',
+    'template': "Cannot patch non-getter '#{name}' with getter patch.",
+  },
+
+  'PATCH_NO_GETTER': {
+    'id': 'XOPDHD',
+    'template': "No getter found for getter patch '#{getterName}'.",
+  },
+
+  'PATCH_NON_SETTER': {
+    'id': 'XBOMMN',
+    'template': "Cannot patch non-setter '#{name}' with setter patch.",
+  },
+
+  'PATCH_NO_SETTER': {
+    'id': 'YITARQ',
+    'template': "No setter found for setter patch '#{setterName}'.",
+  },
+
+  'PATCH_NON_CONSTRUCTOR': {
+    'id': 'TWAEQV',
+    'template': "Cannot patch non-constructor with constructor patch "
+        "'#{constructorName}'.",
+  },
+
+  'PATCH_NON_FUNCTION': {
+    'id': 'EDXBPI',
+    'template': "Cannot patch non-function with function patch "
+        "'#{functionName}'.",
+  },
+
+  'INJECTED_PUBLIC_MEMBER': {
+    'id': 'JGMXMI',
+    'template': "Non-patch members in patch libraries must be private.",
+  },
+
+  'EXTERNAL_WITH_BODY': {
+    'id': 'GAVMSQ',
+    'template':
+        "External function '#{functionName}' cannot have a function body.",
+    'options': ["--output-type=dart"],
+    'howToFix': "Try removing the 'external' modifier or the function body.",
+    'examples': [
+      """
+external foo() => 0;
+main() => foo();
+""",
+      """
+external foo() {}
+main() => foo();
+"""
+    ],
+
+//////////////////////////////////////////////////////////////////////////////
+// Patch errors end.
+//////////////////////////////////////////////////////////////////////////////
+  },
+
+  'EXPERIMENTAL_ASSERT_MESSAGE': {
+    'id': 'NENGIS',
+    'template': "Experimental language feature 'assertion with message'"
+        " is not supported.",
+    'howToFix':
+        "Use option '--assert-message' to use assertions with messages.",
+    'examples': [
+      r'''
+main() {
+int n = -7;
+assert(n > 0, 'must be positive: $n');
+}
+'''
+    ],
+  },
+
+  'IMPORT_EXPERIMENTAL_MIRRORS': {
+    'id': 'SCJYPH',
+    'template': '''
+
+****************************************************************
+* WARNING: dart:mirrors support in dart2js is experimental,
+*          and not recommended.
+*          This implementation of mirrors is incomplete,
+*          and often greatly increases the size of the generated
+*          JavaScript code.
+*
+* Your app imports dart:mirrors via:'''
+        '''
+$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
+*
+* You can disable this message by using the --enable-experimental-mirrors
+* command-line flag.
+*
+* To learn what to do next, please visit:
+*    http://dartlang.org/dart2js-reflection
+****************************************************************
+''',
+  },
+
+  'DISALLOWED_LIBRARY_IMPORT': {
+    'id': 'OCSFJU',
+    'template': '''
+Your app imports the unsupported library '#{uri}' via:
+'''
+        '''
+$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
+
+Use the --categories option to support import of '#{uri}'.
+''',
+  },
+
+  'MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND': {
+    'id': 'JBTRRM',
+    'template': """
+dart:mirrors library is not supported when using this backend.
+
+Your app imports dart:mirrors via:"""
+        """
+$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}""",
+  },
+
+  'CALL_NOT_SUPPORTED_ON_NATIVE_CLASS': {
+    'id': 'HAULDW',
+    'template': "Non-supported 'call' member on a native class, or a "
+        "subclass of a native class.",
+  },
+
+  'DIRECTLY_THROWING_NSM': {
+    'id': 'XLTPCS',
+    'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
+        "exception. The generated code will be smaller if it is "
+        "rewritten.",
+    'howToFix': "Rewrite to "
+        "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
+  },
+
+  'COMPLEX_THROWING_NSM': {
+    'id': 'PLCXVX',
+    'template': "This 'noSuchMethod' implementation is guaranteed to throw an "
+        "exception. The generated code will be smaller and the compiler "
+        "will be able to perform more optimizations if it is rewritten.",
+    'howToFix': "Rewrite to "
+        "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'.",
+  },
+
+  'COMPLEX_RETURNING_NSM': {
+    'id': 'HUTCTQ',
+    'template': "Overriding 'noSuchMethod' causes the compiler to generate "
+        "more code and prevents the compiler from doing some optimizations.",
+    'howToFix': "Consider removing this 'noSuchMethod' implementation."
+  },
+
+  'UNRECOGNIZED_VERSION_OF_LOOKUP_MAP': {
+    'id': 'OVAFEW',
+    'template': "Unsupported version of package:lookup_map.",
+    'howToFix': DONT_KNOW_HOW_TO_FIX
+  },
+};
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 5913cb0..200b63f 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -2,77 +2,15 @@
 // 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.
 
-
-/**
- * The messages in this file should meet the following guide lines:
- *
- * 1. The message should be a complete sentence starting with an uppercase
- * letter, and ending with a period.
- *
- * 2. Reserved words and embedded identifiers should be in single quotes, so
- * prefer double quotes for the complete message. For example, "The
- * class '#{className}' can't use 'super'." Notice that the word 'class' in the
- * preceding message is not quoted as it refers to the concept 'class', not the
- * reserved word. On the other hand, 'super' refers to the reserved word. Do
- * not quote 'null' and numeric literals.
- *
- * 3. Do not try to compose messages, as it can make translating them hard.
- *
- * 4. Try to keep the error messages short, but informative.
- *
- * 5. Use simple words and terminology, assume the reader of the message
- * doesn't have an advanced degree in math, and that English is not the
- * reader's native language. Do not assume any formal computer science
- * training. For example, do not use Latin abbreviations (prefer "that is" over
- * "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
- * only if" and "iff", that level of precision is unnecessary.
- *
- * 6. Prefer contractions when they are in common use, for example, prefer
- * "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
- * off-putting to people new to programming.
- *
- * 7. Use common terminology, preferably from the Dart Language
- * Specification. This increases the user's chance of finding a good
- * explanation on the web.
- *
- * 8. Do not try to be cute or funny. It is extremely frustrating to work on a
- * product that crashes with a "tongue-in-cheek" message, especially if you did
- * not want to use this product to begin with.
- *
- * 9. Do not lie, that is, do not write error messages containing phrases like
- * "can't happen".  If the user ever saw this message, it would be a
- * lie. Prefer messages like: "Internal error: This function should not be
- * called when 'x' is null.".
- *
- * 10. Prefer to not use imperative tone. That is, the message should not sound
- * accusing or like it is ordering the user around. The computer should
- * describe the problem, not criticize for violating the specification.
- *
- * Other things to keep in mind:
- *
- * An INFO message should always be preceded by a non-INFO message, and the
- * INFO messages are additional details about the preceding non-INFO
- * message. For example, consider duplicated elements. First report a WARNING
- * or ERROR about the duplicated element, and then report an INFO about the
- * location of the existing element.
- *
- * Generally, we want to provide messages that consists of three sentences:
- * 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
- * combine the first two in [template] and the last in [howToFix].
- */
-
 library dart2js.messages;
 
-import '../tokens/token.dart' show
-    ErrorToken,
-    Token;
+import '../tokens/token.dart' show ErrorToken, Token;
 
-import 'invariant.dart' show
-    invariant;
-import 'spannable.dart' show
-    CURRENT_ELEMENT_SPANNABLE;
+import 'invariant.dart' show invariant;
+import 'spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
 
-const DONT_KNOW_HOW_TO_FIX = "Computer says no!";
+import 'dart2js_messages.dart' as dart2js_messages;
+import 'shared_messages.dart' as shared_messages;
 
 /// Keys for the [MessageTemplate]s.
 enum MessageKind {
@@ -146,6 +84,7 @@
   CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
   CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
   CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
+  CONST_LOOP_VARIABLE,
   CONST_MAP_KEY_OVERRIDES_EQUALS,
   CONST_WITHOUT_INITIALIZER,
   CONSTRUCTOR_CALL_EXPECTED,
@@ -233,6 +172,7 @@
   IMPORT_BEFORE_PARTS,
   IMPORT_EXPERIMENTAL_MIRRORS,
   IMPORT_PART_OF,
+  IMPORT_PART_OF_HERE,
   IMPORTED_HERE,
   INHERIT_GETTER_AND_METHOD,
   INHERITED_EXPLICIT_GETTER,
@@ -246,7 +186,9 @@
   INTERNAL_LIBRARY,
   INTERNAL_LIBRARY_FROM,
   INVALID_ARGUMENT_AFTER_NAMED,
+  INVALID_AWAIT,
   INVALID_AWAIT_FOR,
+  INVALID_AWAIT_FOR_IN,
   INVALID_BREAK,
   INVALID_CASE_DEFAULT,
   INVALID_CONSTRUCTOR_ARGUMENTS,
@@ -254,6 +196,8 @@
   INVALID_CONTINUE,
   INVALID_FOR_IN,
   INVALID_INITIALIZER,
+  INVALID_METADATA,
+  INVALID_METADATA_GENERIC,
   INVALID_OVERRIDDEN_FIELD,
   INVALID_OVERRIDDEN_GETTER,
   INVALID_OVERRIDDEN_METHOD,
@@ -277,6 +221,7 @@
   INVALID_UNNAMED_CONSTRUCTOR_NAME,
   INVALID_URI,
   INVALID_USE_OF_SUPER,
+  INVALID_YIELD,
   JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
   JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
   JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
@@ -459,6 +404,462 @@
   YIELDING_MODIFIER_ON_ARROW_BODY,
 }
 
+const _KIND_TO_STRING_MAP = const <MessageKind, String>{
+  MessageKind.ABSTRACT_CLASS_INSTANTIATION: "ABSTRACT_CLASS_INSTANTIATION",
+  MessageKind.ABSTRACT_GETTER: "ABSTRACT_GETTER",
+  MessageKind.ABSTRACT_METHOD: "ABSTRACT_METHOD",
+  MessageKind.ABSTRACT_SETTER: "ABSTRACT_SETTER",
+  MessageKind.ACCESSED_IN_CLOSURE: "ACCESSED_IN_CLOSURE",
+  MessageKind.ACCESSED_IN_CLOSURE_HERE: "ACCESSED_IN_CLOSURE_HERE",
+  MessageKind.ADDITIONAL_ARGUMENT: "ADDITIONAL_ARGUMENT",
+  MessageKind.ADDITIONAL_TYPE_ARGUMENT: "ADDITIONAL_TYPE_ARGUMENT",
+  MessageKind.ALREADY_INITIALIZED: "ALREADY_INITIALIZED",
+  MessageKind.AMBIGUOUS_LOCATION: "AMBIGUOUS_LOCATION",
+  MessageKind.AMBIGUOUS_REEXPORT: "AMBIGUOUS_REEXPORT",
+  MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
+      "ASSERT_IS_GIVEN_NAMED_ARGUMENTS",
+  MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER: "ASSIGNING_FINAL_FIELD_IN_SUPER",
+  MessageKind.ASSIGNING_METHOD: "ASSIGNING_METHOD",
+  MessageKind.ASSIGNING_METHOD_IN_SUPER: "ASSIGNING_METHOD_IN_SUPER",
+  MessageKind.ASSIGNING_TYPE: "ASSIGNING_TYPE",
+  MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER: "ASYNC_KEYWORD_AS_IDENTIFIER",
+  MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
+      "ASYNC_MODIFIER_ON_ABSTRACT_METHOD",
+  MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR: "ASYNC_MODIFIER_ON_CONSTRUCTOR",
+  MessageKind.ASYNC_MODIFIER_ON_SETTER: "ASYNC_MODIFIER_ON_SETTER",
+  MessageKind.AWAIT_MEMBER_NOT_FOUND: "AWAIT_MEMBER_NOT_FOUND",
+  MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
+      "AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE",
+  MessageKind.BAD_INPUT_CHARACTER: "BAD_INPUT_CHARACTER",
+  MessageKind.BEFORE_TOP_LEVEL: "BEFORE_TOP_LEVEL",
+  MessageKind.BINARY_OPERATOR_BAD_ARITY: "BINARY_OPERATOR_BAD_ARITY",
+  MessageKind.BODY_EXPECTED: "BODY_EXPECTED",
+  MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
+      "CALL_NOT_SUPPORTED_ON_NATIVE_CLASS",
+  MessageKind.CANNOT_EXTEND: "CANNOT_EXTEND",
+  MessageKind.CANNOT_EXTEND_ENUM: "CANNOT_EXTEND_ENUM",
+  MessageKind.CANNOT_EXTEND_MALFORMED: "CANNOT_EXTEND_MALFORMED",
+  MessageKind.CANNOT_FIND_CONSTRUCTOR: "CANNOT_FIND_CONSTRUCTOR",
+  MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
+      "CANNOT_FIND_UNNAMED_CONSTRUCTOR",
+  MessageKind.CANNOT_IMPLEMENT: "CANNOT_IMPLEMENT",
+  MessageKind.CANNOT_IMPLEMENT_ENUM: "CANNOT_IMPLEMENT_ENUM",
+  MessageKind.CANNOT_IMPLEMENT_MALFORMED: "CANNOT_IMPLEMENT_MALFORMED",
+  MessageKind.CANNOT_INSTANTIATE_ENUM: "CANNOT_INSTANTIATE_ENUM",
+  MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
+      "CANNOT_INSTANTIATE_TYPE_VARIABLE",
+  MessageKind.CANNOT_INSTANTIATE_TYPEDEF: "CANNOT_INSTANTIATE_TYPEDEF",
+  MessageKind.CANNOT_MIXIN: "CANNOT_MIXIN",
+  MessageKind.CANNOT_MIXIN_ENUM: "CANNOT_MIXIN_ENUM",
+  MessageKind.CANNOT_MIXIN_MALFORMED: "CANNOT_MIXIN_MALFORMED",
+  MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
+      "CANNOT_OVERRIDE_FIELD_WITH_METHOD",
+  MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
+      "CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT",
+  MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
+      "CANNOT_OVERRIDE_GETTER_WITH_METHOD",
+  MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
+      "CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
+      "CANNOT_OVERRIDE_METHOD_WITH_FIELD",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
+      "CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
+      "CANNOT_OVERRIDE_METHOD_WITH_GETTER",
+  MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
+      "CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT",
+  MessageKind.CANNOT_RESOLVE: "CANNOT_RESOLVE",
+  MessageKind.CANNOT_RESOLVE_AWAIT: "CANNOT_RESOLVE_AWAIT",
+  MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
+      "CANNOT_RESOLVE_AWAIT_IN_CLOSURE",
+  MessageKind.CANNOT_RESOLVE_CONSTRUCTOR: "CANNOT_RESOLVE_CONSTRUCTOR",
+  MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
+      "CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT",
+  MessageKind.CANNOT_RESOLVE_GETTER: "CANNOT_RESOLVE_GETTER",
+  MessageKind.CANNOT_RESOLVE_IN_INITIALIZER: "CANNOT_RESOLVE_IN_INITIALIZER",
+  MessageKind.CANNOT_RESOLVE_SETTER: "CANNOT_RESOLVE_SETTER",
+  MessageKind.CANNOT_RESOLVE_TYPE: "CANNOT_RESOLVE_TYPE",
+  MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR: "CANNOT_RETURN_FROM_CONSTRUCTOR",
+  MessageKind.CLASS_NAME_EXPECTED: "CLASS_NAME_EXPECTED",
+  MessageKind.COMPILER_CRASHED: "COMPILER_CRASHED",
+  MessageKind.COMPLEX_RETURNING_NSM: "COMPLEX_RETURNING_NSM",
+  MessageKind.COMPLEX_THROWING_NSM: "COMPLEX_THROWING_NSM",
+  MessageKind.CONSIDER_ANALYZE_ALL: "CONSIDER_ANALYZE_ALL",
+  MessageKind.CONST_CALLS_NON_CONST: "CONST_CALLS_NON_CONST",
+  MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
+      "CONST_CALLS_NON_CONST_FOR_IMPLICIT",
+  MessageKind.CONST_CONSTRUCTOR_HAS_BODY: "CONST_CONSTRUCTOR_HAS_BODY",
+  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
+      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS",
+  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
+      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR",
+  MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
+      "CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD",
+  MessageKind.CONST_LOOP_VARIABLE: "CONST_LOOP_VARIABLE",
+  MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS: "CONST_MAP_KEY_OVERRIDES_EQUALS",
+  MessageKind.CONST_WITHOUT_INITIALIZER: "CONST_WITHOUT_INITIALIZER",
+  MessageKind.CONSTRUCTOR_CALL_EXPECTED: "CONSTRUCTOR_CALL_EXPECTED",
+  MessageKind.CONSTRUCTOR_IS_NOT_CONST: "CONSTRUCTOR_IS_NOT_CONST",
+  MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE: "CONSTRUCTOR_WITH_RETURN_TYPE",
+  MessageKind.CYCLIC_CLASS_HIERARCHY: "CYCLIC_CLASS_HIERARCHY",
+  MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS: "CYCLIC_COMPILE_TIME_CONSTANTS",
+  MessageKind.CYCLIC_REDIRECTING_FACTORY: "CYCLIC_REDIRECTING_FACTORY",
+  MessageKind.CYCLIC_TYPE_VARIABLE: "CYCLIC_TYPE_VARIABLE",
+  MessageKind.CYCLIC_TYPEDEF: "CYCLIC_TYPEDEF",
+  MessageKind.CYCLIC_TYPEDEF_ONE: "CYCLIC_TYPEDEF_ONE",
+  MessageKind.DART_EXT_NOT_SUPPORTED: "DART_EXT_NOT_SUPPORTED",
+  MessageKind.DEFERRED_COMPILE_TIME_CONSTANT: "DEFERRED_COMPILE_TIME_CONSTANT",
+  MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
+      "DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION",
+  MessageKind.DEFERRED_LIBRARY_DART_2_DART: "DEFERRED_LIBRARY_DART_2_DART",
+  MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
+      "DEFERRED_LIBRARY_DUPLICATE_PREFIX",
+  MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
+      "DEFERRED_LIBRARY_WITHOUT_PREFIX",
+  MessageKind.DEFERRED_OLD_SYNTAX: "DEFERRED_OLD_SYNTAX",
+  MessageKind.DEFERRED_TYPE_ANNOTATION: "DEFERRED_TYPE_ANNOTATION",
+  MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
+      "DEPRECATED_TYPEDEF_MIXIN_SYNTAX",
+  MessageKind.DIRECTLY_THROWING_NSM: "DIRECTLY_THROWING_NSM",
+  MessageKind.DISALLOWED_LIBRARY_IMPORT: "DISALLOWED_LIBRARY_IMPORT",
+  MessageKind.DUPLICATE_DEFINITION: "DUPLICATE_DEFINITION",
+  MessageKind.DUPLICATE_EXPORT: "DUPLICATE_EXPORT",
+  MessageKind.DUPLICATE_EXPORT_CONT: "DUPLICATE_EXPORT_CONT",
+  MessageKind.DUPLICATE_EXPORT_DECL: "DUPLICATE_EXPORT_DECL",
+  MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS: "DUPLICATE_EXTENDS_IMPLEMENTS",
+  MessageKind.DUPLICATE_IMPLEMENTS: "DUPLICATE_IMPLEMENTS",
+  MessageKind.DUPLICATE_IMPORT: "DUPLICATE_IMPORT",
+  MessageKind.DUPLICATE_INITIALIZER: "DUPLICATE_INITIALIZER",
+  MessageKind.DUPLICATE_LABEL: "DUPLICATE_LABEL",
+  MessageKind.DUPLICATE_SUPER_INITIALIZER: "DUPLICATE_SUPER_INITIALIZER",
+  MessageKind.DUPLICATE_TYPE_VARIABLE_NAME: "DUPLICATE_TYPE_VARIABLE_NAME",
+  MessageKind.DUPLICATED_LIBRARY_NAME: "DUPLICATED_LIBRARY_NAME",
+  MessageKind.DUPLICATED_LIBRARY_RESOURCE: "DUPLICATED_LIBRARY_RESOURCE",
+  MessageKind.DUPLICATED_PART_OF: "DUPLICATED_PART_OF",
+  MessageKind.DUPLICATED_RESOURCE: "DUPLICATED_RESOURCE",
+  MessageKind.EMPTY_CATCH_DECLARATION: "EMPTY_CATCH_DECLARATION",
+  MessageKind.EMPTY_ENUM_DECLARATION: "EMPTY_ENUM_DECLARATION",
+  MessageKind.EMPTY_HIDE: "EMPTY_HIDE",
+  MessageKind.EQUAL_MAP_ENTRY_KEY: "EQUAL_MAP_ENTRY_KEY",
+  MessageKind.EMPTY_SHOW: "EMPTY_SHOW",
+  MessageKind.EXISTING_DEFINITION: "EXISTING_DEFINITION",
+  MessageKind.EXISTING_LABEL: "EXISTING_LABEL",
+  MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
+      "EXPECTED_IDENTIFIER_NOT_RESERVED_WORD",
+  MessageKind.EXPERIMENTAL_ASSERT_MESSAGE: "EXPERIMENTAL_ASSERT_MESSAGE",
+  MessageKind.EXPONENT_MISSING: "EXPONENT_MISSING",
+  MessageKind.EXPORT_BEFORE_PARTS: "EXPORT_BEFORE_PARTS",
+  MessageKind.EXTERNAL_WITH_BODY: "EXTERNAL_WITH_BODY",
+  MessageKind.EXTRA_CATCH_DECLARATION: "EXTRA_CATCH_DECLARATION",
+  MessageKind.EXTRA_FORMALS: "EXTRA_FORMALS",
+  MessageKind.EXTRANEOUS_MODIFIER: "EXTRANEOUS_MODIFIER",
+  MessageKind.EXTRANEOUS_MODIFIER_REPLACE: "EXTRANEOUS_MODIFIER_REPLACE",
+  MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
+      "FACTORY_REDIRECTION_IN_NON_FACTORY",
+  MessageKind.FINAL_FUNCTION_TYPE_PARAMETER: "FINAL_FUNCTION_TYPE_PARAMETER",
+  MessageKind.FINAL_WITHOUT_INITIALIZER: "FINAL_WITHOUT_INITIALIZER",
+  MessageKind.FORIN_NOT_ASSIGNABLE: "FORIN_NOT_ASSIGNABLE",
+  MessageKind.FORMAL_DECLARED_CONST: "FORMAL_DECLARED_CONST",
+  MessageKind.FORMAL_DECLARED_STATIC: "FORMAL_DECLARED_STATIC",
+  MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
+      "FUNCTION_TYPE_FORMAL_WITH_DEFAULT",
+  MessageKind.FUNCTION_WITH_INITIALIZER: "FUNCTION_WITH_INITIALIZER",
+  MessageKind.GENERIC: "GENERIC",
+  MessageKind.GETTER_MISMATCH: "GETTER_MISMATCH",
+  MessageKind.GETTER_NOT_FOUND: "GETTER_NOT_FOUND",
+  MessageKind.HEX_DIGIT_EXPECTED: "HEX_DIGIT_EXPECTED",
+  MessageKind.HIDDEN_HINTS: "HIDDEN_HINTS",
+  MessageKind.HIDDEN_IMPLICIT_IMPORT: "HIDDEN_IMPLICIT_IMPORT",
+  MessageKind.HIDDEN_IMPORT: "HIDDEN_IMPORT",
+  MessageKind.HIDDEN_WARNINGS: "HIDDEN_WARNINGS",
+  MessageKind.HIDDEN_WARNINGS_HINTS: "HIDDEN_WARNINGS_HINTS",
+  MessageKind.IF_NULL_ASSIGNING_TYPE: "IF_NULL_ASSIGNING_TYPE",
+  MessageKind.ILLEGAL_CONST_FIELD_MODIFIER: "ILLEGAL_CONST_FIELD_MODIFIER",
+  MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS: "ILLEGAL_CONSTRUCTOR_MODIFIERS",
+  MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER: "ILLEGAL_FINAL_METHOD_MODIFIER",
+  MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
+      "ILLEGAL_MIXIN_APPLICATION_MODIFIERS",
+  MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR: "ILLEGAL_MIXIN_CONSTRUCTOR",
+  MessageKind.ILLEGAL_MIXIN_CYCLE: "ILLEGAL_MIXIN_CYCLE",
+  MessageKind.ILLEGAL_MIXIN_OBJECT: "ILLEGAL_MIXIN_OBJECT",
+  MessageKind.ILLEGAL_MIXIN_SUPER_USE: "ILLEGAL_MIXIN_SUPER_USE",
+  MessageKind.ILLEGAL_MIXIN_SUPERCLASS: "ILLEGAL_MIXIN_SUPERCLASS",
+  MessageKind.ILLEGAL_MIXIN_WITH_SUPER: "ILLEGAL_MIXIN_WITH_SUPER",
+  MessageKind.ILLEGAL_SETTER_FORMALS: "ILLEGAL_SETTER_FORMALS",
+  MessageKind.ILLEGAL_STATIC: "ILLEGAL_STATIC",
+  MessageKind.ILLEGAL_SUPER_SEND: "ILLEGAL_SUPER_SEND",
+  MessageKind.IMPORT_BEFORE_PARTS: "IMPORT_BEFORE_PARTS",
+  MessageKind.IMPORT_EXPERIMENTAL_MIRRORS: "IMPORT_EXPERIMENTAL_MIRRORS",
+  MessageKind.IMPORT_PART_OF: "IMPORT_PART_OF",
+  MessageKind.IMPORT_PART_OF_HERE: "IMPORT_PART_OF_HERE",
+  MessageKind.IMPORTED_HERE: "IMPORTED_HERE",
+  MessageKind.INHERIT_GETTER_AND_METHOD: "INHERIT_GETTER_AND_METHOD",
+  MessageKind.INHERITED_EXPLICIT_GETTER: "INHERITED_EXPLICIT_GETTER",
+  MessageKind.INHERITED_IMPLICIT_GETTER: "INHERITED_IMPLICIT_GETTER",
+  MessageKind.INHERITED_METHOD: "INHERITED_METHOD",
+  MessageKind.INJECTED_PUBLIC_MEMBER: "INJECTED_PUBLIC_MEMBER",
+  MessageKind.INIT_STATIC_FIELD: "INIT_STATIC_FIELD",
+  MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
+      "INITIALIZING_FORMAL_NOT_ALLOWED",
+  MessageKind.INSTANCE_STATIC_SAME_NAME: "INSTANCE_STATIC_SAME_NAME",
+  MessageKind.INSTANCE_STATIC_SAME_NAME_CONT: "INSTANCE_STATIC_SAME_NAME_CONT",
+  MessageKind.INTERNAL_LIBRARY: "INTERNAL_LIBRARY",
+  MessageKind.INTERNAL_LIBRARY_FROM: "INTERNAL_LIBRARY_FROM",
+  MessageKind.INVALID_ARGUMENT_AFTER_NAMED: "INVALID_ARGUMENT_AFTER_NAMED",
+  MessageKind.INVALID_AWAIT: "INVALID_AWAIT",
+  MessageKind.INVALID_AWAIT_FOR: "INVALID_AWAIT_FOR",
+  MessageKind.INVALID_AWAIT_FOR_IN: "INVALID_AWAIT_FOR_IN",
+  MessageKind.INVALID_BREAK: "INVALID_BREAK",
+  MessageKind.INVALID_CASE_DEFAULT: "INVALID_CASE_DEFAULT",
+  MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS: "INVALID_CONSTRUCTOR_ARGUMENTS",
+  MessageKind.INVALID_CONSTRUCTOR_NAME: "INVALID_CONSTRUCTOR_NAME",
+  MessageKind.INVALID_CONTINUE: "INVALID_CONTINUE",
+  MessageKind.INVALID_FOR_IN: "INVALID_FOR_IN",
+  MessageKind.INVALID_INITIALIZER: "INVALID_INITIALIZER",
+  MessageKind.INVALID_METADATA: "INVALID_METADATA",
+  MessageKind.INVALID_METADATA_GENERIC: "INVALID_METADATA_GENERIC",
+  MessageKind.INVALID_OVERRIDDEN_FIELD: "INVALID_OVERRIDDEN_FIELD",
+  MessageKind.INVALID_OVERRIDDEN_GETTER: "INVALID_OVERRIDDEN_GETTER",
+  MessageKind.INVALID_OVERRIDDEN_METHOD: "INVALID_OVERRIDDEN_METHOD",
+  MessageKind.INVALID_OVERRIDDEN_SETTER: "INVALID_OVERRIDDEN_SETTER",
+  MessageKind.INVALID_OVERRIDE_FIELD: "INVALID_OVERRIDE_FIELD",
+  MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
+      "INVALID_OVERRIDE_FIELD_WITH_GETTER",
+  MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
+      "INVALID_OVERRIDE_FIELD_WITH_SETTER",
+  MessageKind.INVALID_OVERRIDE_GETTER: "INVALID_OVERRIDE_GETTER",
+  MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
+      "INVALID_OVERRIDE_GETTER_WITH_FIELD",
+  MessageKind.INVALID_OVERRIDE_METHOD: "INVALID_OVERRIDE_METHOD",
+  MessageKind.INVALID_OVERRIDE_SETTER: "INVALID_OVERRIDE_SETTER",
+  MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
+      "INVALID_OVERRIDE_SETTER_WITH_FIELD",
+  MessageKind.INVALID_PACKAGE_CONFIG: "INVALID_PACKAGE_CONFIG",
+  MessageKind.INVALID_PACKAGE_URI: "INVALID_PACKAGE_URI",
+  MessageKind.INVALID_PARAMETER: "INVALID_PARAMETER",
+  MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
+      "INVALID_RECEIVER_IN_INITIALIZER",
+  MessageKind.INVALID_SOURCE_FILE_LOCATION: "INVALID_SOURCE_FILE_LOCATION",
+  MessageKind.INVALID_SYMBOL: "INVALID_SYMBOL",
+  MessageKind.INVALID_SYNC_MODIFIER: "INVALID_SYNC_MODIFIER",
+  MessageKind.INVALID_TYPE_VARIABLE_BOUND: "INVALID_TYPE_VARIABLE_BOUND",
+  MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
+      "INVALID_UNNAMED_CONSTRUCTOR_NAME",
+  MessageKind.INVALID_URI: "INVALID_URI",
+  MessageKind.INVALID_USE_OF_SUPER: "INVALID_USE_OF_SUPER",
+  MessageKind.INVALID_YIELD: "INVALID_YIELD",
+  MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
+      "JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS",
+  MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
+      "JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER",
+  MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
+      "JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS",
+  MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
+      "JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS",
+  MessageKind.JS_PLACEHOLDER_CAPTURE: "JS_PLACEHOLDER_CAPTURE",
+  MessageKind.LIBRARY_NAME_MISMATCH: "LIBRARY_NAME_MISMATCH",
+  MessageKind.LIBRARY_NOT_FOUND: "LIBRARY_NOT_FOUND",
+  MessageKind.LIBRARY_NOT_SUPPORTED: "LIBRARY_NOT_SUPPORTED",
+  MessageKind.LIBRARY_TAG_MUST_BE_FIRST: "LIBRARY_TAG_MUST_BE_FIRST",
+  MessageKind.MAIN_NOT_A_FUNCTION: "MAIN_NOT_A_FUNCTION",
+  MessageKind.MAIN_WITH_EXTRA_PARAMETER: "MAIN_WITH_EXTRA_PARAMETER",
+  MessageKind.MALFORMED_STRING_LITERAL: "MALFORMED_STRING_LITERAL",
+  MessageKind.MEMBER_NOT_FOUND: "MEMBER_NOT_FOUND",
+  MessageKind.MEMBER_NOT_STATIC: "MEMBER_NOT_STATIC",
+  MessageKind.MEMBER_USES_CLASS_NAME: "MEMBER_USES_CLASS_NAME",
+  MessageKind.METHOD_NOT_FOUND: "METHOD_NOT_FOUND",
+  MessageKind.MINUS_OPERATOR_BAD_ARITY: "MINUS_OPERATOR_BAD_ARITY",
+  MessageKind.MIRROR_BLOAT: "MIRROR_BLOAT",
+  MessageKind.MIRROR_IMPORT: "MIRROR_IMPORT",
+  MessageKind.MIRROR_IMPORT_NO_USAGE: "MIRROR_IMPORT_NO_USAGE",
+  MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT: "MIRRORS_CANNOT_FIND_IN_ELEMENT",
+  MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
+      "MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY",
+  MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
+      "MIRRORS_CANNOT_RESOLVE_IN_LIBRARY",
+  MessageKind.MIRRORS_EXPECTED_STRING: "MIRRORS_EXPECTED_STRING",
+  MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
+      "MIRRORS_EXPECTED_STRING_OR_LIST",
+  MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
+      "MIRRORS_EXPECTED_STRING_OR_TYPE",
+  MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
+      "MIRRORS_EXPECTED_STRING_TYPE_OR_LIST",
+  MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
+      "MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND",
+  MessageKind.MISSING_ARGUMENT: "MISSING_ARGUMENT",
+  MessageKind.MISSING_ENUM_CASES: "MISSING_ENUM_CASES",
+  MessageKind.MISSING_FACTORY_KEYWORD: "MISSING_FACTORY_KEYWORD",
+  MessageKind.MISSING_FORMALS: "MISSING_FORMALS",
+  MessageKind.MISSING_LIBRARY_NAME: "MISSING_LIBRARY_NAME",
+  MessageKind.MISSING_MAIN: "MISSING_MAIN",
+  MessageKind.MISSING_PART_OF_TAG: "MISSING_PART_OF_TAG",
+  MessageKind.MISSING_TOKEN_AFTER_THIS: "MISSING_TOKEN_AFTER_THIS",
+  MessageKind.MISSING_TOKEN_BEFORE_THIS: "MISSING_TOKEN_BEFORE_THIS",
+  MessageKind.MISSING_TYPE_ARGUMENT: "MISSING_TYPE_ARGUMENT",
+  MessageKind.MULTI_INHERITANCE: "MULTI_INHERITANCE",
+  MessageKind.NAMED_ARGUMENT_NOT_FOUND: "NAMED_ARGUMENT_NOT_FOUND",
+  MessageKind.NAMED_FUNCTION_EXPRESSION: "NAMED_FUNCTION_EXPRESSION",
+  MessageKind.NAMED_PARAMETER_WITH_EQUALS: "NAMED_PARAMETER_WITH_EQUALS",
+  MessageKind.NATIVE_NOT_SUPPORTED: "NATIVE_NOT_SUPPORTED",
+  MessageKind.NO_BREAK_TARGET: "NO_BREAK_TARGET",
+  MessageKind.NO_CATCH_NOR_FINALLY: "NO_CATCH_NOR_FINALLY",
+  MessageKind.NO_COMMON_SUBTYPES: "NO_COMMON_SUBTYPES",
+  MessageKind.NO_CONTINUE_TARGET: "NO_CONTINUE_TARGET",
+  MessageKind.NO_INSTANCE_AVAILABLE: "NO_INSTANCE_AVAILABLE",
+  MessageKind.NO_MATCHING_CONSTRUCTOR: "NO_MATCHING_CONSTRUCTOR",
+  MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
+      "NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT",
+  MessageKind.NO_STATIC_OVERRIDE: "NO_STATIC_OVERRIDE",
+  MessageKind.NO_STATIC_OVERRIDE_CONT: "NO_STATIC_OVERRIDE_CONT",
+  MessageKind.NO_SUCH_LIBRARY_MEMBER: "NO_SUCH_LIBRARY_MEMBER",
+  MessageKind.NO_SUCH_METHOD_IN_NATIVE: "NO_SUCH_METHOD_IN_NATIVE",
+  MessageKind.NO_SUCH_SUPER_MEMBER: "NO_SUCH_SUPER_MEMBER",
+  MessageKind.NO_SUPER_IN_STATIC: "NO_SUPER_IN_STATIC",
+  MessageKind.NO_THIS_AVAILABLE: "NO_THIS_AVAILABLE",
+  MessageKind.NON_CONST_BLOAT: "NON_CONST_BLOAT",
+  MessageKind.NOT_A_COMPILE_TIME_CONSTANT: "NOT_A_COMPILE_TIME_CONSTANT",
+  MessageKind.NOT_A_FIELD: "NOT_A_FIELD",
+  MessageKind.NOT_A_PREFIX: "NOT_A_PREFIX",
+  MessageKind.NOT_A_TYPE: "NOT_A_TYPE",
+  MessageKind.NOT_ASSIGNABLE: "NOT_ASSIGNABLE",
+  MessageKind.NOT_CALLABLE: "NOT_CALLABLE",
+  MessageKind.NOT_INSTANCE_FIELD: "NOT_INSTANCE_FIELD",
+  MessageKind.NOT_MORE_SPECIFIC: "NOT_MORE_SPECIFIC",
+  MessageKind.NOT_MORE_SPECIFIC_SUBTYPE: "NOT_MORE_SPECIFIC_SUBTYPE",
+  MessageKind.NOT_MORE_SPECIFIC_SUGGESTION: "NOT_MORE_SPECIFIC_SUGGESTION",
+  MessageKind.NULL_NOT_ALLOWED: "NULL_NOT_ALLOWED",
+  MessageKind.ONLY_ONE_LIBRARY_TAG: "ONLY_ONE_LIBRARY_TAG",
+  MessageKind.OPERATOR_NAMED_PARAMETERS: "OPERATOR_NAMED_PARAMETERS",
+  MessageKind.OPERATOR_NOT_FOUND: "OPERATOR_NOT_FOUND",
+  MessageKind.OPERATOR_OPTIONAL_PARAMETERS: "OPERATOR_OPTIONAL_PARAMETERS",
+  MessageKind.OPTIONAL_PARAMETER_IN_CATCH: "OPTIONAL_PARAMETER_IN_CATCH",
+  MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE: "OVERRIDE_EQUALS_NOT_HASH_CODE",
+  MessageKind.PARAMETER_NAME_EXPECTED: "PARAMETER_NAME_EXPECTED",
+  MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
+      "PARAMETER_WITH_MODIFIER_IN_CATCH",
+  MessageKind.PARAMETER_WITH_TYPE_IN_CATCH: "PARAMETER_WITH_TYPE_IN_CATCH",
+  MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
+      "PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION",
+  MessageKind.PATCH_NO_GETTER: "PATCH_NO_GETTER",
+  MessageKind.PATCH_NO_SETTER: "PATCH_NO_SETTER",
+  MessageKind.PATCH_NON_CLASS: "PATCH_NON_CLASS",
+  MessageKind.PATCH_NON_CONSTRUCTOR: "PATCH_NON_CONSTRUCTOR",
+  MessageKind.PATCH_NON_EXISTING: "PATCH_NON_EXISTING",
+  MessageKind.PATCH_NON_EXTERNAL: "PATCH_NON_EXTERNAL",
+  MessageKind.PATCH_NON_FUNCTION: "PATCH_NON_FUNCTION",
+  MessageKind.PATCH_NON_GETTER: "PATCH_NON_GETTER",
+  MessageKind.PATCH_NON_SETTER: "PATCH_NON_SETTER",
+  MessageKind.PATCH_NONPATCHABLE: "PATCH_NONPATCHABLE",
+  MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
+      "PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH",
+  MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
+      "PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH",
+  MessageKind.PATCH_PARAMETER_MISMATCH: "PATCH_PARAMETER_MISMATCH",
+  MessageKind.PATCH_PARAMETER_TYPE_MISMATCH: "PATCH_PARAMETER_TYPE_MISMATCH",
+  MessageKind.PATCH_POINT_TO_CLASS: "PATCH_POINT_TO_CLASS",
+  MessageKind.PATCH_POINT_TO_CONSTRUCTOR: "PATCH_POINT_TO_CONSTRUCTOR",
+  MessageKind.PATCH_POINT_TO_FUNCTION: "PATCH_POINT_TO_FUNCTION",
+  MessageKind.PATCH_POINT_TO_GETTER: "PATCH_POINT_TO_GETTER",
+  MessageKind.PATCH_POINT_TO_PARAMETER: "PATCH_POINT_TO_PARAMETER",
+  MessageKind.PATCH_POINT_TO_SETTER: "PATCH_POINT_TO_SETTER",
+  MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
+      "PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH",
+  MessageKind.PATCH_RETURN_TYPE_MISMATCH: "PATCH_RETURN_TYPE_MISMATCH",
+  MessageKind.PLEASE_REPORT_THE_CRASH: "PLEASE_REPORT_THE_CRASH",
+  MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
+      "POSITIONAL_PARAMETER_WITH_EQUALS",
+  MessageKind.POTENTIAL_MUTATION: "POTENTIAL_MUTATION",
+  MessageKind.POTENTIAL_MUTATION_HERE: "POTENTIAL_MUTATION_HERE",
+  MessageKind.POTENTIAL_MUTATION_IN_CLOSURE: "POTENTIAL_MUTATION_IN_CLOSURE",
+  MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
+      "POTENTIAL_MUTATION_IN_CLOSURE_HERE",
+  MessageKind.PREAMBLE: "PREAMBLE",
+  MessageKind.PREFIX_AS_EXPRESSION: "PREFIX_AS_EXPRESSION",
+  MessageKind.PRIVATE_ACCESS: "PRIVATE_ACCESS",
+  MessageKind.PRIVATE_IDENTIFIER: "PRIVATE_IDENTIFIER",
+  MessageKind.PRIVATE_NAMED_PARAMETER: "PRIVATE_NAMED_PARAMETER",
+  MessageKind.READ_SCRIPT_ERROR: "READ_SCRIPT_ERROR",
+  MessageKind.READ_SELF_ERROR: "READ_SELF_ERROR",
+  MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE: "REDIRECTING_CONSTRUCTOR_CYCLE",
+  MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
+      "REDIRECTING_CONSTRUCTOR_HAS_BODY",
+  MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
+      "REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER",
+  MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
+      "REDIRECTING_FACTORY_WITH_DEFAULT",
+  MessageKind.REFERENCE_IN_INITIALIZATION: "REFERENCE_IN_INITIALIZATION",
+  MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
+      "REQUIRED_PARAMETER_WITH_DEFAULT",
+  MessageKind.RETURN_IN_GENERATOR: "RETURN_IN_GENERATOR",
+  MessageKind.RETURN_NOTHING: "RETURN_NOTHING",
+  MessageKind.RETURN_VALUE_IN_VOID: "RETURN_VALUE_IN_VOID",
+  MessageKind.SETTER_MISMATCH: "SETTER_MISMATCH",
+  MessageKind.SETTER_NOT_FOUND: "SETTER_NOT_FOUND",
+  MessageKind.SETTER_NOT_FOUND_IN_SUPER: "SETTER_NOT_FOUND_IN_SUPER",
+  MessageKind.STATIC_FUNCTION_BLOAT: "STATIC_FUNCTION_BLOAT",
+  MessageKind.STRING_EXPECTED: "STRING_EXPECTED",
+  MessageKind.SUPER_CALL_TO_FACTORY: "SUPER_CALL_TO_FACTORY",
+  MessageKind.SUPER_INITIALIZER_IN_OBJECT: "SUPER_INITIALIZER_IN_OBJECT",
+  MessageKind.SWITCH_CASE_FORBIDDEN: "SWITCH_CASE_FORBIDDEN",
+  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL: "SWITCH_CASE_TYPES_NOT_EQUAL",
+  MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
+      "SWITCH_CASE_TYPES_NOT_EQUAL_CASE",
+  MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
+      "SWITCH_CASE_VALUE_OVERRIDES_EQUALS",
+  MessageKind.TERNARY_OPERATOR_BAD_ARITY: "TERNARY_OPERATOR_BAD_ARITY",
+  MessageKind.THIS_CALL_TO_FACTORY: "THIS_CALL_TO_FACTORY",
+  MessageKind.THIS_IS_THE_DECLARATION: "THIS_IS_THE_DECLARATION",
+  MessageKind.THIS_IS_THE_METHOD: "THIS_IS_THE_METHOD",
+  MessageKind.THIS_IS_THE_PART_OF_TAG: "THIS_IS_THE_PART_OF_TAG",
+  MessageKind.THIS_PROPERTY: "THIS_PROPERTY",
+  MessageKind.THROW_WITHOUT_EXPRESSION: "THROW_WITHOUT_EXPRESSION",
+  MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
+      "TOP_LEVEL_VARIABLE_DECLARED_STATIC",
+  MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH: "TYPE_ARGUMENT_COUNT_MISMATCH",
+  MessageKind.TYPE_VARIABLE_IN_CONSTANT: "TYPE_VARIABLE_IN_CONSTANT",
+  MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
+      "TYPE_VARIABLE_WITHIN_STATIC_MEMBER",
+  MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT: "TYPEDEF_FORMAL_WITH_DEFAULT",
+  MessageKind.UNARY_OPERATOR_BAD_ARITY: "UNARY_OPERATOR_BAD_ARITY",
+  MessageKind.UNBOUND_LABEL: "UNBOUND_LABEL",
+  MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER: "UNIMPLEMENTED_EXPLICIT_GETTER",
+  MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER: "UNIMPLEMENTED_EXPLICIT_SETTER",
+  MessageKind.UNIMPLEMENTED_GETTER: "UNIMPLEMENTED_GETTER",
+  MessageKind.UNIMPLEMENTED_GETTER_ONE: "UNIMPLEMENTED_GETTER_ONE",
+  MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER: "UNIMPLEMENTED_IMPLICIT_GETTER",
+  MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER: "UNIMPLEMENTED_IMPLICIT_SETTER",
+  MessageKind.UNIMPLEMENTED_METHOD: "UNIMPLEMENTED_METHOD",
+  MessageKind.UNIMPLEMENTED_METHOD_CONT: "UNIMPLEMENTED_METHOD_CONT",
+  MessageKind.UNIMPLEMENTED_METHOD_ONE: "UNIMPLEMENTED_METHOD_ONE",
+  MessageKind.UNIMPLEMENTED_SETTER: "UNIMPLEMENTED_SETTER",
+  MessageKind.UNIMPLEMENTED_SETTER_ONE: "UNIMPLEMENTED_SETTER_ONE",
+  MessageKind.UNMATCHED_TOKEN: "UNMATCHED_TOKEN",
+  MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
+      "UNRECOGNIZED_VERSION_OF_LOOKUP_MAP",
+  MessageKind.UNSUPPORTED_BANG_EQ_EQ: "UNSUPPORTED_BANG_EQ_EQ",
+  MessageKind.UNSUPPORTED_EQ_EQ_EQ: "UNSUPPORTED_EQ_EQ_EQ",
+  MessageKind.UNSUPPORTED_LITERAL_SYMBOL: "UNSUPPORTED_LITERAL_SYMBOL",
+  MessageKind.UNSUPPORTED_PREFIX_PLUS: "UNSUPPORTED_PREFIX_PLUS",
+  MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP: "UNSUPPORTED_THROW_WITHOUT_EXP",
+  MessageKind.UNTERMINATED_COMMENT: "UNTERMINATED_COMMENT",
+  MessageKind.UNTERMINATED_STRING: "UNTERMINATED_STRING",
+  MessageKind.UNTERMINATED_TOKEN: "UNTERMINATED_TOKEN",
+  MessageKind.UNUSED_CLASS: "UNUSED_CLASS",
+  MessageKind.UNUSED_LABEL: "UNUSED_LABEL",
+  MessageKind.UNUSED_METHOD: "UNUSED_METHOD",
+  MessageKind.UNUSED_TYPEDEF: "UNUSED_TYPEDEF",
+  MessageKind.VAR_FUNCTION_TYPE_PARAMETER: "VAR_FUNCTION_TYPE_PARAMETER",
+  MessageKind.VOID_EXPRESSION: "VOID_EXPRESSION",
+  MessageKind.VOID_NOT_ALLOWED: "VOID_NOT_ALLOWED",
+  MessageKind.VOID_VARIABLE: "VOID_VARIABLE",
+  MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
+      "WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT",
+  MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
+      "WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT",
+  MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
+      "YIELDING_MODIFIER_ON_ARROW_BODY",
+};
+
 /// A message template for an error, warning, hint or info message generated
 /// by the compiler. Each template is associated with a [MessageKind] that
 /// uniquely identifies the message template.
@@ -467,6 +868,8 @@
 class MessageTemplate {
   final MessageKind kind;
 
+  final String id;
+
   /// Should describe what is wrong and why.
   final String template;
 
@@ -486,3090 +889,8 @@
   /// Additional options needed for the examples to work.
   final List<String> options;
 
-  const MessageTemplate(
-      this.kind,
-      this.template,
-      {this.howToFix,
-       this.examples,
-       this.options: const <String>[]});
-
-  /// All templates used by the compiler.
-  ///
-  /// The map is complete mapping from [MessageKind] to their corresponding
-  /// [MessageTemplate].
-  static const Map<MessageKind, MessageTemplate> TEMPLATES =
-    const <MessageKind, MessageTemplate>{
-      /// Do not use this. It is here for legacy and debugging. It violates item
-      /// 4 of the guide lines for error messages in the beginning of the file.
-      MessageKind.GENERIC:
-        const MessageTemplate(MessageKind.GENERIC, '#{text}'),
-
-      MessageKind.NOT_ASSIGNABLE:
-        const MessageTemplate(MessageKind.NOT_ASSIGNABLE,
-          "'#{fromType}' is not assignable to '#{toType}'."),
-
-      MessageKind.FORIN_NOT_ASSIGNABLE:
-        const MessageTemplate(MessageKind.FORIN_NOT_ASSIGNABLE,
-          "The element type '#{currentType}' of '#{expressionType}' "
-          "is not assignable to '#{elementType}'."),
-
-      MessageKind.VOID_EXPRESSION:
-        const MessageTemplate(MessageKind.VOID_EXPRESSION,
-          "Expression does not yield a value."),
-
-      MessageKind.VOID_VARIABLE:
-        const MessageTemplate(MessageKind.VOID_VARIABLE,
-          "Variable cannot be of type void."),
-
-      MessageKind.RETURN_VALUE_IN_VOID:
-        const MessageTemplate(MessageKind.RETURN_VALUE_IN_VOID,
-          "Cannot return value from void function."),
-
-      MessageKind.RETURN_NOTHING:
-        const MessageTemplate(MessageKind.RETURN_NOTHING,
-          "Value of type '#{returnType}' expected."),
-
-      MessageKind.MISSING_ARGUMENT:
-        const MessageTemplate(MessageKind.MISSING_ARGUMENT,
-          "Missing argument of type '#{argumentType}'."),
-
-      MessageKind.ADDITIONAL_ARGUMENT:
-        const MessageTemplate(MessageKind.ADDITIONAL_ARGUMENT,
-          "Additional argument."),
-
-      MessageKind.NAMED_ARGUMENT_NOT_FOUND:
-        const MessageTemplate(MessageKind.NAMED_ARGUMENT_NOT_FOUND,
-          "No named argument '#{argumentName}' found on method."),
-
-      MessageKind.MEMBER_NOT_FOUND:
-        const MessageTemplate(MessageKind.MEMBER_NOT_FOUND,
-          "No member named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.AWAIT_MEMBER_NOT_FOUND:
-        const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND,
-          "No member named 'await' in class '#{className}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to '#{functionName}'?",
-          examples: const ["""
-class A {
-  m() => await -3;
-}
-main() => new A().m();
-"""]),
-
-      MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE:
-        const MessageTemplate(MessageKind.AWAIT_MEMBER_NOT_FOUND_IN_CLOSURE,
-          "No member named 'await' in class '#{className}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to the enclosing function?",
-          examples: const ["""
-class A {
-  m() => () => await -3;
-}
-main() => new A().m();
-"""]),
-
-      MessageKind.METHOD_NOT_FOUND:
-        const MessageTemplate(MessageKind.METHOD_NOT_FOUND,
-          "No method named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.OPERATOR_NOT_FOUND:
-        const MessageTemplate(MessageKind.OPERATOR_NOT_FOUND,
-          "No operator '#{memberName}' in class '#{className}'."),
-
-      MessageKind.SETTER_NOT_FOUND:
-        const MessageTemplate(MessageKind.SETTER_NOT_FOUND,
-          "No setter named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.SETTER_NOT_FOUND_IN_SUPER:
-        const MessageTemplate(MessageKind.SETTER_NOT_FOUND_IN_SUPER,
-          "No setter named '#{name}' in superclass of '#{className}'."),
-
-      MessageKind.GETTER_NOT_FOUND:
-        const MessageTemplate(MessageKind.GETTER_NOT_FOUND,
-          "No getter named '#{memberName}' in class '#{className}'."),
-
-      MessageKind.NOT_CALLABLE:
-        const MessageTemplate(MessageKind.NOT_CALLABLE,
-          "'#{elementName}' is not callable."),
-
-      MessageKind.MEMBER_NOT_STATIC:
-        const MessageTemplate(MessageKind.MEMBER_NOT_STATIC,
-          "'#{className}.#{memberName}' is not static."),
-
-      MessageKind.NO_INSTANCE_AVAILABLE:
-        const MessageTemplate(MessageKind.NO_INSTANCE_AVAILABLE,
-          "'#{name}' is only available in instance methods."),
-
-      MessageKind.NO_THIS_AVAILABLE:
-        const MessageTemplate(MessageKind.NO_THIS_AVAILABLE,
-          "'this' is only available in instance methods."),
-
-      MessageKind.PRIVATE_ACCESS:
-        const MessageTemplate(MessageKind.PRIVATE_ACCESS,
-          "'#{name}' is declared private within library "
-          "'#{libraryName}'."),
-
-      MessageKind.THIS_IS_THE_DECLARATION:
-        const MessageTemplate(MessageKind.THIS_IS_THE_DECLARATION,
-          "This is the declaration of '#{name}'."),
-
-      MessageKind.THIS_IS_THE_METHOD:
-        const MessageTemplate(MessageKind.THIS_IS_THE_METHOD,
-          "This is the method declaration."),
-
-      MessageKind.CANNOT_RESOLVE:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE,
-          "Cannot resolve '#{name}'."),
-
-      MessageKind.CANNOT_RESOLVE_AWAIT:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT,
-          "Cannot resolve '#{name}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to '#{functionName}'?",
-          examples: const [
-              "main() => await -3;",
-              "foo() => await -3; main() => foo();"
-          ]),
-
-      MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_AWAIT_IN_CLOSURE,
-          "Cannot resolve '#{name}'.",
-          howToFix: "Did you mean to add the 'async' marker "
-                    "to the enclosing function?",
-          examples: const [
-              "main() { (() => await -3)(); }",
-          ]),
-
-      MessageKind.CANNOT_RESOLVE_IN_INITIALIZER:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_IN_INITIALIZER,
-          "Cannot resolve '#{name}'. It would be implicitly looked up on this "
-          "instance, but instances are not available in initializers.",
-          howToFix: "Try correcting the unresolved reference or move the "
-              "initialization to a constructor body.",
-          examples: const ["""
-class A {
-  var test = unresolvedName;
-}
-main() => new A();
-"""]),
-
-      MessageKind.CANNOT_RESOLVE_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_CONSTRUCTOR,
-          "Cannot resolve constructor '#{constructorName}'."),
-
-      MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT:
-        const MessageTemplate(
-          MessageKind.CANNOT_RESOLVE_CONSTRUCTOR_FOR_IMPLICIT,
-          "cannot resolve constructor '#{constructorName}' "
-          "for implicit super call.",
-          howToFix: "Try explicitly invoking a constructor of the super class",
-          examples: const ["""
-class A {
-  A.foo() {}
-}
-class B extends A {
-  B();
-}
-main() => new B();
-"""]),
-
-      MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME:
-        const MessageTemplate(MessageKind.INVALID_UNNAMED_CONSTRUCTOR_NAME,
-          "Unnamed constructor name must be '#{name}'."),
-
-      MessageKind.INVALID_CONSTRUCTOR_NAME:
-        const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_NAME,
-          "Constructor name must start with '#{name}'."),
-
-      MessageKind.CANNOT_RESOLVE_TYPE:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_TYPE,
-          "Cannot resolve type '#{typeName}'."),
-
-      MessageKind.DUPLICATE_DEFINITION:
-        const MessageTemplate(MessageKind.DUPLICATE_DEFINITION,
-          "Duplicate definition of '#{name}'.",
-          howToFix: "Try to rename or remove this definition.",
-          examples: const ["""
-class C {
-  void f() {}
-  int get f => 1;
-}
-
-main() {
-  new C();
-}
-
-"""]),
-
-      MessageKind.EXISTING_DEFINITION:
-        const MessageTemplate(MessageKind.EXISTING_DEFINITION,
-          "Existing definition of '#{name}'."),
-
-      MessageKind.DUPLICATE_IMPORT:
-        const MessageTemplate(MessageKind.DUPLICATE_IMPORT,
-          "Duplicate import of '#{name}'."),
-
-      MessageKind.HIDDEN_IMPORT:
-        const MessageTemplate(MessageKind.HIDDEN_IMPORT,
-          "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
-          "from library '#{hidingUri}'.",
-          howToFix:
-            "Try adding 'hide #{name}' to the import of '#{hiddenUri}'.",
-          examples: const [
-              const {
-'main.dart':
-"""
-import 'dart:async'; // This imports a class Future.
-import 'future.dart';
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""},
-
-          const {
-'main.dart':
-"""
-import 'future.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""},
-
-          const {
-'main.dart':
-"""
-import 'export.dart';
-import 'dart:async'; // This imports a class Future.
-
-void main() => new Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}""",
-
-'export.dart':
-"""
-library export;
-
-export 'future.dart';"""},
-
-         const {
-'main.dart':
-"""
-import 'future.dart' as prefix;
-import 'dart:async' as prefix; // This imports a class Future.
-
-void main() => new prefix.Future();""",
-
-'future.dart':
-"""
-library future;
-
-class Future {}"""}]),
-
-
-      MessageKind.HIDDEN_IMPLICIT_IMPORT:
-        const MessageTemplate(MessageKind.HIDDEN_IMPLICIT_IMPORT,
-          "'#{name}' from library '#{hiddenUri}' is hidden by '#{name}' "
-          "from library '#{hidingUri}'.",
-          howToFix: "Try adding an explicit "
-                    "'import \"#{hiddenUri}\" hide #{name}'.",
-          examples: const [
-              const {
-'main.dart':
-"""
-// This hides the implicit import of class Type from dart:core.
-import 'type.dart';
-
-void main() => new Type();""",
-
-'type.dart':
-"""
-library type;
-
-class Type {}"""},
-          const {
-'conflictsWithDart.dart':
-"""
-library conflictsWithDart;
-
-class Duration {
-  static var x = 100;
-}
-""",
-
-'conflictsWithDartAsWell.dart':
-"""
-library conflictsWithDartAsWell;
-
-class Duration {
-  static var x = 100;
-}
-""",
-
-'main.dart':
-r"""
-library testDartConflicts;
-
-import 'conflictsWithDart.dart';
-import 'conflictsWithDartAsWell.dart';
-
-main() {
-  print("Hail Caesar ${Duration.x}");
-}
-"""}]),
-
-      MessageKind.DUPLICATE_EXPORT:
-        const MessageTemplate(MessageKind.DUPLICATE_EXPORT,
-          "Duplicate export of '#{name}'.",
-          howToFix: "Try adding 'hide #{name}' to one of the exports.",
-          examples: const [const {
-'main.dart': """
-export 'decl1.dart';
-export 'decl2.dart';
-
-main() {}""",
-'decl1.dart': "class Class {}",
-'decl2.dart': "class Class {}"}]),
-
-      MessageKind.DUPLICATE_EXPORT_CONT:
-        const MessageTemplate(MessageKind.DUPLICATE_EXPORT_CONT,
-          "This is another export of '#{name}'."),
-
-      MessageKind.DUPLICATE_EXPORT_DECL:
-        const MessageTemplate(MessageKind.DUPLICATE_EXPORT_DECL,
-          "The exported '#{name}' from export #{uriString} is defined here."),
-
-      MessageKind.EMPTY_HIDE:
-        const MessageTemplate(MessageKind.EMPTY_HIDE,
-            "Library '#{uri}' doesn't export a '#{name}' declaration.",
-      howToFix: "Try removing '#{name}' the 'hide' clause.",
-      examples: const [
-        const {
-            'main.dart': """
-import 'dart:core' hide Foo;
-
-main() {}"""},
-        const {
-'main.dart': """
-export 'dart:core' hide Foo;
-
-main() {}"""},
-]),
-
-      MessageKind.EMPTY_SHOW:
-        const MessageTemplate(MessageKind.EMPTY_SHOW,
-            "Library '#{uri}' doesn't export a '#{name}' declaration.",
-      howToFix: "Try removing '#{name}' from the 'show' clause.",
-      examples: const [
-        const {
-            'main.dart': """
-import 'dart:core' show Foo;
-
-main() {}"""},
-        const {
-'main.dart': """
-export 'dart:core' show Foo;
-
-main() {}"""},
-]),
-
-      MessageKind.NOT_A_TYPE:
-        const MessageTemplate(MessageKind.NOT_A_TYPE,
-          "'#{node}' is not a type."),
-
-      MessageKind.NOT_A_PREFIX:
-        const MessageTemplate(MessageKind.NOT_A_PREFIX,
-          "'#{node}' is not a prefix."),
-
-      MessageKind.PREFIX_AS_EXPRESSION:
-        const MessageTemplate(MessageKind.PREFIX_AS_EXPRESSION,
-          "Library prefix '#{prefix}' is not a valid expression."),
-
-      MessageKind.CANNOT_FIND_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_FIND_CONSTRUCTOR,
-          "Cannot find constructor '#{constructorName}' in class "
-          "'#{className}'."),
-
-      MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_FIND_UNNAMED_CONSTRUCTOR,
-          "Cannot find unnamed constructor in class "
-          "'#{className}'."),
-
-      MessageKind.CYCLIC_CLASS_HIERARCHY:
-        const MessageTemplate(MessageKind.CYCLIC_CLASS_HIERARCHY,
-          "'#{className}' creates a cycle in the class hierarchy."),
-
-      MessageKind.CYCLIC_REDIRECTING_FACTORY:
-        const MessageTemplate(MessageKind.CYCLIC_REDIRECTING_FACTORY,
-          'Redirecting factory leads to a cyclic redirection.'),
-
-      MessageKind.INVALID_RECEIVER_IN_INITIALIZER:
-        const MessageTemplate(MessageKind.INVALID_RECEIVER_IN_INITIALIZER,
-          "Field initializer expected."),
-
-      MessageKind.NO_SUPER_IN_STATIC:
-        const MessageTemplate(MessageKind.NO_SUPER_IN_STATIC,
-          "'super' is only available in instance methods."),
-
-      MessageKind.DUPLICATE_INITIALIZER:
-        const MessageTemplate(MessageKind.DUPLICATE_INITIALIZER,
-          "Field '#{fieldName}' is initialized more than once."),
-
-      MessageKind.ALREADY_INITIALIZED:
-        const MessageTemplate(MessageKind.ALREADY_INITIALIZED,
-          "'#{fieldName}' was already initialized here."),
-
-      MessageKind.INIT_STATIC_FIELD:
-        const MessageTemplate(MessageKind.INIT_STATIC_FIELD,
-          "Cannot initialize static field '#{fieldName}'."),
-
-      MessageKind.NOT_A_FIELD:
-        const MessageTemplate(MessageKind.NOT_A_FIELD,
-          "'#{fieldName}' is not a field."),
-
-      MessageKind.CONSTRUCTOR_CALL_EXPECTED:
-        const MessageTemplate(MessageKind.CONSTRUCTOR_CALL_EXPECTED,
-          "only call to 'this' or 'super' constructor allowed."),
-
-      MessageKind.INVALID_FOR_IN:
-        const MessageTemplate(MessageKind.INVALID_FOR_IN,
-          "Invalid for-in variable declaration."),
-
-      MessageKind.INVALID_INITIALIZER:
-        const MessageTemplate(MessageKind.INVALID_INITIALIZER,
-          "Invalid initializer."),
-
-      MessageKind.FUNCTION_WITH_INITIALIZER:
-        const MessageTemplate(MessageKind.FUNCTION_WITH_INITIALIZER,
-          "Only constructors can have initializers."),
-
-      MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE:
-        const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_CYCLE,
-          "Cyclic constructor redirection."),
-
-      MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY:
-        const MessageTemplate(MessageKind.REDIRECTING_CONSTRUCTOR_HAS_BODY,
-          "Redirecting constructor can't have a body."),
-
-      MessageKind.CONST_CONSTRUCTOR_HAS_BODY:
-        const MessageTemplate(MessageKind.CONST_CONSTRUCTOR_HAS_BODY,
-          "Const constructor or factory can't have a body.",
-          howToFix: "Remove the 'const' keyword or the body",
-          examples: const ["""
-class C {
-  const C() {}
-}
-
-main() => new C();"""]),
-
-      MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER:
-        const MessageTemplate(
-          MessageKind.REDIRECTING_CONSTRUCTOR_HAS_INITIALIZER,
-          "Redirecting constructor cannot have other initializers."),
-
-      MessageKind.SUPER_INITIALIZER_IN_OBJECT:
-        const MessageTemplate(MessageKind.SUPER_INITIALIZER_IN_OBJECT,
-          "'Object' cannot have a super initializer."),
-
-      MessageKind.DUPLICATE_SUPER_INITIALIZER:
-        const MessageTemplate(MessageKind.DUPLICATE_SUPER_INITIALIZER,
-          "Cannot have more than one super initializer."),
-
-      MessageKind.SUPER_CALL_TO_FACTORY:
-        const MessageTemplate(MessageKind.SUPER_CALL_TO_FACTORY,
-          "The target of the superinitializer must be a generative "
-          "constructor.",
-          howToFix: "Try calling another constructor on the superclass.",
-          examples: const ["""
-class Super {
-  factory Super() => null;
-}
-class Class extends Super {}
-main() => new Class();
-""", """
-class Super {
-  factory Super() => null;
-}
-class Class extends Super {
-  Class();
-}
-main() => new Class();
-""", """
-class Super {
-  factory Super() => null;
-}
-class Class extends Super {
-  Class() : super();
-}
-main() => new Class();
-""", """
-class Super {
-  factory Super.foo() => null;
-}
-class Class extends Super {
-  Class() : super.foo();
-}
-main() => new Class();
-"""]),
-
-      MessageKind.THIS_CALL_TO_FACTORY:
-        const MessageTemplate(MessageKind.THIS_CALL_TO_FACTORY,
-          "The target of the redirection clause must be a generative "
-          "constructor",
-        howToFix: "Try redirecting to another constructor.",
-        examples: const ["""
-class Class {
-  factory Class() => null;
-  Class.foo() : this();
-}
-main() => new Class.foo();
-""", """
-class Class {
-  factory Class.foo() => null;
-  Class() : this.foo();
-}
-main() => new Class();
-"""]),
-
-      MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS:
-        const MessageTemplate(MessageKind.INVALID_CONSTRUCTOR_ARGUMENTS,
-          "Arguments do not match the expected parameters of constructor "
-          "'#{constructorName}'."),
-
-      MessageKind.NO_MATCHING_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR,
-          "'super' call arguments and constructor parameters do not match."),
-
-      MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT:
-        const MessageTemplate(MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT,
-              "Implicit 'super' call arguments and constructor parameters "
-              "do not match."),
-
-      MessageKind.CONST_CALLS_NON_CONST:
-        const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST,
-          "'const' constructor cannot call a non-const constructor."),
-
-      MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT:
-        const MessageTemplate(MessageKind.CONST_CALLS_NON_CONST_FOR_IMPLICIT,
-              "'const' constructor cannot call a non-const constructor. "
-              "This constructor has an implicit call to a "
-              "super non-const constructor.",
-              howToFix: "Try making the super constructor const.",
-              examples: const ["""
-class C {
-  C(); // missing const
-}
-class D extends C {
-  final d;
-  const D(this.d);
-}
-main() => new D(0);"""]),
-
-      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS:
-        const MessageTemplate(
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS,
-          "Can't declare constructor 'const' on class #{className} "
-          "because the class contains non-final instance fields.",
-          howToFix: "Try making all fields final.",
-          examples: const ["""
-class C {
-  // 'a' must be declared final to allow for the const constructor.
-  var a;
-  const C(this.a);
-}
-
-main() => new C(0);"""]),
-
-      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD:
-        const MessageTemplate(
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_FIELD,
-          "This non-final field prevents using const constructors."),
-
-      MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR:
-        const MessageTemplate(
-          MessageKind.CONST_CONSTRUCTOR_WITH_NONFINAL_FIELDS_CONSTRUCTOR,
-          "This const constructor is not allowed due to "
-          "non-final fields."),
-
-
-      MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED:
-        const MessageTemplate(MessageKind.INITIALIZING_FORMAL_NOT_ALLOWED,
-          "Initializing formal parameter only allowed in generative "
-          "constructor."),
-
-      MessageKind.INVALID_PARAMETER:
-        const MessageTemplate(MessageKind.INVALID_PARAMETER,
-          "Cannot resolve parameter."),
-
-      MessageKind.NOT_INSTANCE_FIELD:
-        const MessageTemplate(MessageKind.NOT_INSTANCE_FIELD,
-          "'#{fieldName}' is not an instance field."),
-
-      MessageKind.THIS_PROPERTY:
-        const MessageTemplate(MessageKind.THIS_PROPERTY,
-          "Expected an identifier."),
-
-      MessageKind.NO_CATCH_NOR_FINALLY:
-        const MessageTemplate(MessageKind.NO_CATCH_NOR_FINALLY,
-          "Expected 'catch' or 'finally'."),
-
-      MessageKind.EMPTY_CATCH_DECLARATION:
-        const MessageTemplate(MessageKind.EMPTY_CATCH_DECLARATION,
-          "Expected an identifier in catch declaration."),
-
-      MessageKind.EXTRA_CATCH_DECLARATION:
-        const MessageTemplate(MessageKind.EXTRA_CATCH_DECLARATION,
-          "Extra parameter in catch declaration."),
-
-      MessageKind.PARAMETER_WITH_TYPE_IN_CATCH:
-        const MessageTemplate(MessageKind.PARAMETER_WITH_TYPE_IN_CATCH,
-          "Cannot use type annotations in catch."),
-
-      MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH:
-        const MessageTemplate(MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH,
-          "Cannot use modifiers in catch."),
-
-      MessageKind.OPTIONAL_PARAMETER_IN_CATCH:
-        const MessageTemplate(MessageKind.OPTIONAL_PARAMETER_IN_CATCH,
-          "Cannot use optional parameters in catch."),
-
-      MessageKind.THROW_WITHOUT_EXPRESSION:
-        const MessageTemplate(MessageKind.THROW_WITHOUT_EXPRESSION,
-          "Cannot use re-throw outside of catch block "
-          "(expression expected after 'throw')."),
-
-      MessageKind.UNBOUND_LABEL:
-        const MessageTemplate(MessageKind.UNBOUND_LABEL,
-          "Cannot resolve label '#{labelName}'."),
-
-      MessageKind.NO_BREAK_TARGET:
-        const MessageTemplate(MessageKind.NO_BREAK_TARGET,
-          "'break' statement not inside switch or loop."),
-
-      MessageKind.NO_CONTINUE_TARGET:
-        const MessageTemplate(MessageKind.NO_CONTINUE_TARGET,
-          "'continue' statement not inside loop."),
-
-      MessageKind.EXISTING_LABEL:
-        const MessageTemplate(MessageKind.EXISTING_LABEL,
-          "Original declaration of duplicate label '#{labelName}'."),
-
-      MessageKind.DUPLICATE_LABEL:
-        const MessageTemplate(MessageKind.DUPLICATE_LABEL,
-          "Duplicate declaration of label '#{labelName}'."),
-
-      MessageKind.UNUSED_LABEL:
-        const MessageTemplate(MessageKind.UNUSED_LABEL,
-          "Unused label '#{labelName}'."),
-
-      MessageKind.INVALID_CONTINUE:
-        const MessageTemplate(MessageKind.INVALID_CONTINUE,
-          "Target of continue is not a loop or switch case."),
-
-      MessageKind.INVALID_BREAK:
-        const MessageTemplate(MessageKind.INVALID_BREAK,
-          "Target of break is not a statement."),
-
-      MessageKind.DUPLICATE_TYPE_VARIABLE_NAME:
-        const MessageTemplate(MessageKind.DUPLICATE_TYPE_VARIABLE_NAME,
-          "Type variable '#{typeVariableName}' already declared."),
-
-      MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER:
-        const MessageTemplate(MessageKind.TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
-              "Cannot refer to type variable '#{typeVariableName}' "
-              "within a static member."),
-
-      MessageKind.TYPE_VARIABLE_IN_CONSTANT:
-        const MessageTemplate(MessageKind.TYPE_VARIABLE_IN_CONSTANT,
-          "Constant expressions can't refer to type variables.",
-          howToFix: "Try removing the type variable or replacing it with a "
-                    "concrete type.",
-          examples: const ["""
-class C<T> {
-  const C();
-
-  m(T t) => const C<T>();
-}
-
-void main() => new C().m(null);
-"""
-]),
-
-      MessageKind.INVALID_TYPE_VARIABLE_BOUND:
-        const MessageTemplate(MessageKind.INVALID_TYPE_VARIABLE_BOUND,
-          "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
-          "type variable '#{typeVariable}' of type '#{thisType}'.",
-          howToFix: "Try to change or remove the type argument.",
-          examples: const ["""
-class C<T extends num> {}
-
-// 'String' is not a valid instantiation of T with bound num.'.
-main() => new C<String>();
-"""]),
-
-      MessageKind.INVALID_USE_OF_SUPER:
-        const MessageTemplate(MessageKind.INVALID_USE_OF_SUPER,
-          "'super' not allowed here."),
-
-      MessageKind.INVALID_CASE_DEFAULT:
-        const MessageTemplate(MessageKind.INVALID_CASE_DEFAULT,
-          "'default' only allowed on last case of a switch."),
-
-      MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL:
-        const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL,
-          "'case' expressions do not all have type '#{type}'."),
-
-      MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE:
-        const MessageTemplate(MessageKind.SWITCH_CASE_TYPES_NOT_EQUAL_CASE,
-          "'case' expression of type '#{type}'."),
-
-      MessageKind.SWITCH_CASE_FORBIDDEN:
-        const MessageTemplate(MessageKind.SWITCH_CASE_FORBIDDEN,
-          "'case' expression may not be of type '#{type}'."),
-
-      MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS:
-        const MessageTemplate(MessageKind.SWITCH_CASE_VALUE_OVERRIDES_EQUALS,
-              "'case' expression type '#{type}' overrides 'operator =='."),
-
-      MessageKind.INVALID_ARGUMENT_AFTER_NAMED:
-        const MessageTemplate(MessageKind.INVALID_ARGUMENT_AFTER_NAMED,
-          "Unnamed argument after named argument."),
-
-      MessageKind.NOT_A_COMPILE_TIME_CONSTANT:
-        const MessageTemplate(MessageKind.NOT_A_COMPILE_TIME_CONSTANT,
-          "Not a compile-time constant."),
-
-      MessageKind.DEFERRED_COMPILE_TIME_CONSTANT:
-        const MessageTemplate(MessageKind.DEFERRED_COMPILE_TIME_CONSTANT,
-          "A deferred value cannot be used as a compile-time constant."),
-
-      MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION:
-        const MessageTemplate(
-          MessageKind.DEFERRED_COMPILE_TIME_CONSTANT_CONSTRUCTION,
-          "A deferred class cannot be used to create a "
-          "compile-time constant."),
-
-      MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS:
-        const MessageTemplate(MessageKind.CYCLIC_COMPILE_TIME_CONSTANTS,
-          "Cycle in the compile-time constant computation."),
-
-      MessageKind.CONSTRUCTOR_IS_NOT_CONST:
-        const MessageTemplate(MessageKind.CONSTRUCTOR_IS_NOT_CONST,
-          "Constructor is not a 'const' constructor."),
-
-      MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS:
-        const MessageTemplate(MessageKind.CONST_MAP_KEY_OVERRIDES_EQUALS,
-              "Const-map key type '#{type}' overrides 'operator =='."),
-
-      MessageKind.NO_SUCH_LIBRARY_MEMBER:
-        const MessageTemplate(MessageKind.NO_SUCH_LIBRARY_MEMBER,
-          "'#{libraryName}' has no member named '#{memberName}'."),
-
-      MessageKind.CANNOT_INSTANTIATE_TYPEDEF:
-        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
-          "Cannot instantiate typedef '#{typedefName}'."),
-
-      MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT,
-          "Non-optional parameters can't have a default value.",
-          howToFix:
-            "Try removing the default value or making the parameter optional.",
-          examples: const ["""
-main() {
-  foo(a: 1) => print(a);
-  foo(2);
-}""", """
-main() {
-  foo(a = 1) => print(a);
-  foo(2);
-}"""]),
-
-      MessageKind.NAMED_PARAMETER_WITH_EQUALS:
-        const MessageTemplate(MessageKind.NAMED_PARAMETER_WITH_EQUALS,
-          "Named optional parameters can't use '=' to specify a default "
-          "value.",
-          howToFix: "Try replacing '=' with ':'.",
-          examples: const ["""
-main() {
-  foo({a = 1}) => print(a);
-  foo(a: 2);
-}"""]),
-
-      MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS:
-        const MessageTemplate(MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS,
-          "Positional optional parameters can't use ':' to specify a "
-          "default value.",
-          howToFix: "Try replacing ':' with '='.",
-          examples: const ["""
-main() {
-  foo([a: 1]) => print(a);
-  foo(2);
-}"""]),
-
-      MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.TYPEDEF_FORMAL_WITH_DEFAULT,
-          "A parameter of a typedef can't specify a default value.",
-          howToFix:
-            "Try removing the default value.",
-          examples: const ["""
-typedef void F([int arg = 0]);
-
-main() {
-  F f;
-}""", """
-typedef void F({int arg: 0});
-
-main() {
-  F f;
-}"""]),
-
-      MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.FUNCTION_TYPE_FORMAL_WITH_DEFAULT,
-          "A function type parameter can't specify a default value.",
-          howToFix:
-            "Try removing the default value.",
-          examples: const ["""
-foo(f(int i, [a = 1])) {}
-
-main() {
-  foo(1, 2);
-}""", """
-foo(f(int i, {a: 1})) {}
-
-main() {
-  foo(1, a: 2);
-}"""]),
-
-      MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT:
-        const MessageTemplate(MessageKind.REDIRECTING_FACTORY_WITH_DEFAULT,
-          "A parameter of a redirecting factory constructor can't specify a "
-          "default value.",
-          howToFix:
-            "Try removing the default value.",
-          examples: const ["""
-class A {
-  A([a]);
-  factory A.foo([a = 1]) = A;
-}
-
-main() {
-  new A.foo(1);
-}""", """
-class A {
-  A({a});
-  factory A.foo({a: 1}) = A;
-}
-
-main() {
-  new A.foo(a: 1);
-}"""]),
-
-      MessageKind.FORMAL_DECLARED_CONST:
-        const MessageTemplate(MessageKind.FORMAL_DECLARED_CONST,
-          "A formal parameter can't be declared const.",
-          howToFix: "Try removing 'const'.",
-          examples: const ["""
-foo(const x) {}
-main() => foo(42);
-""", """
-foo({const x}) {}
-main() => foo(42);
-""", """
-foo([const x]) {}
-main() => foo(42);
-"""]),
-
-      MessageKind.FORMAL_DECLARED_STATIC:
-        const MessageTemplate(MessageKind.FORMAL_DECLARED_STATIC,
-          "A formal parameter can't be declared static.",
-          howToFix: "Try removing 'static'.",
-          examples: const ["""
-foo(static x) {}
-main() => foo(42);
-""", """
-foo({static x}) {}
-main() => foo(42);
-""", """
-foo([static x]) {}
-main() => foo(42);
-"""]),
-
-      MessageKind.FINAL_FUNCTION_TYPE_PARAMETER:
-        const MessageTemplate(MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
-          "A function type parameter can't be declared final.",
-          howToFix: "Try removing 'final'.",
-          examples: const ["""
-foo(final int x(int a)) {}
-main() => foo((y) => 42);
-""", """
-foo({final int x(int a)}) {}
-main() => foo((y) => 42);
-""", """
-foo([final int x(int a)]) {}
-main() => foo((y) => 42);
-"""]),
-
-      MessageKind.VAR_FUNCTION_TYPE_PARAMETER:
-        const MessageTemplate(MessageKind.VAR_FUNCTION_TYPE_PARAMETER,
-          "A function type parameter can't be declared with 'var'.",
-          howToFix: "Try removing 'var'.",
-          examples: const ["""
-foo(var int x(int a)) {}
-main() => foo((y) => 42);
-""", """
-foo({var int x(int a)}) {}
-main() => foo((y) => 42);
-""", """
-foo([var int x(int a)]) {}
-main() => foo((y) => 42);
-"""]),
-
-      MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE:
-        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
-          "Cannot instantiate type variable '#{typeVariableName}'."),
-
-      MessageKind.CYCLIC_TYPE_VARIABLE:
-        const MessageTemplate(MessageKind.CYCLIC_TYPE_VARIABLE,
-          "Type variable '#{typeVariableName}' is a supertype of itself."),
-
-      MessageKind.CYCLIC_TYPEDEF:
-        const MessageTemplate(MessageKind.CYCLIC_TYPEDEF,
-          "A typedef can't refer to itself.",
-          howToFix: "Try removing all references to '#{typedefName}' "
-                    "in the definition of '#{typedefName}'.",
-          examples: const ["""
-typedef F F(); // The return type 'F' is a self-reference.
-main() { F f = null; }"""]),
-
-      MessageKind.CYCLIC_TYPEDEF_ONE:
-        const MessageTemplate(MessageKind.CYCLIC_TYPEDEF_ONE,
-          "A typedef can't refer to itself through another typedef.",
-          howToFix:
-            "Try removing all references to "
-            "'#{otherTypedefName}' in the definition of '#{typedefName}'.",
-          examples: const ["""
-typedef G F(); // The return type 'G' is a self-reference through typedef 'G'.
-typedef F G(); // The return type 'F' is a self-reference through typedef 'F'.
-main() { F f = null; }""",
-"""
-typedef G F(); // The return type 'G' creates a self-reference.
-typedef H G(); // The return type 'H' creates a self-reference.
-typedef H(F f); // The argument type 'F' creates a self-reference.
-main() { F f = null; }"""]),
-
-      MessageKind.CLASS_NAME_EXPECTED:
-        const MessageTemplate(MessageKind.CLASS_NAME_EXPECTED,
-          "Class name expected."),
-
-      MessageKind.CANNOT_EXTEND:
-        const MessageTemplate(MessageKind.CANNOT_EXTEND,
-          "'#{type}' cannot be extended."),
-
-      MessageKind.CANNOT_IMPLEMENT:
-        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT,
-          "'#{type}' cannot be implemented."),
-
-      // TODO(johnnwinther): Split messages into reasons for malformedness.
-      MessageKind.CANNOT_EXTEND_MALFORMED:
-        const MessageTemplate(MessageKind.CANNOT_EXTEND_MALFORMED,
-          "Class '#{className}' can't extend the type '#{malformedType}' "
-          "because it is malformed.",
-          howToFix:
-            "Try correcting the malformed type annotation or removing the "
-            "'extends' clause.",
-          examples: const ["""
-class A extends Malformed {}
-main() => new A();"""]),
-
-      MessageKind.CANNOT_IMPLEMENT_MALFORMED:
-        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_MALFORMED,
-          "Class '#{className}' can't implement the type '#{malformedType}' "
-          "because it is malformed.",
-          howToFix:
-            "Try correcting the malformed type annotation or removing the "
-            "type from the 'implements' clause.",
-          examples: const ["""
-class A implements Malformed {}
-main() => new A();"""]),
-
-      MessageKind.CANNOT_MIXIN_MALFORMED:
-        const MessageTemplate(MessageKind.CANNOT_MIXIN_MALFORMED,
-          "Class '#{className}' can't mixin the type '#{malformedType}' "
-          "because it is malformed.",
-          howToFix:
-            "Try correcting the malformed type annotation or removing the "
-            "type from the 'with' clause.",
-          examples: const ["""
-class A extends Object with Malformed {}
-main() => new A();"""]),
-
-      MessageKind.CANNOT_MIXIN:
-        const MessageTemplate(MessageKind.CANNOT_MIXIN,
-          "The type '#{type}' can't be mixed in.",
-          howToFix: "Try removing '#{type}' from the 'with' clause.",
-          examples: const ["""
-class C extends Object with String {}
-
-main() => new C();
-""", """
-typedef C = Object with String;
-
-main() => new C();
-"""]),
-
-      MessageKind.CANNOT_EXTEND_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_EXTEND_ENUM,
-          "Class '#{className}' can't extend the type '#{enumType}' because "
-          "it is declared by an enum.",
-          howToFix: "Try making '#{enumType}' a normal class or removing the "
-            "'extends' clause.",
-          examples: const ["""
-enum Enum { A }
-class B extends Enum {}
-main() => new B();"""]),
-
-      MessageKind.CANNOT_IMPLEMENT_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_IMPLEMENT_ENUM,
-          "Class '#{className}' can't implement the type '#{enumType}' "
-          "because it is declared by an enum.",
-          howToFix: "Try making '#{enumType}' a normal class or removing the "
-            "type from the 'implements' clause.",
-          examples: const ["""
-enum Enum { A }
-class B implements Enum {}
-main() => new B();"""]),
-
-      MessageKind.CANNOT_MIXIN_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_MIXIN_ENUM,
-          "Class '#{className}' can't mixin the type '#{enumType}' because it "
-          "is declared by an enum.",
-          howToFix: "Try making '#{enumType}' a normal class or removing the "
-            "type from the 'with' clause.",
-          examples: const ["""
-enum Enum { A }
-class B extends Object with Enum {}
-main() => new B();"""]),
-
-      MessageKind.CANNOT_INSTANTIATE_ENUM:
-        const MessageTemplate(MessageKind.CANNOT_INSTANTIATE_ENUM,
-          "Enum type '#{enumName}' cannot be instantiated.",
-          howToFix: "Try making '#{enumType}' a normal class or use an enum "
-                    "constant.",
-          examples: const ["""
-enum Enum { A }
-main() => new Enum(0);""", """
-enum Enum { A }
-main() => const Enum(0);"""]),
-
-      MessageKind.EMPTY_ENUM_DECLARATION:
-        const MessageTemplate(MessageKind.EMPTY_ENUM_DECLARATION,
-          "Enum '#{enumName}' must contain at least one value.",
-          howToFix: "Try adding an enum constant or making #{enumName} a "
-                    "normal class.",
-          examples: const ["""
-enum Enum {}
-main() { Enum e; }"""]),
-
-      MessageKind.MISSING_ENUM_CASES:
-        const MessageTemplate(MessageKind.MISSING_ENUM_CASES,
-          "Missing enum constants in switch statement: #{enumValues}.",
-          howToFix: "Try adding the missing constants or a default case.",
-          examples: const ["""
-enum Enum { A, B }
-main() {
-  switch (Enum.A) {
-  case Enum.B: break;
-  }
-}""", """
-enum Enum { A, B, C }
-main() {
-  switch (Enum.A) {
-  case Enum.B: break;
-  }
-}"""]),
-
-      MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS:
-        const MessageTemplate(MessageKind.DUPLICATE_EXTENDS_IMPLEMENTS,
-          "'#{type}' can not be both extended and implemented."),
-
-      MessageKind.DUPLICATE_IMPLEMENTS:
-        const MessageTemplate(MessageKind.DUPLICATE_IMPLEMENTS,
-          "'#{type}' must not occur more than once "
-          "in the implements clause."),
-
-      MessageKind.MULTI_INHERITANCE:
-        const MessageTemplate(MessageKind.MULTI_INHERITANCE,
-          "Dart2js does not currently support inheritance of the same class "
-          "with different type arguments: Both #{firstType} and #{secondType} "
-          "are supertypes of #{thisType}."),
-
-      MessageKind.ILLEGAL_SUPER_SEND:
-        const MessageTemplate(MessageKind.ILLEGAL_SUPER_SEND,
-          "'#{name}' cannot be called on super."),
-
-      MessageKind.NO_SUCH_SUPER_MEMBER:
-        const MessageTemplate(MessageKind.NO_SUCH_SUPER_MEMBER,
-          "Cannot resolve '#{memberName}' in a superclass of '#{className}'."),
-
-      MessageKind.ADDITIONAL_TYPE_ARGUMENT:
-        const MessageTemplate(MessageKind.ADDITIONAL_TYPE_ARGUMENT,
-          "Additional type argument."),
-
-      MessageKind.MISSING_TYPE_ARGUMENT:
-        const MessageTemplate(MessageKind.MISSING_TYPE_ARGUMENT,
-          "Missing type argument."),
-
-      // TODO(johnniwinther): Use ADDITIONAL_TYPE_ARGUMENT or
-      // MISSING_TYPE_ARGUMENT instead.
-      MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH:
-        const MessageTemplate(MessageKind.TYPE_ARGUMENT_COUNT_MISMATCH,
-          "Incorrect number of type arguments on '#{type}'."),
-
-      MessageKind.GETTER_MISMATCH:
-        const MessageTemplate(MessageKind.GETTER_MISMATCH,
-          "Setter disagrees on: '#{modifiers}'."),
-
-      MessageKind.SETTER_MISMATCH:
-        const MessageTemplate(MessageKind.SETTER_MISMATCH,
-          "Getter disagrees on: '#{modifiers}'."),
-
-      MessageKind.ILLEGAL_SETTER_FORMALS:
-        const MessageTemplate(MessageKind.ILLEGAL_SETTER_FORMALS,
-          "A setter must have exactly one argument."),
-
-      MessageKind.NO_STATIC_OVERRIDE:
-        const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE,
-          "Static member cannot override instance member '#{memberName}' of "
-          "'#{className}'."),
-
-      MessageKind.NO_STATIC_OVERRIDE_CONT:
-        const MessageTemplate(MessageKind.NO_STATIC_OVERRIDE_CONT,
-          "This is the instance member that cannot be overridden "
-          "by a static member."),
-
-      MessageKind.INSTANCE_STATIC_SAME_NAME:
-        const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME,
-          "Instance member '#{memberName}' and static member of "
-          "superclass '#{className}' have the same name."),
-
-      MessageKind.INSTANCE_STATIC_SAME_NAME_CONT:
-        const MessageTemplate(MessageKind.INSTANCE_STATIC_SAME_NAME_CONT,
-          "This is the static member with the same name."),
-
-      MessageKind.INVALID_OVERRIDE_METHOD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_METHOD,
-          "The type '#{declaredType}' of method '#{name}' declared in "
-          "'#{class}' is not a subtype of the overridden method type "
-          "'#{inheritedType}' inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_METHOD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_METHOD,
-          "This is the overridden method '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.INVALID_OVERRIDE_GETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER,
-          "The type '#{declaredType}' of getter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden getter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_GETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_GETTER,
-          "This is the overridden getter '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_GETTER_WITH_FIELD,
-          "The type '#{declaredType}' of field '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden getter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_GETTER,
-          "The type '#{declaredType}' of getter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden field inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_SETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER,
-          "The type '#{declaredType}' of setter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden setter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_SETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_SETTER,
-          "This is the overridden setter '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_SETTER_WITH_FIELD,
-          "The type '#{declaredType}' of field '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden setter inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD_WITH_SETTER,
-          "The type '#{declaredType}' of setter '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden field inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDE_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDE_FIELD,
-          "The type '#{declaredType}' of field '#{name}' declared in "
-          "'#{class}' is not assignable to the type '#{inheritedType}' of the "
-          "overridden field inherited from '#{inheritedClass}'."),
-
-      MessageKind.INVALID_OVERRIDDEN_FIELD:
-        const MessageTemplate(MessageKind.INVALID_OVERRIDDEN_FIELD,
-          "This is the overridden field '#{name}' declared in class "
-          "'#{class}'."),
-
-      MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD:
-        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD,
-          "Method '#{name}' in '#{class}' can't override field from "
-          "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_FIELD_WITH_METHOD_CONT,
-          "This is the field that cannot be overridden by a method."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD,
-          "Field '#{name}' in '#{class}' can't override method from "
-          "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_FIELD_CONT,
-          "This is the method that cannot be overridden by a field."),
-
-      MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD:
-        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD,
-              "Method '#{name}' in '#{class}' can't override getter from "
-              "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT,
-          "This is the getter that cannot be overridden by a method."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER:
-        const MessageTemplate(MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER,
-          "Getter '#{name}' in '#{class}' can't override method from "
-          "'#{inheritedClass}'."),
-
-      MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT:
-        const MessageTemplate(
-          MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT,
-          "This is the method that cannot be overridden by a getter."),
-
-      MessageKind.MISSING_FORMALS:
-        const MessageTemplate(MessageKind.MISSING_FORMALS,
-          "Formal parameters are missing."),
-
-      MessageKind.EXTRA_FORMALS:
-        const MessageTemplate(MessageKind.EXTRA_FORMALS,
-          "Formal parameters are not allowed here."),
-
-      MessageKind.UNARY_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.UNARY_OPERATOR_BAD_ARITY,
-          "Operator '#{operatorName}' must have no parameters."),
-
-      MessageKind.MINUS_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.MINUS_OPERATOR_BAD_ARITY,
-          "Operator '-' must have 0 or 1 parameters."),
-
-      MessageKind.BINARY_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.BINARY_OPERATOR_BAD_ARITY,
-          "Operator '#{operatorName}' must have exactly 1 parameter."),
-
-      MessageKind.TERNARY_OPERATOR_BAD_ARITY:
-        const MessageTemplate(MessageKind.TERNARY_OPERATOR_BAD_ARITY,
-          "Operator '#{operatorName}' must have exactly 2 parameters."),
-
-      MessageKind.OPERATOR_OPTIONAL_PARAMETERS:
-        const MessageTemplate(MessageKind.OPERATOR_OPTIONAL_PARAMETERS,
-          "Operator '#{operatorName}' cannot have optional parameters."),
-
-      MessageKind.OPERATOR_NAMED_PARAMETERS:
-        const MessageTemplate(MessageKind.OPERATOR_NAMED_PARAMETERS,
-          "Operator '#{operatorName}' cannot have named parameters."),
-
-      MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE:
-        const MessageTemplate(MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE,
-          "Cannot have return type for constructor."),
-
-      MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR,
-          "Constructors can't return values.",
-          howToFix: "Remove the return statement or use a factory constructor.",
-          examples: const ["""
-class C {
-  C() {
-    return 1;
-  }
-}
-
-main() => new C();"""]),
-
-      MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER:
-        const MessageTemplate(MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER,
-          "Cannot have final modifier on method."),
-
-      MessageKind.ILLEGAL_CONST_FIELD_MODIFIER:
-        const MessageTemplate(MessageKind.ILLEGAL_CONST_FIELD_MODIFIER,
-          "Cannot have const modifier on non-static field.",
-          howToFix:
-            "Try adding a static modifier, or removing the const modifier.",
-          examples: const ["""
-class C {
-  const int a = 1;
-}
-
-main() => new C();"""]),
-
-      MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS:
-        const MessageTemplate(MessageKind.ILLEGAL_CONSTRUCTOR_MODIFIERS,
-          "Illegal constructor modifiers: '#{modifiers}'."),
-
-      MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_APPLICATION_MODIFIERS,
-              "Illegal mixin application modifiers: '#{modifiers}'."),
-
-      MessageKind.ILLEGAL_MIXIN_SUPERCLASS:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPERCLASS,
-          "Class used as mixin must have Object as superclass."),
-
-      MessageKind.ILLEGAL_MIXIN_OBJECT:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_OBJECT,
-          "Cannot use Object as mixin."),
-
-      MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CONSTRUCTOR,
-          "Class used as mixin cannot have non-factory constructor."),
-
-      MessageKind.ILLEGAL_MIXIN_CYCLE:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_CYCLE,
-          "Class used as mixin introduces mixin cycle: "
-          "'#{mixinName1}' <-> '#{mixinName2}'."),
-
-      MessageKind.ILLEGAL_MIXIN_WITH_SUPER:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_WITH_SUPER,
-          "Cannot use class '#{className}' as a mixin because it uses "
-          "'super'."),
-
-      MessageKind.ILLEGAL_MIXIN_SUPER_USE:
-        const MessageTemplate(MessageKind.ILLEGAL_MIXIN_SUPER_USE,
-          "Use of 'super' in class used as mixin."),
-
-      MessageKind.PARAMETER_NAME_EXPECTED:
-        const MessageTemplate(MessageKind.PARAMETER_NAME_EXPECTED,
-          "parameter name expected."),
-
-      MessageKind.CANNOT_RESOLVE_GETTER:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_GETTER,
-          "Cannot resolve getter."),
-
-      MessageKind.CANNOT_RESOLVE_SETTER:
-        const MessageTemplate(MessageKind.CANNOT_RESOLVE_SETTER,
-          "Cannot resolve setter."),
-
-      MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER:
-        const MessageTemplate(MessageKind.ASSIGNING_FINAL_FIELD_IN_SUPER,
-          "Cannot assign a value to final field '#{name}' "
-          "in superclass '#{superclassName}'."),
-
-      MessageKind.ASSIGNING_METHOD:
-        const MessageTemplate(MessageKind.ASSIGNING_METHOD,
-          "Cannot assign a value to a method."),
-
-      MessageKind.ASSIGNING_METHOD_IN_SUPER:
-        const MessageTemplate(MessageKind.ASSIGNING_METHOD_IN_SUPER,
-          "Cannot assign a value to method '#{name}' "
-          "in superclass '#{superclassName}'."),
-
-      MessageKind.ASSIGNING_TYPE:
-        const MessageTemplate(MessageKind.ASSIGNING_TYPE,
-          "Cannot assign a value to a type."),
-
-      MessageKind.IF_NULL_ASSIGNING_TYPE:
-        const MessageTemplate(MessageKind.IF_NULL_ASSIGNING_TYPE,
-          "Cannot assign a value to a type. Note that types are never null, "
-          "so this ??= assignment has no effect.",
-          howToFix: "Try removing the '??=' assignment.",
-          examples: const [
-              "class A {} main() { print(A ??= 3);}",
-          ]),
-
-      MessageKind.VOID_NOT_ALLOWED:
-        const MessageTemplate(MessageKind.VOID_NOT_ALLOWED,
-          "Type 'void' can't be used here because it isn't a return type.",
-          howToFix:
-            "Try removing 'void' keyword or replace it with 'var', 'final', "
-            "or a type.",
-          examples: const [
-              "void x; main() {}",
-              "foo(void x) {} main() { foo(null); }",
-          ]),
-
-      MessageKind.NULL_NOT_ALLOWED:
-        const MessageTemplate(MessageKind.NULL_NOT_ALLOWED,
-          "`null` can't be used here."),
-
-      MessageKind.BEFORE_TOP_LEVEL:
-        const MessageTemplate(MessageKind.BEFORE_TOP_LEVEL,
-          "Part header must come before top-level definitions."),
-
-      MessageKind.IMPORT_PART_OF:
-        const MessageTemplate(MessageKind.IMPORT_PART_OF,
-          "The imported library must not have a 'part-of' directive.",
-          howToFix: "Try removing the 'part-of' directive or replacing the "
-                    "import of the library with a 'part' directive.",
-          examples: const [const {
-'main.dart': """
-library library;
-
-import 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of library;
-"""}]),
-
-      MessageKind.LIBRARY_NAME_MISMATCH:
-        const MessageTemplate(MessageKind.LIBRARY_NAME_MISMATCH,
-          "Expected part of library name '#{libraryName}'.",
-          howToFix: "Try changing the directive to 'part of #{libraryName};'.",
-          examples: const [const {
-'main.dart': """
-library lib.foo;
-
-part 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of lib.bar;
-"""}]),
-
-      MessageKind.MISSING_LIBRARY_NAME:
-        const MessageTemplate(MessageKind.MISSING_LIBRARY_NAME,
-          "Library has no name. Part directive expected library name "
-          "to be '#{libraryName}'.",
-          howToFix: "Try adding 'library #{libraryName};' to the library.",
-          examples: const [const {
-'main.dart': """
-part 'part.dart';
-
-main() {}
-""",
-
-'part.dart': """
-part of lib.foo;
-"""}]),
-
-      MessageKind.THIS_IS_THE_PART_OF_TAG:
-        const MessageTemplate(MessageKind.THIS_IS_THE_PART_OF_TAG,
-          "This is the part of directive."),
-
-      MessageKind.MISSING_PART_OF_TAG:
-        const MessageTemplate(MessageKind.MISSING_PART_OF_TAG,
-          "This file has no part-of tag, but it is being used as a part."),
-
-      MessageKind.DUPLICATED_PART_OF:
-        const MessageTemplate(MessageKind.DUPLICATED_PART_OF,
-          "Duplicated part-of directive."),
-
-      MessageKind.DUPLICATED_LIBRARY_NAME:
-        const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_NAME,
-          "Duplicated library name '#{libraryName}'."),
-
-      MessageKind.DUPLICATED_RESOURCE:
-        const MessageTemplate(MessageKind.DUPLICATED_RESOURCE,
-          "The resource '#{resourceUri}' is loaded through both "
-          "'#{canonicalUri1}' and '#{canonicalUri2}'."),
-
-      MessageKind.DUPLICATED_LIBRARY_RESOURCE:
-        const MessageTemplate(MessageKind.DUPLICATED_LIBRARY_RESOURCE,
-          "The library '#{libraryName}' in '#{resourceUri}' is loaded through "
-          "both '#{canonicalUri1}' and '#{canonicalUri2}'."),
-
-      // This is used as an exception.
-      MessageKind.INVALID_SOURCE_FILE_LOCATION:
-        const MessageTemplate(MessageKind.INVALID_SOURCE_FILE_LOCATION, '''
-Invalid offset (#{offset}) in source map.
-File: #{fileName}
-Length: #{length}'''),
-
-      MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC:
-        const MessageTemplate(MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC,
-              "Top-level variable cannot be declared static."),
-
-      MessageKind.REFERENCE_IN_INITIALIZATION:
-        const MessageTemplate(MessageKind.REFERENCE_IN_INITIALIZATION,
-           "Variable '#{variableName}' is referenced during its "
-           "initialization.",
-           howToFix:
-             "If you are trying to reference a shadowed variable, rename "
-             "one of the variables.",
-           examples: const ["""
-foo(t) {
-  var t = t;
-  return t;
-}
-
-main() => foo(1);
-"""]),
-
-      MessageKind.CONST_WITHOUT_INITIALIZER:
-        const MessageTemplate(MessageKind.CONST_WITHOUT_INITIALIZER,
-          "A constant variable must be initialized.",
-          howToFix: "Try adding an initializer or "
-                    "removing the 'const' modifier.",
-          examples: const ["""
-void main() {
-  const c; // This constant variable must be initialized.
-}"""]),
-
-      MessageKind.FINAL_WITHOUT_INITIALIZER:
-        const MessageTemplate(MessageKind.FINAL_WITHOUT_INITIALIZER,
-          "A final variable must be initialized.",
-          howToFix: "Try adding an initializer or "
-                    "removing the 'final' modifier.",
-          examples: const [
-              "class C { static final field; } main() => C.field;"]),
-
-      MessageKind.MEMBER_USES_CLASS_NAME:
-        const MessageTemplate(MessageKind.MEMBER_USES_CLASS_NAME,
-          "Member variable can't have the same name as the class it is "
-          "declared in.",
-          howToFix: "Try renaming the variable.",
-          examples: const ["""
-class A { var A; }
-main() {
-  var a = new A();
-  a.A = 1;
-}
-""", """
-class A { static var A; }
-main() => A.A = 1;
-"""]),
-
-      MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT:
-        const MessageTemplate(
-          MessageKind.WRONG_NUMBER_OF_ARGUMENTS_FOR_ASSERT,
-          "Wrong number of arguments to assert. Should be 1, but given "
-          "#{argumentCount}."),
-
-      MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS:
-        const MessageTemplate(MessageKind.ASSERT_IS_GIVEN_NAMED_ARGUMENTS,
-          "'assert' takes no named arguments, but given #{argumentCount}."),
-
-      MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY:
-        const MessageTemplate(MessageKind.FACTORY_REDIRECTION_IN_NON_FACTORY,
-          "Factory redirection only allowed in factories."),
-
-      MessageKind.MISSING_FACTORY_KEYWORD:
-        const MessageTemplate(MessageKind.MISSING_FACTORY_KEYWORD,
-          "Did you forget a factory keyword here?"),
-
-      MessageKind.NO_SUCH_METHOD_IN_NATIVE:
-        const MessageTemplate(MessageKind.NO_SUCH_METHOD_IN_NATIVE,
-          "'NoSuchMethod' is not supported for classes that extend native "
-          "classes."),
-
-      MessageKind.DEFERRED_LIBRARY_DART_2_DART:
-        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DART_2_DART,
-          "Deferred loading is not supported by the dart backend yet. "
-          "The output will not be split."),
-
-      MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX:
-        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_WITHOUT_PREFIX,
-          "This import is deferred but there is no prefix keyword.",
-          howToFix: "Try adding a prefix to the import."),
-
-      MessageKind.DEFERRED_OLD_SYNTAX:
-        const MessageTemplate(MessageKind.DEFERRED_OLD_SYNTAX,
-          "The DeferredLibrary annotation is obsolete.",
-          howToFix:
-            "Use the \"import 'lib.dart' deferred as prefix\" syntax instead."),
-
-      MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX:
-        const MessageTemplate(MessageKind.DEFERRED_LIBRARY_DUPLICATE_PREFIX,
-          "The prefix of this deferred import is not unique.",
-          howToFix: "Try changing the import prefix."),
-
-      MessageKind.DEFERRED_TYPE_ANNOTATION:
-        const MessageTemplate(MessageKind.DEFERRED_TYPE_ANNOTATION,
-          "The type #{node} is deferred. "
-          "Deferred types are not valid as type annotations.",
-          howToFix:
-            "Try using a non-deferred abstract class as an interface."),
-
-      MessageKind.ILLEGAL_STATIC:
-        const MessageTemplate(MessageKind.ILLEGAL_STATIC,
-          "Modifier static is only allowed on functions declared in "
-          "a class."),
-
-      MessageKind.STATIC_FUNCTION_BLOAT:
-        const MessageTemplate(MessageKind.STATIC_FUNCTION_BLOAT,
-          "Using '#{class}.#{name}' may lead to unnecessarily large "
-          "generated code.",
-          howToFix:
-              "Try adding '@MirrorsUsed(...)' as described at "
-              "https://goo.gl/Akrrog."),
-
-      MessageKind.NON_CONST_BLOAT:
-        const MessageTemplate(MessageKind.NON_CONST_BLOAT,
-          "Using 'new #{name}' may lead to unnecessarily large generated "
-          "code.",
-          howToFix:
-              "Try using 'const #{name}' or adding '@MirrorsUsed(...)' as "
-              "described at https://goo.gl/Akrrog."),
-
-      MessageKind.STRING_EXPECTED:
-        const MessageTemplate(MessageKind.STRING_EXPECTED,
-          "Expected a 'String', but got an instance of '#{type}'."),
-
-      MessageKind.PRIVATE_IDENTIFIER:
-        const MessageTemplate(MessageKind.PRIVATE_IDENTIFIER,
-          "'#{value}' is not a valid Symbol name because it starts with "
-          "'_'."),
-
-      MessageKind.PRIVATE_NAMED_PARAMETER:
-        const MessageTemplate(MessageKind.PRIVATE_NAMED_PARAMETER,
-          "Named optional parameter can't have a library private name.",
-          howToFix:
-            "Try removing the '_' or making the parameter positional or "
-            "required.",
-          examples: const ["""foo({int _p}) {} main() => foo();"""]),
-
-      MessageKind.UNSUPPORTED_LITERAL_SYMBOL:
-        const MessageTemplate(MessageKind.UNSUPPORTED_LITERAL_SYMBOL,
-          "Symbol literal '##{value}' is currently unsupported by dart2js."),
-
-      MessageKind.INVALID_SYMBOL:
-        const MessageTemplate(MessageKind.INVALID_SYMBOL, '''
-'#{value}' is not a valid Symbol name because is not:
- * an empty String,
- * a user defined operator,
- * a qualified non-private identifier optionally followed by '=', or
- * a qualified non-private identifier followed by '.' and a user-defined '''
-"operator."),
-
-      MessageKind.AMBIGUOUS_REEXPORT:
-        const MessageTemplate(MessageKind.AMBIGUOUS_REEXPORT,
-          "'#{name}' is (re)exported by multiple libraries."),
-
-      MessageKind.AMBIGUOUS_LOCATION:
-        const MessageTemplate(MessageKind.AMBIGUOUS_LOCATION,
-          "'#{name}' is defined here."),
-
-      MessageKind.IMPORTED_HERE:
-        const MessageTemplate(MessageKind.IMPORTED_HERE,
-          "'#{name}' is imported here."),
-
-      MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE:
-        const MessageTemplate(MessageKind.OVERRIDE_EQUALS_NOT_HASH_CODE,
-          "The class '#{class}' overrides 'operator==', "
-          "but not 'get hashCode'."),
-
-      MessageKind.INTERNAL_LIBRARY_FROM:
-        const MessageTemplate(MessageKind.INTERNAL_LIBRARY_FROM,
-          "Internal library '#{resolvedUri}' is not accessible from "
-          "'#{importingUri}'."),
-
-      MessageKind.INTERNAL_LIBRARY:
-        const MessageTemplate(MessageKind.INTERNAL_LIBRARY,
-          "Internal library '#{resolvedUri}' is not accessible."),
-
-      MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS:
-        const MessageTemplate(
-          MessageKind.JS_INTEROP_CLASS_CANNOT_EXTEND_DART_CLASS,
-          "Js-interop class '#{cls}' cannot extend from the non js-interop "
-          "class '#{superclass}'.",
-          howToFix: "Annotate the superclass with @JS.",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              class Foo { }
-
-              @JS()
-              class Bar extends Foo { }
-
-              main() {
-                new Bar();
-              }
-              """]),
-
-      MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER:
-        const MessageTemplate(
-          MessageKind.JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER,
-          "Member '#{member}' in js-interop class '#{cls}' is not external.",
-          howToFix: "Mark all interop methods external",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              @JS()
-              class Foo {
-                bar() {}
-              }
-
-              main() {
-                new Foo().bar();
-              }
-              """]),
-
-      MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS:
-        const MessageTemplate(
-          MessageKind.JS_INTEROP_METHOD_WITH_NAMED_ARGUMENTS,
-          "Js-interop method '#{method}' has named arguments but is not "
-          "a factory constructor of an @anonymous @JS class.",
-          howToFix: "Remove all named arguments from js-interop method or "
-                    "in the case of a factory constructor annotate the class "
-                    "as @anonymous.",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              @JS()
-              class Foo {
-                external bar(foo, {baz});
-              }
-
-              main() {
-                new Foo().bar(4, baz: 5);
-              }
-              """]),
-
-      MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS:
-        const MessageTemplate(
-          MessageKind.JS_OBJECT_LITERAL_CONSTRUCTOR_WITH_POSITIONAL_ARGUMENTS,
-          "Parameter '#{parameter}' in anonymous js-interop class '#{cls}' "
-          "object literal constructor is positional instead of named."
-          ".",
-          howToFix: "Make all arguments in external factory object literal "
-                    "constructors named.",
-          examples: const [
-              """
-              import 'package:js/js.dart';
-
-              @anonymous
-              @JS()
-              class Foo {
-                external factory Foo(foo, {baz});
-              }
-
-              main() {
-                new Foo(5, baz: 5);
-              }
-              """]),
-
-      MessageKind.LIBRARY_NOT_FOUND:
-        const MessageTemplate(MessageKind.LIBRARY_NOT_FOUND,
-          "Library not found '#{resolvedUri}'."),
-
-      MessageKind.LIBRARY_NOT_SUPPORTED:
-        const MessageTemplate(MessageKind.LIBRARY_NOT_SUPPORTED,
-          "Library not supported '#{resolvedUri}'.",
-          howToFix: "Try removing the dependency or enabling support using "
-                    "the '--categories' option.",
-          examples: const [/*
-              """
-              import 'dart:io';
-              main() {}
-              """
-          */]),
-          // TODO(johnniwinther): Enable example when message_kind_test.dart
-          // supports library loader callbacks.
-
-      MessageKind.UNSUPPORTED_EQ_EQ_EQ:
-        const MessageTemplate(MessageKind.UNSUPPORTED_EQ_EQ_EQ,
-          "'===' is not an operator. "
-          "Did you mean '#{lhs} == #{rhs}' or 'identical(#{lhs}, #{rhs})'?"),
-
-      MessageKind.UNSUPPORTED_BANG_EQ_EQ:
-        const MessageTemplate(MessageKind.UNSUPPORTED_BANG_EQ_EQ,
-          "'!==' is not an operator. "
-          "Did you mean '#{lhs} != #{rhs}' or '!identical(#{lhs}, #{rhs})'?"),
-
-      MessageKind.UNSUPPORTED_PREFIX_PLUS:
-        const MessageTemplate(MessageKind.UNSUPPORTED_PREFIX_PLUS,
-          "'+' is not a prefix operator. ",
-          howToFix: "Try removing '+'.",
-          examples: const [
-              "main() => +2;  // No longer a valid way to write '2'"
-          ]),
-
-      MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP:
-        const MessageTemplate(MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP,
-          "No expression after 'throw'. "
-          "Did you mean 'rethrow'?"),
-
-      MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
-        const MessageTemplate(MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX,
-          "'typedef' not allowed here. ",
-          howToFix: "Try replacing 'typedef' with 'class'.",
-          examples: const [
-              """
-class B { }
-class M1 {  }
-typedef C = B with M1;  // Need to replace 'typedef' with 'class'.
-main() { new C(); }
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "and a 'String' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// 'Foo' is a type literal, not a string.
-@MirrorsUsed(symbols: const [Foo])
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_TYPE,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "and a 'String' or 'Type' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// 'main' is a method, not a class.
-@MirrorsUsed(targets: const [main])
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_OR_LIST,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "and a 'String' or 'List' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// 'Foo' is not a string.
-@MirrorsUsed(symbols: Foo)
-import 'dart:mirrors';
-
-class Foo {}
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST:
-        const MessageTemplate(MessageKind.MIRRORS_EXPECTED_STRING_TYPE_OR_LIST,
-          "Can't use '#{name}' here because it's an instance of '#{type}' "
-          "but a 'String', 'Type', or 'List' value is expected.",
-          howToFix: "Did you forget to add quotes?",
-          examples: const [
-              """
-// '1' is not a string.
-@MirrorsUsed(targets: 1)
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY:
-        const MessageTemplate(
-          MessageKind.MIRRORS_CANNOT_RESOLVE_IN_CURRENT_LIBRARY,
-          "Can't find '#{name}' in the current library.",
-          // TODO(ahe): The closest identifiers in edit distance would be nice.
-          howToFix: "Did you forget to add an import?",
-          examples: const [
-              """
-// 'window' is not in scope because dart:html isn't imported.
-@MirrorsUsed(targets: 'window')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY:
-        const MessageTemplate(MessageKind.MIRRORS_CANNOT_RESOLVE_IN_LIBRARY,
-          "Can't find '#{name}' in the library '#{library}'.",
-          // TODO(ahe): The closest identifiers in edit distance would be nice.
-          howToFix: "Is '#{name}' spelled right?",
-          examples: const [
-              """
-// 'List' is misspelled.
-@MirrorsUsed(targets: 'dart.core.Lsit')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT:
-        const MessageTemplate(MessageKind.MIRRORS_CANNOT_FIND_IN_ELEMENT,
-          "Can't find '#{name}' in '#{element}'.",
-          // TODO(ahe): The closest identifiers in edit distance would be nice.
-          howToFix: "Is '#{name}' spelled right?",
-          examples: const [
-              """
-// 'addAll' is misspelled.
-@MirrorsUsed(targets: 'dart.core.List.addAl')
-import 'dart:mirrors';
-
-main() {}
-"""]),
-
-      MessageKind.INVALID_URI:
-        const MessageTemplate(MessageKind.INVALID_URI,
-          "'#{uri}' is not a valid URI.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-            """
-// can't have a '[' in a URI
-import '../../Udyn[mic ils/expect.dart';
-
-main() {}
-"""]),
-
-      MessageKind.INVALID_PACKAGE_CONFIG:
-          const MessageTemplate(MessageKind.INVALID_PACKAGE_CONFIG,
-            """Package config file '#{uri}' is invalid.
-#{exception}""",
-            howToFix: DONT_KNOW_HOW_TO_FIX
-      ),
-
-      MessageKind.INVALID_PACKAGE_URI:
-        const MessageTemplate(MessageKind.INVALID_PACKAGE_URI,
-          "'#{uri}' is not a valid package URI (#{exception}).",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-            """
-// can't have a 'top level' package URI
-import 'package:foo.dart';
-
-main() {}
-""", """
-// can't have 2 slashes
-import 'package://foo/foo.dart';
-
-main() {}
-""", """
-// package name must be valid
-import 'package:not\valid/foo.dart';
-
-main() {}
-"""]),
-
-      MessageKind.READ_SCRIPT_ERROR:
-        const MessageTemplate(MessageKind.READ_SCRIPT_ERROR,
-          "Can't read '#{uri}' (#{exception}).",
-          // Don't know how to fix since the underlying error is unknown.
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-              """
-// 'foo.dart' does not exist.
-import 'foo.dart';
-
-main() {}
-"""]),
-
-      MessageKind.READ_SELF_ERROR:
-        const MessageTemplate(MessageKind.READ_SELF_ERROR,
-          "#{exception}",
-          // Don't know how to fix since the underlying error is unknown.
-          howToFix: DONT_KNOW_HOW_TO_FIX),
-
-      MessageKind.EXTRANEOUS_MODIFIER:
-        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER,
-          "Can't have modifier '#{modifier}' here.",
-          howToFix: "Try removing '#{modifier}'.",
-          examples: const [
-              "var String foo; main(){}",
-              // "var get foo; main(){}",
-              "var set foo; main(){}",
-              "var final foo; main(){}",
-              "var var foo; main(){}",
-              "var const foo; main(){}",
-              "var abstract foo; main(){}",
-              "var static foo; main(){}",
-              "var external foo; main(){}",
-              "get var foo; main(){}",
-              "set var foo; main(){}",
-              "final var foo; main(){}",
-              "var var foo; main(){}",
-              "const var foo; main(){}",
-              "abstract var foo; main(){}",
-              "static var foo; main(){}",
-              "external var foo; main(){}"]),
-
-      MessageKind.EXTRANEOUS_MODIFIER_REPLACE:
-        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER_REPLACE,
-          "Can't have modifier '#{modifier}' here.",
-          howToFix:
-            "Try replacing modifier '#{modifier}' with 'var', 'final', "
-            "or a type.",
-          examples: const [
-              // "get foo; main(){}",
-              "set foo; main(){}",
-              "abstract foo; main(){}",
-              "static foo; main(){}",
-              "external foo; main(){}"]),
-
-      MessageKind.ABSTRACT_CLASS_INSTANTIATION:
-        const MessageTemplate(MessageKind.ABSTRACT_CLASS_INSTANTIATION,
-          "Can't instantiate abstract class.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["abstract class A {} main() { new A(); }"]),
-
-      MessageKind.BODY_EXPECTED:
-        const MessageTemplate(MessageKind.BODY_EXPECTED,
-          "Expected a function body or '=>'.",
-          // TODO(ahe): In some scenarios, we can suggest removing the 'static'
-          // keyword.
-          howToFix: "Try adding {}.",
-          examples: const [
-              "main();"]),
-
-      MessageKind.MIRROR_BLOAT:
-        const MessageTemplate(MessageKind.MIRROR_BLOAT,
-          "#{count} methods retained for use by dart:mirrors out of #{total}"
-          " total methods (#{percentage}%)."),
-
-      MessageKind.MIRROR_IMPORT:
-        const MessageTemplate(MessageKind.MIRROR_IMPORT,
-          "Import of 'dart:mirrors'."),
-
-      MessageKind.MIRROR_IMPORT_NO_USAGE:
-        const MessageTemplate(MessageKind.MIRROR_IMPORT_NO_USAGE,
-          "This import is not annotated with @MirrorsUsed, which may lead to "
-          "unnecessarily large generated code.",
-          howToFix:
-              "Try adding '@MirrorsUsed(...)' as described at "
-              "https://goo.gl/Akrrog."),
-
-      MessageKind.JS_PLACEHOLDER_CAPTURE:
-        const MessageTemplate(
-            MessageKind.JS_PLACEHOLDER_CAPTURE,
-            "JS code must not use '#' placeholders inside functions.",
-            howToFix:
-            "Use an immediately called JavaScript function to capture the"
-            " the placeholder values as JavaScript function parameters."),
-
-      MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT:
-        const MessageTemplate(
-          MessageKind.WRONG_ARGUMENT_FOR_JS_INTERCEPTOR_CONSTANT,
-          "Argument for 'JS_INTERCEPTOR_CONSTANT' must be a type constant."),
-
-      MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD:
-        const MessageTemplate(MessageKind.EXPECTED_IDENTIFIER_NOT_RESERVED_WORD,
-              "'#{keyword}' is a reserved word and can't be used here.",
-              howToFix: "Try using a different name.",
-              examples: const ["do() {} main() {}"]),
-
-      MessageKind. NAMED_FUNCTION_EXPRESSION:
-        const MessageTemplate(MessageKind.NAMED_FUNCTION_EXPRESSION,
-          "Function expression '#{name}' cannot be named.",
-          howToFix: "Try removing the name.",
-          examples: const ["main() { var f = func() {}; }"]),
-
-      MessageKind.UNUSED_METHOD:
-        const MessageTemplate(MessageKind.UNUSED_METHOD,
-          "The method '#{name}' is never called.",
-          howToFix: "Consider deleting it.",
-          examples: const ["deadCode() {} main() {}"]),
-
-      MessageKind.UNUSED_CLASS:
-        const MessageTemplate(MessageKind.UNUSED_CLASS,
-          "The class '#{name}' is never used.",
-          howToFix: "Consider deleting it.",
-          examples: const ["class DeadCode {} main() {}"]),
-
-      MessageKind.UNUSED_TYPEDEF:
-        const MessageTemplate(MessageKind.UNUSED_TYPEDEF,
-          "The typedef '#{name}' is never used.",
-          howToFix: "Consider deleting it.",
-          examples: const ["typedef DeadCode(); main() {}"]),
-
-      MessageKind.ABSTRACT_METHOD:
-        const MessageTemplate(MessageKind.ABSTRACT_METHOD,
-          "The method '#{name}' has no implementation in "
-          "class '#{class}'.",
-          howToFix: "Try adding a body to '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-class Class {
-  method();
-}
-main() => new Class().method();
-"""]),
-
-      MessageKind.ABSTRACT_GETTER:
-        const MessageTemplate(MessageKind.ABSTRACT_GETTER,
-          "The getter '#{name}' has no implementation in "
-          "class '#{class}'.",
-          howToFix: "Try adding a body to '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-class Class {
-  get getter;
-}
-main() => new Class();
-"""]),
-
-      MessageKind.ABSTRACT_SETTER:
-        const MessageTemplate(MessageKind.ABSTRACT_SETTER,
-          "The setter '#{name}' has no implementation in "
-          "class '#{class}'.",
-          howToFix: "Try adding a body to '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-class Class {
-  set setter(_);
-}
-main() => new Class();
-"""]),
-
-      MessageKind.INHERIT_GETTER_AND_METHOD:
-        const MessageTemplate(MessageKind.INHERIT_GETTER_AND_METHOD,
-          "The class '#{class}' can't inherit both getters and methods "
-          "by the named '#{name}'.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["""
-class A {
-  get member => null;
-}
-class B {
-  member() {}
-}
-class Class implements A, B {
-}
-main() => new Class();
-"""]),
-
-      MessageKind.INHERITED_METHOD:
-        const MessageTemplate(MessageKind.INHERITED_METHOD,
-          "The inherited method '#{name}' is declared here in class "
-          "'#{class}'."),
-
-      MessageKind.INHERITED_EXPLICIT_GETTER:
-        const MessageTemplate(MessageKind.INHERITED_EXPLICIT_GETTER,
-          "The inherited getter '#{name}' is declared here in class "
-          "'#{class}'."),
-
-      MessageKind.INHERITED_IMPLICIT_GETTER:
-        const MessageTemplate(MessageKind.INHERITED_IMPLICIT_GETTER,
-          "The inherited getter '#{name}' is implicitly declared by this "
-          "field in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_METHOD_ONE:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_ONE,
-          "'#{class}' doesn't implement '#{method}' "
-          "declared in '#{declarer}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  m();
-}
-class C implements I {}
-main() => new C();
-""", """
-abstract class I {
-  m();
-}
-class C extends I {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_METHOD:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD,
-          "'#{class}' doesn't implement '#{method}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  m();
-}
-
-abstract class J {
-  m();
-}
-
-class C implements I, J {}
-
-main() {
- new C();
-}
-""", """
-abstract class I {
-  m();
-}
-
-abstract class J {
-  m();
-}
-
-class C extends I implements J {}
-
-main() {
- new C();
-}
-"""]),
-
-      MessageKind.UNIMPLEMENTED_METHOD_CONT:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_METHOD_CONT,
-          "The method '#{name}' is declared here in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_SETTER_ONE:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER_ONE,
-          "'#{class}' doesn't implement the setter '#{name}' "
-          "declared in '#{declarer}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  set m(_);
-}
-class C implements I {}
-class D implements I {
-  set m(_) {}
-}
-main() {
- new D().m = 0;
- new C();
-}
-"""]),
-
-      MessageKind.UNIMPLEMENTED_SETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_SETTER,
-          "'#{class}' doesn't implement the setter '#{name}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  set m(_);
-}
-abstract class J {
-  set m(_);
-}
-class C implements I, J {}
-main() => new C();
-""", """
-abstract class I {
-  set m(_);
-}
-abstract class J {
-  set m(_);
-}
-class C extends I implements J {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_SETTER,
-          "The setter '#{name}' is declared here in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_SETTER,
-          "The setter '#{name}' is implicitly declared by this field "
-          "in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_GETTER_ONE:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER_ONE,
-          "'#{class}' doesn't implement the getter '#{name}' "
-          "declared in '#{declarer}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  get m;
-}
-class C implements I {}
-main() => new C();
-""", """
-abstract class I {
-  get m;
-}
-class C extends I {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_GETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_GETTER,
-          "'#{class}' doesn't implement the getter '#{name}'.",
-          howToFix: "Try adding an implementation of '#{name}' or declaring "
-                    "'#{class}' to be 'abstract'.",
-          examples: const ["""
-abstract class I {
-  get m;
-}
-abstract class J {
-  get m;
-}
-class C implements I, J {}
-main() => new C();
-""", """
-abstract class I {
-  get m;
-}
-abstract class J {
-  get m;
-}
-class C extends I implements J {}
-main() => new C();
-"""]),
-
-      MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_EXPLICIT_GETTER,
-          "The getter '#{name}' is declared here in class '#{class}'."),
-
-      MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER:
-        const MessageTemplate(MessageKind.UNIMPLEMENTED_IMPLICIT_GETTER,
-          "The getter '#{name}' is implicitly declared by this field "
-          "in class '#{class}'."),
-
-      MessageKind.EQUAL_MAP_ENTRY_KEY:
-        const MessageTemplate(MessageKind.EQUAL_MAP_ENTRY_KEY,
-          "An entry with the same key already exists in the map.",
-          howToFix:
-            "Try removing the previous entry or changing the key in one "
-            "of the entries.",
-          examples: const ["""
-main() {
-  var m = const {'foo': 1, 'foo': 2};
-}"""]),
-
-      MessageKind.BAD_INPUT_CHARACTER:
-        const MessageTemplate(MessageKind.BAD_INPUT_CHARACTER,
-          "Character U+#{characterHex} isn't allowed here.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["""
-main() {
-  String x = ç;
-}
-"""]),
-
-      MessageKind.UNTERMINATED_STRING:
-        const MessageTemplate(MessageKind.UNTERMINATED_STRING,
-          "String must end with #{quote}.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const ["""
-main() {
-  return '
-;
-}
-""",
-"""
-main() {
-  return \"
-;
-}
-""",
-"""
-main() {
-  return r'
-;
-}
-""",
-"""
-main() {
-  return r\"
-;
-}
-""",
-"""
-main() => '''
-""",
-"""
-main() => \"\"\"
-""",
-"""
-main() => r'''
-""",
-"""
-main() => r\"\"\"
-"""]),
-
-      MessageKind.UNMATCHED_TOKEN:
-        const MessageTemplate(MessageKind.UNMATCHED_TOKEN,
-          "Can't find '#{end}' to match '#{begin}'.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const[
-              "main(",
-              "main(){",
-              "main(){]}",
-            ]),
-
-      MessageKind.UNTERMINATED_TOKEN:
-        const MessageTemplate(MessageKind.UNTERMINATED_TOKEN,
-          // This is a fall-back message that shouldn't happen.
-          "Incomplete token."),
-
-      MessageKind.EXPONENT_MISSING:
-        const MessageTemplate(MessageKind.EXPONENT_MISSING,
-          "Numbers in exponential notation should always contain an exponent"
-          " (an integer number with an optional sign).",
-          howToFix:
-            "Make sure there is an exponent, and remove any whitespace "
-            "before it.",
-          examples: const ["""
-main() {
-  var i = 1e;
-}
-"""]),
-
-      MessageKind.HEX_DIGIT_EXPECTED:
-        const MessageTemplate(MessageKind.HEX_DIGIT_EXPECTED,
-          "A hex digit (0-9 or A-F) must follow '0x'.",
-          howToFix:
-            DONT_KNOW_HOW_TO_FIX, // Seems obvious from the error message.
-          examples: const ["""
-main() {
-  var i = 0x;
-}
-"""]),
-
-      MessageKind.MALFORMED_STRING_LITERAL:
-        const MessageTemplate(MessageKind.MALFORMED_STRING_LITERAL,
-          r"A '$' has special meaning inside a string, and must be followed by "
-          "an identifier or an expression in curly braces ({}).",
-          howToFix: r"Try adding a backslash (\) to escape the '$'.",
-          examples: const [r"""
-main() {
-  return '$';
-}
-""",
-r'''
-main() {
-  return "$";
-}
-''',
-r"""
-main() {
-  return '''$''';
-}
-""",
-r'''
-main() {
-  return """$""";
-}
-''']),
-
-      MessageKind.UNTERMINATED_COMMENT:
-        const MessageTemplate(MessageKind.UNTERMINATED_COMMENT,
-          "Comment starting with '/*' must end with '*/'.",
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [r"""
-main() {
-}
-/*"""]),
-
-      MessageKind.MISSING_TOKEN_BEFORE_THIS:
-        const MessageTemplate(MessageKind.MISSING_TOKEN_BEFORE_THIS,
-          "Expected '#{token}' before this.",
-          // Consider the second example below: the parser expects a ')' before
-          // 'y', but a ',' would also have worked. We don't have enough
-          // information to give a good suggestion.
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-              "main() => true ? 1;",
-              "main() => foo(x: 1 y: 2);",
-            ]),
-
-      MessageKind.MISSING_TOKEN_AFTER_THIS:
-        const MessageTemplate(MessageKind.MISSING_TOKEN_AFTER_THIS,
-          "Expected '#{token}' after this.",
-          // See [MISSING_TOKEN_BEFORE_THIS], we don't have enough information
-          // to give a good suggestion.
-          howToFix: DONT_KNOW_HOW_TO_FIX,
-          examples: const [
-              "main(x) {x}",
-"""
-class S1 {}
-class S2 {}
-class S3 {}
-class A = S1 with S2, S3
-main() => new A();
-"""
-]),
-
-      MessageKind.CONSIDER_ANALYZE_ALL:
-        const MessageTemplate(MessageKind.CONSIDER_ANALYZE_ALL,
-          "Could not find '#{main}'.  Nothing will be analyzed.",
-          howToFix: "Try using '--analyze-all' to analyze everything.",
-          examples: const ['']),
-
-      MessageKind.MISSING_MAIN:
-        const MessageTemplate(MessageKind.MISSING_MAIN,
-          "Could not find '#{main}'.",
-          howToFix: "Try adding a method named '#{main}' to your program."
-          /* No example, test uses '--analyze-only' which will produce the above
-           * message [CONSIDER_ANALYZE_ALL].  An example for a human operator
-           * would be an empty file.*/),
-
-      MessageKind.MAIN_NOT_A_FUNCTION:
-        const MessageTemplate(MessageKind.MAIN_NOT_A_FUNCTION,
-          "'#{main}' is not a function.",
-          howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
-          examples: const ['var main;']),
-
-      MessageKind.MAIN_WITH_EXTRA_PARAMETER:
-        const MessageTemplate(MessageKind.MAIN_WITH_EXTRA_PARAMETER,
-          "'#{main}' cannot have more than two parameters.",
-          howToFix: DONT_KNOW_HOW_TO_FIX, /* Don't state the obvious. */
-          examples: const ['main(a, b, c) {}']),
-
-      MessageKind.COMPILER_CRASHED:
-        const MessageTemplate(MessageKind.COMPILER_CRASHED,
-          "The compiler crashed when compiling this element."),
-
-      MessageKind.PLEASE_REPORT_THE_CRASH:
-        const MessageTemplate(MessageKind.PLEASE_REPORT_THE_CRASH, '''
-The compiler is broken.
-
-When compiling the above element, the compiler crashed. It is not
-possible to tell if this is caused by a problem in your program or
-not. Regardless, the compiler should not crash.
-
-The Dart team would greatly appreciate if you would take a moment to
-report this problem at http://dartbug.com/new.
-
-Please include the following information:
-
-* the name and version of your operating system,
-
-* the Dart SDK build number (#{buildId}), and
-
-* the entire message you see here (including the full stack trace
-  below as well as the source location above).
-'''),
-
-      MessageKind.POTENTIAL_MUTATION:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION,
-          "Variable '#{variableName}' is not known to be of type "
-          "'#{shownType}' because it is potentially mutated in the scope for "
-          "promotion."),
-
-      MessageKind.POTENTIAL_MUTATION_HERE:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_HERE,
-          "Variable '#{variableName}' is potentially mutated here."),
-
-      MessageKind.POTENTIAL_MUTATION_IN_CLOSURE:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE,
-          "Variable '#{variableName}' is not known to be of type "
-          "'#{shownType}' because it is potentially mutated within a closure."),
-
-      MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE:
-        const MessageTemplate(MessageKind.POTENTIAL_MUTATION_IN_CLOSURE_HERE,
-              "Variable '#{variableName}' is potentially mutated in a "
-              "closure here."),
-
-      MessageKind.ACCESSED_IN_CLOSURE:
-        const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE,
-          "Variable '#{variableName}' is not known to be of type "
-          "'#{shownType}' because it is accessed by a closure in the scope for "
-          "promotion and potentially mutated in the scope of "
-          "'#{variableName}'."),
-
-      MessageKind.ACCESSED_IN_CLOSURE_HERE:
-        const MessageTemplate(MessageKind.ACCESSED_IN_CLOSURE_HERE,
-          "Variable '#{variableName}' is accessed in a closure here."),
-
-      MessageKind.NOT_MORE_SPECIFIC:
-        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC,
-          "Variable '#{variableName}' is not shown to have type "
-          "'#{shownType}' because '#{shownType}' is not more specific than the "
-          "known type '#{knownType}' of '#{variableName}'."),
-
-      MessageKind.NOT_MORE_SPECIFIC_SUBTYPE:
-        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUBTYPE,
-          "Variable '#{variableName}' is not shown to have type "
-          "'#{shownType}' because '#{shownType}' is not a subtype of the "
-          "known type '#{knownType}' of '#{variableName}'."),
-
-      MessageKind.NOT_MORE_SPECIFIC_SUGGESTION:
-        const MessageTemplate(MessageKind.NOT_MORE_SPECIFIC_SUGGESTION,
-          "Variable '#{variableName}' is not shown to have type "
-          "'#{shownType}' because '#{shownType}' is not more specific than the "
-          "known type '#{knownType}' of '#{variableName}'.",
-          howToFix:
-            "Try replacing '#{shownType}' with '#{shownTypeSuggestion}'."),
-
-      MessageKind.NO_COMMON_SUBTYPES:
-        const MessageTemplate(MessageKind.NO_COMMON_SUBTYPES,
-           "Types '#{left}' and '#{right}' have no common subtypes."),
-
-      MessageKind.HIDDEN_WARNINGS_HINTS:
-        const MessageTemplate(MessageKind.HIDDEN_WARNINGS_HINTS,
-          "#{warnings} warning(s) and #{hints} hint(s) suppressed in #{uri}."),
-
-      MessageKind.HIDDEN_WARNINGS:
-        const MessageTemplate(MessageKind.HIDDEN_WARNINGS,
-          "#{warnings} warning(s) suppressed in #{uri}."),
-
-      MessageKind.HIDDEN_HINTS:
-        const MessageTemplate(MessageKind.HIDDEN_HINTS,
-          "#{hints} hint(s) suppressed in #{uri}."),
-
-      MessageKind.PREAMBLE:
-        const MessageTemplate(MessageKind.PREAMBLE,
-        "When run on the command-line, the compiled output might"
-        " require a preamble file located in:\n"
-        "  <sdk>/lib/_internal/js_runtime/lib/preambles."),
-
-      MessageKind.INVALID_SYNC_MODIFIER:
-        const MessageTemplate(MessageKind.INVALID_SYNC_MODIFIER,
-          "Invalid modifier 'sync'.",
-          options: const ['--enable-async'],
-          howToFix: "Try replacing 'sync' with 'sync*'.",
-          examples: const [
-            "main() sync {}"
-          ]),
-
-      MessageKind.INVALID_AWAIT_FOR:
-        const MessageTemplate(MessageKind.INVALID_AWAIT_FOR,
-          "'await' is only supported on for-in loops.",
-          options: const ['--enable-async'],
-          howToFix: "Try rewriting the loop as a for-in loop or removing the "
-                    "'await' keyword.",
-          examples: const ["""
-main() async* {
-  await for (int i = 0; i < 10; i++) {}
-}
-"""]),
-
-      MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD:
-        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_ABSTRACT_METHOD,
-          "The modifier '#{modifier}' is not allowed on an abstract method.",
-          options: const ['--enable-async'],
-          howToFix: "Try removing the '#{modifier}' modifier or adding a "
-                    "body to the method.",
-          examples: const ["""
-abstract class A {
-  method() async;
-}
-class B extends A {
-  method() {}
-}
-main() {
-  A a = new B();
-  a.method();
-}
-"""]),
-
-      MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_CONSTRUCTOR,
-              "The modifier '#{modifier}' is not allowed on constructors.",
-              options: const ['--enable-async'],
-              howToFix: "Try removing the '#{modifier}' modifier.",
-              examples: const ["""
-class A {
-  A() async;
-}
-main() => new A();""",
-
-"""
-class A {
-  A();
-  factory A.a() async* {}
-}
-main() => new A.a();"""]),
-
-      MessageKind.ASYNC_MODIFIER_ON_SETTER:
-        const MessageTemplate(MessageKind.ASYNC_MODIFIER_ON_SETTER,
-              "The modifier '#{modifier}' is not allowed on setters.",
-              options: const ['--enable-async'],
-              howToFix: "Try removing the '#{modifier}' modifier.",
-              examples: const ["""
-class A {
-  set foo(v) async {}
-}
-main() => new A().foo = 0;"""]),
-
-      MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY:
-        const MessageTemplate(MessageKind.YIELDING_MODIFIER_ON_ARROW_BODY,
-          "The modifier '#{modifier}' is not allowed on methods implemented "
-          "using '=>'.",
-          options: const ['--enable-async'],
-          howToFix: "Try removing the '#{modifier}' modifier or implementing "
-                    "the method body using a block: '{ ... }'.",
-          examples: const ["main() sync* => null;", "main() async* => null;"]),
-
-      // TODO(johnniwinther): Check for 'async' as identifier.
-      MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER:
-        const MessageTemplate(MessageKind.ASYNC_KEYWORD_AS_IDENTIFIER,
-          "'#{keyword}' cannot be used as an identifier in a function body "
-          "marked with '#{modifier}'.",
-          options: const ['--enable-async'],
-          howToFix: "Try removing the '#{modifier}' modifier or renaming the "
-                    "identifier.",
-          examples: const ["""
-main() async {
- var await;
-}""",
-"""
-main() async* {
- var yield;
-}""",
-"""
-main() sync* {
- var yield;
-}"""]),
-
-      MessageKind.RETURN_IN_GENERATOR:
-        const MessageTemplate(MessageKind.RETURN_IN_GENERATOR,
-          "'return' with a value is not allowed in a method body using the "
-          "'#{modifier}' modifier.",
-          howToFix: "Try removing the value, replacing 'return' with 'yield' "
-                    "or changing the method body modifier.",
-          examples: const [
-"""
-foo() async* { return 0; }
-main() => foo();
-""",
-
-"""
-foo() sync* { return 0; }
-main() => foo();
-"""]),
-
-      MessageKind.NATIVE_NOT_SUPPORTED:
-        const MessageTemplate(MessageKind.NATIVE_NOT_SUPPORTED,
-          "'native' modifier is not supported.",
-          howToFix: "Try removing the 'native' implementation or analyzing the "
-                    "code with the --allow-native-extensions option.",
-          examples: const ["""
-main() native "Main";
-"""]),
-
-      MessageKind.DART_EXT_NOT_SUPPORTED:
-        const MessageTemplate(MessageKind.DART_EXT_NOT_SUPPORTED,
-          "The 'dart-ext' scheme is not supported.",
-          howToFix: "Try analyzing the code with the --allow-native-extensions "
-                    "option.",
-          examples: const ["""
-import 'dart-ext:main';
-
-main() {}
-"""]),
-
-      MessageKind.LIBRARY_TAG_MUST_BE_FIRST:
-        const MessageTemplate(MessageKind.LIBRARY_TAG_MUST_BE_FIRST,
-          "The library declaration should come before other declarations.",
-          howToFix: "Try moving the declaration to the top of the file.",
-          examples: const [
-"""
-import 'dart:core';
-library foo;
-main() {}
-""",
-      ]),
-
-      MessageKind.ONLY_ONE_LIBRARY_TAG:
-        const MessageTemplate(MessageKind.ONLY_ONE_LIBRARY_TAG,
-          "There can only be one library declaration.",
-          howToFix: "Try removing all other library declarations.",
-          examples: const [
-"""
-library foo;
-library bar;
-main() {}
-""",
-"""
-library foo;
-import 'dart:core';
-library bar;
-main() {}
-""",
-      ]),
-
-      MessageKind.IMPORT_BEFORE_PARTS:
-        const MessageTemplate(MessageKind.IMPORT_BEFORE_PARTS,
-          "Import declarations should come before parts.",
-          howToFix: "Try moving this import further up in the file.",
-          examples: const [
-              const <String, String>{
-                'main.dart': """
-library test.main;
-part 'part.dart';
-import 'dart:core';
-main() {}
-""",
-                'part.dart': """
-part of test.main;
-""",
-          }]),
-
-      MessageKind.EXPORT_BEFORE_PARTS:
-        const MessageTemplate(MessageKind.EXPORT_BEFORE_PARTS,
-          "Export declarations should come before parts.",
-          howToFix: "Try moving this export further up in the file.",
-          examples: const [
-              const <String, String>{
-                'main.dart': """
-library test.main;
-part 'part.dart';
-export 'dart:core';
-main() {}
-""",
-               'part.dart': """
-part of test.main;
-""",
-          }]),
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Patch errors start.
-  //////////////////////////////////////////////////////////////////////////////
-
-      MessageKind.PATCH_RETURN_TYPE_MISMATCH:
-        const MessageTemplate(MessageKind.PATCH_RETURN_TYPE_MISMATCH,
-          "Patch return type '#{patchReturnType}' does not match "
-          "'#{originReturnType}' on origin method '#{methodName}'."),
-
-      MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH:
-        const MessageTemplate(
-          MessageKind.PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
-          "Required parameter count of patch method "
-          "(#{patchParameterCount}) does not match parameter count on origin "
-          "method '#{methodName}' (#{originParameterCount})."),
-
-      MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH:
-        const MessageTemplate(
-          MessageKind.PATCH_OPTIONAL_PARAMETER_COUNT_MISMATCH,
-          "Optional parameter count of patch method "
-          "(#{patchParameterCount}) does not match parameter count on origin "
-          "method '#{methodName}' (#{originParameterCount})."),
-
-      MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH:
-        const MessageTemplate(
-          MessageKind.PATCH_OPTIONAL_PARAMETER_NAMED_MISMATCH,
-          "Optional parameters of origin and patch method "
-          "'#{methodName}' must both be either named or positional."),
-
-      MessageKind.PATCH_PARAMETER_MISMATCH:
-        const MessageTemplate(MessageKind.PATCH_PARAMETER_MISMATCH,
-          "Patch method parameter '#{patchParameter}' does not match "
-          "'#{originParameter}' on origin method '#{methodName}'."),
-
-      MessageKind.PATCH_PARAMETER_TYPE_MISMATCH:
-        const MessageTemplate(MessageKind.PATCH_PARAMETER_TYPE_MISMATCH,
-          "Patch method parameter '#{parameterName}' type "
-          "'#{patchParameterType}' does not match '#{originParameterType}' on "
-          "origin method '#{methodName}'."),
-
-      MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION:
-        const MessageTemplate(MessageKind.PATCH_EXTERNAL_WITHOUT_IMPLEMENTATION,
-          "External method without an implementation."),
-
-      MessageKind.PATCH_POINT_TO_FUNCTION:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_FUNCTION,
-          "This is the function patch '#{functionName}'."),
-
-      MessageKind.PATCH_POINT_TO_CLASS:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_CLASS,
-          "This is the class patch '#{className}'."),
-
-      MessageKind.PATCH_POINT_TO_GETTER:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_GETTER,
-          "This is the getter patch '#{getterName}'."),
-
-      MessageKind.PATCH_POINT_TO_SETTER:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_SETTER,
-          "This is the setter patch '#{setterName}'."),
-
-      MessageKind.PATCH_POINT_TO_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_CONSTRUCTOR,
-          "This is the constructor patch '#{constructorName}'."),
-
-      MessageKind.PATCH_POINT_TO_PARAMETER:
-        const MessageTemplate(MessageKind.PATCH_POINT_TO_PARAMETER,
-          "This is the patch parameter '#{parameterName}'."),
-
-      MessageKind.PATCH_NON_EXISTING:
-        const MessageTemplate(MessageKind.PATCH_NON_EXISTING,
-          "Origin does not exist for patch '#{name}'."),
-
-      // TODO(ahe): Eventually, this error should be removed as it will be
-      // handled by the regular parser.
-      MessageKind.PATCH_NONPATCHABLE:
-        const MessageTemplate(MessageKind.PATCH_NONPATCHABLE,
-          "Only classes and functions can be patched."),
-
-      MessageKind.PATCH_NON_EXTERNAL:
-        const MessageTemplate(MessageKind.PATCH_NON_EXTERNAL,
-          "Only external functions can be patched."),
-
-      MessageKind.PATCH_NON_CLASS:
-        const MessageTemplate(MessageKind.PATCH_NON_CLASS,
-          "Patching non-class with class patch '#{className}'."),
-
-      MessageKind.PATCH_NON_GETTER:
-        const MessageTemplate(MessageKind.PATCH_NON_GETTER,
-          "Cannot patch non-getter '#{name}' with getter patch."),
-
-      MessageKind.PATCH_NO_GETTER:
-        const MessageTemplate(MessageKind.PATCH_NO_GETTER,
-          "No getter found for getter patch '#{getterName}'."),
-
-      MessageKind.PATCH_NON_SETTER:
-        const MessageTemplate(MessageKind.PATCH_NON_SETTER,
-          "Cannot patch non-setter '#{name}' with setter patch."),
-
-      MessageKind.PATCH_NO_SETTER:
-        const MessageTemplate(MessageKind.PATCH_NO_SETTER,
-          "No setter found for setter patch '#{setterName}'."),
-
-      MessageKind.PATCH_NON_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.PATCH_NON_CONSTRUCTOR,
-          "Cannot patch non-constructor with constructor patch "
-          "'#{constructorName}'."),
-
-      MessageKind.PATCH_NON_FUNCTION:
-        const MessageTemplate(MessageKind.PATCH_NON_FUNCTION,
-          "Cannot patch non-function with function patch "
-          "'#{functionName}'."),
-
-      MessageKind.INJECTED_PUBLIC_MEMBER:
-        const MessageTemplate(MessageKind.INJECTED_PUBLIC_MEMBER,
-            "Non-patch members in patch libraries must be private."),
-
-      MessageKind.EXTERNAL_WITH_BODY:
-        const MessageTemplate(MessageKind.EXTERNAL_WITH_BODY,
-          "External function '#{functionName}' cannot have a function body.",
-          options: const ["--output-type=dart"],
-          howToFix:
-            "Try removing the 'external' modifier or the function body.",
-          examples: const ["""
-external foo() => 0;
-main() => foo();
-""", """
-external foo() {}
-main() => foo();
-"""]),
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Patch errors end.
-  //////////////////////////////////////////////////////////////////////////////
-
-      MessageKind.EXPERIMENTAL_ASSERT_MESSAGE:
-        const MessageTemplate(MessageKind.EXPERIMENTAL_ASSERT_MESSAGE,
-          "Experimental language feature 'assertion with message'"
-          " is not supported.",
-          howToFix:
-            "Use option '--assert-message' to use assertions with messages.",
-          examples: const [r'''
-main() {
-  int n = -7;
-  assert(n > 0, 'must be positive: $n');
-}
-''']),
-
-      MessageKind.IMPORT_EXPERIMENTAL_MIRRORS:
-        const MessageTemplate(MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, r'''
-
-****************************************************************
-* WARNING: dart:mirrors support in dart2js is experimental,
-*          and not recommended.
-*          This implementation of mirrors is incomplete,
-*          and often greatly increases the size of the generated
-*          JavaScript code.
-*
-* Your app imports dart:mirrors via:''''''
-$IMPORT_EXPERIMENTAL_MIRRORS_PADDING#{importChain}
-*
-* You can disable this message by using the --enable-experimental-mirrors
-* command-line flag.
-*
-* To learn what to do next, please visit:
-*    http://dartlang.org/dart2js-reflection
-****************************************************************
-'''),
-
-      MessageKind.DISALLOWED_LIBRARY_IMPORT:
-        const MessageTemplate(MessageKind.DISALLOWED_LIBRARY_IMPORT, '''
-Your app imports the unsupported library '#{uri}' via:
-''''''
-$DISALLOWED_LIBRARY_IMPORT_PADDING#{importChain}
-
-Use the --categories option to support import of '#{uri}'.
-'''),
-
-      MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND:
-        const MessageTemplate(
-          MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND,
-          """
-dart:mirrors library is not supported when using this backend.
-
-Your app imports dart:mirrors via:""""""
-$MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING#{importChain}"""),
-
-      MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS:
-        const MessageTemplate(MessageKind.CALL_NOT_SUPPORTED_ON_NATIVE_CLASS,
-          "Non-supported 'call' member on a native class, or a "
-          "subclass of a native class."),
-
-      MessageKind.DIRECTLY_THROWING_NSM:
-        const MessageTemplate(MessageKind.DIRECTLY_THROWING_NSM,
-          "This 'noSuchMethod' implementation is guaranteed to throw an "
-          "exception. The generated code will be smaller if it is "
-          "rewritten.",
-          howToFix: "Rewrite to "
-                    "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
-
-      MessageKind.COMPLEX_THROWING_NSM:
-        const MessageTemplate(MessageKind.COMPLEX_THROWING_NSM,
-          "This 'noSuchMethod' implementation is guaranteed to throw an "
-          "exception. The generated code will be smaller and the compiler "
-          "will be able to perform more optimizations if it is rewritten.",
-          howToFix: "Rewrite to "
-                    "'noSuchMethod(Invocation i) => super.noSuchMethod(i);'."),
-
-      MessageKind.COMPLEX_RETURNING_NSM:
-        const MessageTemplate(MessageKind.COMPLEX_RETURNING_NSM,
-          "Overriding 'noSuchMethod' causes the compiler to generate "
-          "more code and prevents the compiler from doing some optimizations.",
-          howToFix: "Consider removing this 'noSuchMethod' implementation."),
-
-      MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP:
-        const MessageTemplate(MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP,
-          "Unsupported version of package:lookup_map.",
-          howToFix: DONT_KNOW_HOW_TO_FIX),
-
-  }; // End of TEMPLATES.
-
-  /// Padding used before and between import chains in the message for
-  /// [MessageKind.IMPORT_EXPERIMENTAL_MIRRORS].
-  static const String IMPORT_EXPERIMENTAL_MIRRORS_PADDING = '\n*   ';
-
-  /// Padding used before and between import chains in the message for
-  /// [MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND].
-  static const String MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING = '\n   ';
-
-  /// Padding used before and between import chains in the message for
-  /// [MessageKind.DISALLOWED_LIBRARY_IMPORT].
-  static const String DISALLOWED_LIBRARY_IMPORT_PADDING = '\n  ';
+  const MessageTemplate(this.kind, this.id, this.template, this.howToFix,
+      this.examples, this.options);
 
   toString() => template;
 
@@ -3577,7 +898,42 @@
     return new Message(this, arguments, terse);
   }
 
-  bool get hasHowToFix => howToFix != null && howToFix != DONT_KNOW_HOW_TO_FIX;
+  bool get hasHowToFix =>
+      howToFix != null && howToFix != dart2js_messages.DONT_KNOW_HOW_TO_FIX;
+
+  static final Map<MessageKind, MessageTemplate> TEMPLATES =
+      _constructMessageTemplates();
+
+  static String get IMPORT_EXPERIMENTAL_MIRRORS_PADDING =>
+      dart2js_messages.IMPORT_EXPERIMENTAL_MIRRORS_PADDING;
+
+  static String get MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING =>
+      dart2js_messages.MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING;
+
+  static String get DISALLOWED_LIBRARY_IMPORT_PADDING =>
+      dart2js_messages.DISALLOWED_LIBRARY_IMPORT_PADDING;
+
+  static Map<MessageKind, MessageTemplate> _constructMessageTemplates() {
+    Map<MessageKind, MessageTemplate> result = <MessageKind, MessageTemplate>{};
+    for (MessageKind kind in MessageKind.values) {
+      String name = _KIND_TO_STRING_MAP[kind];
+      if (name == null) {
+        throw new ArgumentError("No mapping for $kind in _KIND_TO_STRING_MAP");
+      }
+      Map data =
+          shared_messages.MESSAGES[name] ?? dart2js_messages.MESSAGES[name];
+      if (data == null) throw new ArgumentError.value(name);
+
+      String id = data['id'];
+      String template = data['template'];
+      String howToFix = data['howToFix'];
+      List examples = data['examples'];
+      List<String> options = data['options'] ?? const <String>[];
+      result[kind] =
+          new MessageTemplate(kind, id, template, howToFix, examples, options);
+    }
+    return result;
+  }
 }
 
 class Message {
@@ -3587,7 +943,10 @@
   String message;
 
   Message(this.template, this.arguments, this.terse) {
-    assert(() { computeMessage(); return true; });
+    assert(() {
+      computeMessage();
+      return true;
+    });
   }
 
   MessageKind get kind => template.kind;
@@ -3601,7 +960,7 @@
       assert(invariant(
           CURRENT_ELEMENT_SPANNABLE,
           kind == MessageKind.GENERIC ||
-            !message.contains(new RegExp(r'#\{.+\}')),
+              !message.contains(new RegExp(r'#\{.+\}')),
           message: 'Missing arguments in error message: "$message"'));
       if (!terse && template.hasHowToFix) {
         String howToFix = template.howToFix;
@@ -3618,8 +977,8 @@
     return computeMessage();
   }
 
-  bool operator==(other) {
-    if (other is !Message) return false;
+  bool operator ==(other) {
+    if (other is! Message) return false;
     return (template == other.template) && (toString() == other.toString());
   }
 
diff --git a/pkg/compiler/lib/src/diagnostics/shared_messages.dart b/pkg/compiler/lib/src/diagnostics/shared_messages.dart
new file mode 100644
index 0000000..0a4d2ab
--- /dev/null
+++ b/pkg/compiler/lib/src/diagnostics/shared_messages.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This file is parsed by JavaScript and must not use fancy Dart constructs.
+// It can contain JSON like constructs and "//" comments (but not "/*" "*/").
+// It must have one assignment (`final MESSAGES =`).
+// All strings must be raw strings.
+
+// The messages in this file should meet the following guide lines:
+//
+// 1. The message should be a complete sentence starting with an uppercase
+// letter, and ending with a period.
+//
+// 2. Reserved words and embedded identifiers should be in single quotes, so
+// prefer double quotes for the complete message. For example, "The
+// class '#{className}' can't use 'super'." Notice that the word 'class' in the
+// preceding message is not quoted as it refers to the concept 'class', not the
+// reserved word. On the other hand, 'super' refers to the reserved word. Do
+// not quote 'null' and numeric literals.
+//
+// 3. Do not try to compose messages, as it can make translating them hard.
+//
+// 4. Try to keep the error messages short, but informative.
+//
+// 5. Use simple words and terminology, assume the reader of the message
+// doesn't have an advanced degree in math, and that English is not the
+// reader's native language. Do not assume any formal computer science
+// training. For example, do not use Latin abbreviations (prefer "that is" over
+// "i.e.", and "for example" over "e.g."). Also avoid phrases such as "if and
+// only if" and "iff", that level of precision is unnecessary.
+//
+// 6. Prefer contractions when they are in common use, for example, prefer
+// "can't" over "cannot". Using "cannot", "must not", "shall not", etc. is
+// off-putting to people new to programming.
+//
+// 7. Use common terminology, preferably from the Dart Language
+// Specification. This increases the user's chance of finding a good
+// explanation on the web.
+//
+// 8. Do not try to be cute or funny. It is extremely frustrating to work on a
+// product that crashes with a "tongue-in-cheek" message, especially if you did
+// not want to use this product to begin with.
+//
+// 9. Do not lie, that is, do not write error messages containing phrases like
+// "can't happen".  If the user ever saw this message, it would be a
+// lie. Prefer messages like: "Internal error: This function should not be
+// called when 'x' is null.".
+//
+// 10. Prefer to not use imperative tone. That is, the message should not sound
+// accusing or like it is ordering the user around. The computer should
+// describe the problem, not criticize for violating the specification.
+//
+// Other things to keep in mind:
+//
+// Generally, we want to provide messages that consists of three sentences:
+// 1. what is wrong, 2. why is it wrong, 3. how do I fix it. However, we
+// combine the first two in [template] and the last in [howToFix].
+
+final MESSAGES = {
+};
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 95b2b2a..5549f45 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -785,9 +785,9 @@
   void setPartOf(PartOf tag, DiagnosticReporter reporter) {
     LibraryElementX library = enclosingElement;
     if (library.entryCompilationUnit == this) {
+      // This compilation unit is loaded as a library. The error is reported by
+      // the library loader.
       partTag = tag;
-      reporter.reportErrorMessage(
-          tag, MessageKind.IMPORT_PART_OF);
       return;
     }
     if (!localMembers.isEmpty) {
diff --git a/pkg/compiler/lib/src/js/placeholder_safety.dart b/pkg/compiler/lib/src/js/placeholder_safety.dart
new file mode 100644
index 0000000..67ff563
--- /dev/null
+++ b/pkg/compiler/lib/src/js/placeholder_safety.dart
@@ -0,0 +1,327 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+
+library js.safety;
+
+import "js.dart" as js;
+
+typedef bool PositionPredicate(int position);
+
+/// PlaceholderSafetyAnalysis determines which placeholders in a JavaScript
+/// template may be replaced with an arbitrary expression. Placeholders may be
+/// replaced with an arbitrary expression providied the template ensures the
+/// placeholders are evaluated in the same left-to-right order with no
+/// additional effects interleaved.
+///
+/// The result is semi-conservative, giving reasonable results for many simple
+/// JS fragments. The non-conservative part is the assumption that arithmetic
+/// operators are used on 'good' operands that do not force arbitrary code to be
+/// executed via conversions (valueOf() and toString() methods).
+class PlaceholderSafetyAnalysis extends js.BaseVisitor<int> {
+  final PositionPredicate isNullableInput;
+  int nextPosition = 0;
+  int maxSafePosition = -1;
+  bool safe = true;
+
+  // We do a crude abstract interpretation to find operations that might throw
+  // exceptions. The possible values of expressions are represented by
+  // integers. Small non-negative integers 0, 1, 2, ... represent the values of
+  // the placeholders. Other values are:
+  static const int NONNULL_VALUE = -1;  // Unknown but not null.
+  static const int UNKNOWN_VALUE = -2;  // Unknown and might be null.
+
+  PlaceholderSafetyAnalysis._(this.isNullableInput);
+
+  /// Returns the number of placeholders that can be substituted into the
+  /// template AST [node] without changing the order of observable effects.
+  /// [isNullableInput] is a function that takes the 0-based index of a
+  /// placeholder and returns `true` if expression at run time may be null, and
+  /// `false` if the value is never null.
+  static int analyze(js.Node node, PositionPredicate isNullableInput) {
+    PlaceholderSafetyAnalysis analysis =
+        new PlaceholderSafetyAnalysis._(isNullableInput);
+    analysis.visit(node);
+    return analysis.maxSafePosition + 1;
+  }
+
+  bool canBeNull(int value) {
+    if (value == NONNULL_VALUE) return false;
+    if (value == UNKNOWN_VALUE) return true;
+    return isNullableInput(value);
+  }
+
+  int unsafe(int value) {
+    safe = false;
+    return value;
+  }
+
+  int visit(js.Node node) {
+    return node.accept(this);
+  }
+
+  int visitNode(js.Node node) {
+    safe = false;
+    super.visitNode(node);
+    return UNKNOWN_VALUE;
+  }
+
+  int visitLiteralNull(js.LiteralNull node) {
+    return UNKNOWN_VALUE;
+  }
+
+  int visitLiteral(js.Literal node) {
+    return NONNULL_VALUE;
+  }
+
+  int handleInterpolatedNode(js.InterpolatedNode node) {
+    assert(node.isPositional);
+    int position = nextPosition++;
+    if (safe) maxSafePosition = position;
+    return position;
+  }
+
+  int visitInterpolatedExpression(js.InterpolatedExpression node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedLiteral(js.InterpolatedLiteral node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedSelector(js.InterpolatedSelector node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedStatement(js.InterpolatedStatement node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitInterpolatedDeclaration(js.InterpolatedDeclaration node) {
+    return handleInterpolatedNode(node);
+  }
+
+  int visitObjectInitializer(js.ObjectInitializer node) {
+    for (js.Property property in node.properties) {
+      visit(property);
+    }
+    return NONNULL_VALUE;
+  }
+
+  int visitProperty(js.Property node) {
+    visit(node.name);
+    visit(node.value);
+    return UNKNOWN_VALUE;
+  }
+
+  int visitArrayInitializer(js.ArrayInitializer node) {
+    node.elements.forEach(visit);
+    return NONNULL_VALUE;
+  }
+
+  int visitArrayHole(js.ArrayHole node) {
+    return UNKNOWN_VALUE;
+  }
+
+  int visitAccess(js.PropertyAccess node) {
+    int first = visit(node.receiver);
+    int second = visit(node.selector);
+    // TODO(sra): If the JS is annotated as never throwing, we can avoid this.
+    if (canBeNull(first)) safe = false;
+    return UNKNOWN_VALUE;
+  }
+
+  int visitAssignment(js.Assignment node) {
+    js.Expression left = node.leftHandSide;
+    js.Expression right = node.value;
+
+    int leftToRight() {
+      visit(left);
+      visit(right);
+      return UNKNOWN_VALUE;
+    }
+
+    if (left is js.InterpolatedNode) {
+      // A bare interpolated expression should not be the LHS of an assignment.
+      safe = false;
+      return leftToRight();
+    }
+    
+    // Assignment operators dereference the LHS before evaluating the RHS.
+    if (node.op != null) return leftToRight();
+
+    // Assignment (1) evaluates the LHS as a Reference `lval`, (2) evaluates the
+    // RHS as a value, (3) dereferences the `lval` in PutValue.
+    if (left is js.VariableReference) {
+      int value = visit(right); 
+      // Assignment could change an observed global or cause a ReferenceError.
+      safe = false;
+      return value;
+    }
+    if (left is js.PropertyAccess) {
+      // "a.b.x = c.y" gives a TypeError for null values in this order: `a`,
+      // `c`, `a.b`.
+      int receiver = visit(left.receiver);
+      int selector = visit(left.selector);
+      int value = visit(right);
+      if (canBeNull(receiver)) safe = false;
+      return value;
+    }
+    // Be conserative with unrecognized LHS expressions.
+    safe = false;
+    return leftToRight();
+  }
+
+  int visitCall(js.Call node) {
+    // TODO(sra): Recognize JavaScript built-ins like
+    // 'Object.prototype.hasOwnProperty.call'.
+    visit(node.target);
+    node.arguments.forEach(visit);
+    return unsafe(UNKNOWN_VALUE);
+  }
+
+  int visitNew(js.New node) {
+    visit(node.target);
+    node.arguments.forEach(visit);
+    return unsafe(NONNULL_VALUE);
+  }
+
+  int visitBinary(js.Binary node) {
+    switch (node.op) {
+      // We make the non-conservative assumption that these operations are not
+      // used in ways that force calling arbitrary code via valueOf() or
+      // toString().
+      case "*":
+      case "/":
+      case "%":
+      case "+":
+      case "-":
+      case "<<":
+      case ">>":
+      case ">>>":
+      case "<":
+      case ">":
+      case "<=":
+      case ">=":
+      case "==":
+      case "===":
+      case "!=":
+      case "!==":
+      case "&":
+      case "^":
+      case "|":
+        int left = visit(node.left);
+        int right = visit(node.right);
+        return NONNULL_VALUE;  // Number, String, Boolean.
+
+      case ',':
+        int left = visit(node.left);
+        int right = visit(node.right);
+        return right;
+
+      case "&&":
+      case "||":
+        int left = visit(node.left);
+        // TODO(sra): Might be safe, e.g.  "x || 0".
+        safe = false;
+        int right = visit(node.right);
+        return UNKNOWN_VALUE;
+
+      case "instanceof":
+      case "in":
+        int left = visit(node.left);
+        int right = visit(node.right);
+        return UNKNOWN_VALUE;
+
+      default:
+        return unsafe(UNKNOWN_VALUE);
+    }
+  }
+
+  int visitConditional(js.Conditional node) {
+    int cond = visit(node.condition);
+    // TODO(sra): Might be safe, e.g.  "# ? 1 : 2".
+    safe = false;
+    int thenValue = visit(node.then);
+    int elseValue = visit(node.otherwise);
+    return UNKNOWN_VALUE;
+  }
+
+  int visitThrow(js.Throw node) {
+    visit(node.expression);
+    return unsafe(UNKNOWN_VALUE);
+  }
+
+  int visitPrefix(js.Prefix node) {
+    if (node.op == 'typeof') {
+      // "typeof a" first evaluates to a Reference. If the Reference is to a
+      // variable that is not present, "undefined" is returned without
+      // dereferencing.
+      if (node.argument is js.VariableUse) return NONNULL_VALUE;  // A string.
+    }
+
+    visit(node.argument);
+
+    switch (node.op) {
+      case '+':
+      case '-':
+      case '!':
+      case '~':
+        // Non-conservative assumption that these operators are used on values
+        // that do not call arbitrary code via valueOf() or toString().
+        return NONNULL_VALUE;
+
+      case 'typeof':
+        return NONNULL_VALUE;  // Always a string.
+
+      case 'void':
+        return UNKNOWN_VALUE;
+
+      case '--':
+      case '++':
+        return NONNULL_VALUE;  // Always a number.
+
+      default:
+        safe = false;
+        return UNKNOWN_VALUE;
+    }
+  }
+
+  int visitPostfix(js.Postfix node) {
+    assert(node.op == '--' || node.op == '++');
+    visit(node.argument);
+    return NONNULL_VALUE;  // Always a number, even for "(a=null, a++)".
+  }
+
+  int visitVariableUse(js.VariableUse node) {
+    // We could get a ReferenceError unless the variable is in scope.  For JS
+    // fragments, the only use of VariableUse outside a `function(){...}` should
+    // be for global references. Certain global names are almost certainly not
+    // reference errors, e.g 'Array'.
+    switch (node.name) {
+      case 'Array':
+      case 'Date':
+      case 'Function':
+      case 'Number':
+      case 'Object':
+      case 'RegExp':
+      case 'String':
+      case 'self':
+      case 'window':
+        return NONNULL_VALUE;
+      default:
+        return unsafe(UNKNOWN_VALUE);
+    }
+  }
+
+  int visitFun(js.Fun node) {
+    bool oldSafe = safe;
+    int oldNextPosition = nextPosition;
+    visit(node.body);
+    // Creating a function has no effect on order unless there are embedded
+    // placeholders.
+    safe = (nextPosition == oldNextPosition) && oldSafe;
+    return NONNULL_VALUE;
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 768a072..4cd691e 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1888,6 +1888,8 @@
 
   @override
   int visitDeferred(DeferredConstantValue constant, [_]) {
+    // TODO(sra): Investigate that the use of hashCode here is probably a source
+    // of instability.
     int hash = constant.prefix.hashCode;
     return _combine(hash, _visit(constant.referenced));
   }
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
new file mode 100644
index 0000000..8e574c8
--- /dev/null
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -0,0 +1,213 @@
+// Copyright (c) 2012, 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 dart2js.js_emitter.constant_ordering;
+
+import '../constants/values.dart';
+
+import '../common.dart';
+//import '../core_types.dart';
+import '../dart_types.dart';
+import '../elements/elements.dart'
+    show Element,
+         Elements,
+         FieldElement;
+import '../tree/tree.dart' show DartString;
+import '../js_backend/js_backend.dart' show SyntheticConstantKind;
+
+/// A canonical but arbrary ordering of constants. The ordering is 'stable'
+/// under perturbation of the source.
+int deepCompareConstants(ConstantValue a, ConstantValue b) {
+  return _CompareVisitor.compareValues(a, b);
+}
+
+class _CompareVisitor implements ConstantValueVisitor<int, ConstantValue> {
+  const _CompareVisitor();
+
+  static int compareValues(ConstantValue a, ConstantValue b) {
+    if (identical(a, b)) return 0;
+    int r = _KindVisitor.kind(a).compareTo(_KindVisitor.kind(b));
+    if (r != 0) return r;
+    r = a.accept(const _CompareVisitor(), b);
+    return r;
+  }
+
+  static int compareNullable(int compare(a, b), a, b) {
+    if (a == null && b == null) return 0;
+    if (a == null) return -1;
+    if (b == null) return 1;
+    return compare(a, b);
+  }
+
+  static int compareLists(int compare(a, b), List a, List b) {
+    int r = a.length.compareTo(b.length);
+    if (r != 0) return r;
+    for (int i = 0; i < a.length; i++) {
+      r = compare(a[i], b[i]);
+      if (r != 0) return r;
+    }
+    return 0;
+  }
+
+  static int compareElements(Element a, Element b) {
+    int r = a.name.compareTo(b.name);
+    if (r != 0) return r;
+    return Elements.compareByPosition(a, b);
+  }
+
+  static int compareDartTypes(DartType a, DartType b) {
+    if (a == b) return 0;
+    int r = a.kind.index.compareTo(b.kind.index);
+    if (r != 0) return r;
+    r = compareNullable(compareElements, a.element, b.element);
+    if (r != 0) return r;
+
+    if (a is GenericType) {
+      GenericType aGeneric = a;
+      GenericType bGeneric = b;
+      r = compareLists(compareDartTypes,
+                       aGeneric.typeArguments, bGeneric.typeArguments);
+      if (r != 0) return r;
+    }
+    throw 'unexpected compareDartTypes  $a  $b';
+  }
+
+  int visitFunction(FunctionConstantValue a, FunctionConstantValue b) {
+    return compareElements(a.element, b.element);
+  }
+
+  int visitNull(NullConstantValue a, NullConstantValue b) {
+    return 0;
+  }
+
+  int visitInt(IntConstantValue a, IntConstantValue b) {
+    return a.primitiveValue.compareTo(b.primitiveValue);
+  }
+
+  int visitDouble(DoubleConstantValue a, DoubleConstantValue b) {
+    return a.primitiveValue.compareTo(b.primitiveValue);
+  }
+
+  int visitBool(BoolConstantValue a, BoolConstantValue b) {
+    int aInt = a.primitiveValue ? 1 : 0;
+    int bInt = b.primitiveValue ? 1 : 0;
+    return aInt.compareTo(bInt);
+  }
+
+  int visitString(StringConstantValue a, StringConstantValue b) {
+    DartString aString = a.primitiveValue;
+    DartString bString = b.primitiveValue;
+    int r = aString.length.compareTo(bString.length);
+    if (r != 0) return r;
+    return aString.slowToString().compareTo(bString.slowToString());
+  }
+
+  int visitList(ListConstantValue a, ListConstantValue b) {
+    int r = compareLists(compareValues, a.entries, b.entries);
+    if (r != 0) return r;
+    return compareDartTypes(a.type, b.type);
+  }
+
+  int visitMap(MapConstantValue a, MapConstantValue b) {
+    int r = compareLists(compareValues, a.keys, b.keys);
+    if (r != 0) return r;
+    r = compareLists(compareValues, a.values, b.values);
+    if (r != 0) return r;
+    return compareDartTypes(a.type, b.type);
+  }
+
+  int visitConstructed(ConstructedConstantValue a, ConstructedConstantValue b) {
+    int r = compareDartTypes(a.type, b.type);
+    if (r != 0) return r;
+
+    List<FieldElement> aFields = a.fields.keys.toList()..sort(compareElements);
+    List<FieldElement> bFields = b.fields.keys.toList()..sort(compareElements);
+
+    r = compareLists(compareElements, aFields, bFields);
+    if (r != 0) return r;
+
+    return compareLists(compareValues,
+        aFields.map((field) => a.fields[field]).toList(),
+        aFields.map((field) => b.fields[field]).toList());
+  }
+
+  int visitType(TypeConstantValue a, TypeConstantValue b) {
+    int r = compareDartTypes(a.representedType, b.representedType);
+    if (r != 0) return r;
+    return compareDartTypes(a.type, b.type);
+  }
+
+  int visitInterceptor(InterceptorConstantValue a, InterceptorConstantValue b) {
+    return compareDartTypes(a.dispatchedType, b.dispatchedType);
+  }
+
+  int visitSynthetic(SyntheticConstantValue a, SyntheticConstantValue b) {
+    // [SyntheticConstantValue]s have abstract fields that are set only by
+    // convention.  Lucky for us, they do not occur as top level constant, only
+    // as elements of a few constants.  If this becomes a source of instability,
+    // we will need to add a total ordering on JavaScript ASTs including
+    // deferred elements.
+    SyntheticConstantKind aKind = a.kind;
+    SyntheticConstantKind bKind = b.kind;
+    int r = aKind.index - bKind.index;
+    if (r != 0) return r;
+    switch (a.kind) {
+      case SyntheticConstantKind.DUMMY_INTERCEPTOR:
+      case SyntheticConstantKind.EMPTY_VALUE:
+        // Never emitted.
+        return 0;
+
+      case SyntheticConstantKind.TYPEVARIABLE_REFERENCE:
+        // An opaque deferred JS AST reference to a type in reflection data.
+        return 0;
+      case SyntheticConstantKind.NAME:
+        // An opaque deferred JS AST reference to a name.
+        return 0;
+      default:
+        // Should not happen.
+        throw 'unexpected SyntheticConstantKind $aKind';
+    }
+  }
+
+  int visitDeferred(DeferredConstantValue a, DeferredConstantValue b) {
+    int r = compareValues(a.referenced, b.referenced);
+    if (r != 0) return r;
+    return compareElements(a.prefix, b.prefix);
+  }
+}
+
+class _KindVisitor implements ConstantValueVisitor<int, Null> {
+  const _KindVisitor();
+
+  static const int FUNCTION = 1;
+  static const int NULL = 2;
+  static const int INT = 3;
+  static const int DOUBLE = 4;
+  static const int BOOL = 5;
+  static const int STRING = 6;
+  static const int LIST = 7;
+  static const int MAP = 8;
+  static const int CONSTRUCTED = 9;
+  static const int TYPE = 10;
+  static const int INTERCEPTOR = 11;
+  static const int SYNTHETIC = 12;
+  static const int DEFERRED = 13;
+
+  static int kind(ConstantValue constant) =>
+      constant.accept(const _KindVisitor(), null);
+
+  int visitFunction(FunctionConstantValue a, _) => FUNCTION;
+  int visitNull(NullConstantValue a, _) => NULL;
+  int visitInt(IntConstantValue a, _) => INT;
+  int visitDouble(DoubleConstantValue a, _) => DOUBLE;
+  int visitBool(BoolConstantValue a, _) => BOOL;
+  int visitString(StringConstantValue a, _) => STRING;
+  int visitList(ListConstantValue a, _) => LIST;
+  int visitMap(MapConstantValue a, _) => MAP;
+  int visitConstructed(ConstructedConstantValue a, _) => CONSTRUCTED;
+  int visitType(TypeConstantValue a, _) => TYPE;
+  int visitInterceptor(InterceptorConstantValue a, _) => INTERCEPTOR;
+  int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
+  int visitDeferred(DeferredConstantValue a, _) => DEFERRED;
+}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index 07ba88b..b16379f 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -17,6 +17,7 @@
 import '../js_emitter.dart' as js_emitter show Emitter;
 import '../model.dart';
 import '../program_builder/program_builder.dart';
+import '../constant_ordering.dart' show deepCompareConstants;
 
 import '../../common.dart';
 import '../../common/names.dart' show
@@ -252,11 +253,9 @@
     // which compresses a tiny bit better.
     int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
     if (r != 0) return r;
-    // Resolve collisions in the long name by using the constant name (i.e. JS
-    // name) which is unique.
-    // TODO(herhut): Find a better way to resolve collisions.
-    return namer.constantName(a).hashCode.compareTo(
-        namer.constantName(b).hashCode);
+
+    // Resolve collisions in the long name by using a structural order.
+    return deepCompareConstants(a, b);
   }
 
   @override
@@ -1371,6 +1370,16 @@
     assembleTypedefs(program);
   }
 
+  jsAst.Statement buildDeferredHeader() {
+    /// For deferred loading we communicate the initializers via this global
+    /// variable. The deferred hunks will add their initialization to this.
+    /// The semicolon is important in minified mode, without it the
+    /// following parenthesis looks like a call to the object literal.
+    return js.statement('self.#deferredInitializers = '
+                        'self.#deferredInitializers || Object.create(null);',
+                        {'deferredInitializers': deferredInitializers});
+  }
+
   jsAst.Program buildOutputAstForMain(Program program,
       Map<OutputUnit, _DeferredOutputUnitHash> deferredLoadHashes) {
     MainFragment mainFragment = program.mainFragment;
@@ -1383,14 +1392,7 @@
               ..add(js.comment(HOOKS_API_USAGE));
 
     if (isProgramSplit) {
-      /// For deferred loading we communicate the initializers via this global
-      /// variable. The deferred hunks will add their initialization to this.
-      /// The semicolon is important in minified mode, without it the
-      /// following parenthesis looks like a call to the object literal.
-      statements.add(
-          js.statement('self.#deferredInitializers = '
-                       'self.#deferredInitializers || Object.create(null);',
-                       {'deferredInitializers': deferredInitializers}));
+      statements.add(buildDeferredHeader());
     }
 
     // Collect the AST for the decriptors
@@ -1999,6 +2001,7 @@
 
       statements
           ..add(buildGeneratedBy())
+          ..add(buildDeferredHeader())
           ..add(js.statement('${deferredInitializers}.current = '
                              """function (#, ${namer.staticStateHolder}) {
                                   #
diff --git a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
index 485195e..96838ac 100644
--- a/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/lazy_emitter/model_emitter.dart
@@ -21,6 +21,7 @@
     ConstantEmitter;
 
 import '../js_emitter.dart' show NativeEmitter;
+import '../constant_ordering.dart' show deepCompareConstants;
 
 import 'package:js_runtime/shared/embedded_names.dart' show
     CREATE_NEW_ISOLATE,
@@ -108,9 +109,9 @@
     // which compresses a tiny bit better.
     int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
     if (r != 0) return r;
-    // Resolve collisions in the long name by using the constant name (i.e. JS
-    // name) which is unique.
-    return namer.constantName(a).compareTo(namer.constantName(b));
+
+    // Resolve collisions in the long name by using a structural order.
+    return deepCompareConstants(a, b);
   }
 
   js.Expression generateStaticClosureAccess(FunctionElement element) {
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 7fbd768..14dea34 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -55,11 +55,6 @@
 // names we want. Furthermore, the pretty-printer minifies local variables, thus
 // reducing their size.
 const String mainBoilerplate = '''
-{
-// Declare deferred-initializer global, which is used to keep track of the
-// loaded fragments.
-#deferredInitializer;
-
 (function() {
 // Copies the own properties from [from] to [to].
 function copyProperties(from, to) {
@@ -355,8 +350,8 @@
 
 // Invokes main (making sure that it records the 'current-script' value).
 #invokeMain;
-})();
-}''';
+})()
+''';
 
 /// Deferred fragments (aka 'hunks') are built similarly to the main fragment.
 ///
@@ -441,8 +436,7 @@
         .where((Holder holder) => !holder.isStaticStateHolder);
 
     return js.js.statement(mainBoilerplate,
-        {'deferredInitializer': emitDeferredInitializerGlobal(program.loadMap),
-         'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
+        {'typeNameProperty': js.string(ModelEmitter.typeNameProperty),
          'cyclicThrow': backend.emitter.staticFunctionAccess(
                  backend.helpers.cyclicThrowHelper),
          'operatorIsPrefix': js.string(namer.operatorIsPrefix),
@@ -516,15 +510,6 @@
     });
   }
 
-  js.Statement emitDeferredInitializerGlobal(Map loadMap) {
-    if (loadMap.isEmpty) return new js.Block.empty();
-
-    String global = ModelEmitter.deferredInitializersGlobal;
-    return js.js.statement(
-        "if (typeof($global) === 'undefined') var # = Object.create(null);",
-        new js.VariableDeclaration(global, allowRename: false));
-  }
-
   /// Emits all holders, except for the static-state holder.
   ///
   /// The emitted holders contain classes (only the constructors) and all
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 739fe77..9e81bca 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -56,6 +56,7 @@
 import '../../util/uri_extras.dart' show
     relativize;
 
+import '../constant_ordering.dart' show deepCompareConstants;
 import '../headers.dart';
 import '../js_emitter.dart' show
     NativeEmitter;
@@ -140,9 +141,9 @@
     // which compresses a tiny bit better.
     int r = namer.constantLongName(a).compareTo(namer.constantLongName(b));
     if (r != 0) return r;
-    // Resolve collisions in the long name by using the constant name (i.e. JS
-    // name) which is unique.
-    return namer.constantName(a).compareTo(namer.constantName(b));
+
+    // Resolve collisions in the long name by using a structural order.
+    return deepCompareConstants(a, b);
   }
 
   js.Expression generateStaticClosureAccess(FunctionElement element) {
@@ -208,7 +209,8 @@
       token.setHash(hunkHashes[key]);
     });
 
-    writeMainFragment(mainFragment, mainCode);
+    writeMainFragment(mainFragment, mainCode,
+      isSplit: program.deferredFragments.isNotEmpty);
 
     if (backend.requiresPreamble &&
         !backend.htmlLibraryIsLoaded) {
@@ -249,10 +251,18 @@
     return hunkHashes;
   }
 
+  js.Statement buildDeferredInitializerGlobal() {
+    String global = deferredInitializersGlobal;
+    return js.js.statement(
+        "if (typeof($global) === 'undefined') var # = Object.create(null);",
+        new js.VariableDeclaration(global, allowRename: false));
+  }
+
   // Writes the given [fragment]'s [code] into a file.
   //
   // Updates the shared [outputBuffers] field with the output.
-  void writeMainFragment(MainFragment fragment, js.Statement code) {
+  void writeMainFragment(MainFragment fragment, js.Statement code,
+      {bool isSplit}) {
     LineColumnCollector lineColumnCollector;
     List<CodeOutputListener> codeOutputListeners;
     if (shouldGenerateSourceMap) {
@@ -268,6 +278,7 @@
     js.Program program = new js.Program([
         buildGeneratedBy(),
         new js.Comment(HOOKS_API_USAGE),
+        isSplit ? buildDeferredInitializerGlobal() : new js.Block.empty(),
         code]);
 
     mainOutput.addBuffer(js.prettyPrint(program, compiler,
@@ -321,6 +332,7 @@
 
     js.Program program = new js.Program([
         buildGeneratedBy(),
+        buildDeferredInitializerGlobal(),
         js.js.statement('$deferredInitializersGlobal.current = #', code)]);
 
     output.addBuffer(js.prettyPrint(program, compiler,
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index 71bfd9f..6006bc9 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -384,7 +384,21 @@
       return reporter.withCurrentElement(library, () {
 
         Uri computeUri(LibraryDependency node) {
-          String tagUriString = node.uri.dartString.slowToString();
+          StringNode uriNode = node.uri;
+          if (node.conditionalUris != null) {
+            for (ConditionalUri conditionalUri in node.conditionalUris) {
+              String key = conditionalUri.key.slowNameString;
+              String value = conditionalUri.value == null
+                  ? "true"
+                  : conditionalUri.value.dartString.slowToString();
+              String actual = compiler.fromEnvironment(key);
+              if (value == actual) {
+                uriNode = conditionalUri.uri;
+                break;
+              }
+            }
+          }
+          String tagUriString = uriNode.dartString.slowToString();
           try {
             return Uri.parse(tagUriString);
           } on FormatException {
@@ -610,6 +624,19 @@
         if (script == null) return null;
         LibraryElement element =
             createLibrarySync(handler, script, resolvedUri);
+        CompilationUnitElementX compilationUnit = element.entryCompilationUnit;
+        if (compilationUnit.partTag != null) {
+          DiagnosticMessage error = reporter.withCurrentElement(
+              compilationUnit,
+              () => reporter.createMessage(
+                  compilationUnit.partTag, MessageKind.IMPORT_PART_OF));
+          DiagnosticMessage info = reporter.withCurrentElement(
+              importingLibrary,
+              () => reporter.createMessage(
+                  node,
+                  MessageKind.IMPORT_PART_OF_HERE));
+          reporter.reportError(error, <DiagnosticMessage>[info]);
+        }
         return processLibraryTags(handler, element).then((_) {
           reporter.withCurrentElement(element, () {
             handler.registerLibraryExports(element);
diff --git a/pkg/compiler/lib/src/parser/class_element_parser.dart b/pkg/compiler/lib/src/parser/class_element_parser.dart
index 745665d..319cba5 100644
--- a/pkg/compiler/lib/src/parser/class_element_parser.dart
+++ b/pkg/compiler/lib/src/parser/class_element_parser.dart
@@ -13,7 +13,8 @@
     PartialParser;
 
 class ClassElementParser extends PartialParser {
-  ClassElementParser(Listener listener) : super(listener);
+  ClassElementParser(Listener listener)
+      : super(listener, enableConditionalDirectives: false);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 10a0a9f..9afc8d4 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -23,7 +23,12 @@
     PartialParser;
 
 class DietParserTask extends CompilerTask {
-  DietParserTask(Compiler compiler) : super(compiler);
+  final bool _enableConditionalDirectives;
+
+  DietParserTask(Compiler compiler, {bool enableConditionalDirectives})
+      : this._enableConditionalDirectives = enableConditionalDirectives,
+        super(compiler);
+
   final String name = 'Diet Parser';
 
   dietParse(CompilationUnitElement compilationUnit, Token tokens) {
@@ -34,7 +39,8 @@
               compilationUnit.library));
       ElementListener listener = new ElementListener(
           scannerOptions, compiler.reporter, compilationUnit, idGenerator);
-      PartialParser parser = new PartialParser(listener);
+      PartialParser parser = new PartialParser(
+          listener, enableConditionalDirectives: _enableConditionalDirectives);
       try {
         parser.parseUnit(tokens);
       } on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 0cdf72e..fb5314e 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -150,12 +150,34 @@
     if (asKeyword != null) {
       prefix = popNode();
     }
+    NodeList conditionalUris = popNode();
     StringNode uri = popLiteralString();
-    addLibraryTag(new Import(importKeyword, uri, prefix, combinators,
+    addLibraryTag(new Import(importKeyword, uri, conditionalUris,
+                             prefix, combinators,
                              popMetadata(compilationUnitElement),
                              isDeferred: isDeferred));
   }
 
+  void endDottedName(int count, Token token) {
+    NodeList identifiers = makeNodeList(count, null, null, '.');
+    pushNode(new DottedName(token, identifiers));
+  }
+
+  void endConditionalUris(int count) {
+    if (count == 0) {
+      pushNode(null);
+    } else {
+      pushNode(makeNodeList(count, null, null, " "));
+    }
+  }
+
+  void endConditionalUri(Token ifToken, Token equalSign) {
+    StringNode uri = popNode();
+    LiteralString conditionValue = (equalSign != null) ? popNode() : null;
+    DottedName identifier = popNode();
+    pushNode(new ConditionalUri(ifToken, identifier, conditionValue, uri));
+  }
+
   void endEnum(Token enumKeyword, Token endBrace, int count) {
     NodeList names = makeNodeList(count, enumKeyword.next.next, endBrace, ",");
     Identifier name = popNode();
@@ -169,8 +191,9 @@
 
   void endExport(Token exportKeyword, Token semicolon) {
     NodeList combinators = popNode();
+    NodeList conditionalUris = popNode();
     StringNode uri = popNode();
-    addLibraryTag(new Export(exportKeyword, uri, combinators,
+    addLibraryTag(new Export(exportKeyword, uri, conditionalUris, combinators,
                              popMetadata(compilationUnitElement)));
   }
 
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index 6511abc..618b86a 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -232,6 +232,24 @@
                  Token asKeyword, Token semicolon) {
   }
 
+  void beginConditionalUris(Token token) {
+  }
+
+  void endConditionalUris(int count) {
+  }
+
+  void beginConditionalUri(Token ifKeyword) {
+  }
+
+  void endConditionalUri(Token ifKeyword, Token equalitySign) {
+  }
+
+  void beginDottedName(Token token) {
+  }
+
+  void endDottedName(int count, Token firstIdentifier) {
+  }
+
   void beginInitializedIdentifier(Token token) {
   }
 
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index 7adddb5..f2e0577 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -98,11 +98,12 @@
 class Parser {
   final Listener listener;
   bool mayParseFunctionExpressions = true;
-  bool yieldIsKeyword;
-  bool awaitIsKeyword;
+  final bool enableConditionalDirectives;
+  bool asyncAwaitKeywordsEnabled;
 
   Parser(this.listener,
-         {this.yieldIsKeyword: false, this.awaitIsKeyword: false});
+      {this.enableConditionalDirectives: false,
+       this.asyncAwaitKeywordsEnabled: false});
 
   Token parseUnit(Token token) {
     listener.beginCompilationUnit(token);
@@ -151,12 +152,13 @@
     return token;
   }
 
-  /// import uri (as identifier)? combinator* ';'
+  /// import uri (if (test) uri)* (as identifier)? combinator* ';'
   Token parseImport(Token token) {
     Token importKeyword = token;
     listener.beginImport(importKeyword);
     assert(optional('import', token));
     token = parseLiteralStringOrRecoverExpression(token.next);
+    token = parseConditionalUris(token);
     Token deferredKeyword;
     if (optional('deferred', token)) {
       deferredKeyword = token;
@@ -174,12 +176,57 @@
     return token;
   }
 
-  /// export uri combinator* ';'
+  /// if (test) uri
+  Token parseConditionalUris(Token token) {
+    listener.beginConditionalUris(token);
+    int count = 0;
+    if (enableConditionalDirectives) {
+      while (optional('if', token)) {
+        count++;
+        token = parseConditionalUri(token);
+      }
+    }
+    listener.endConditionalUris(count);
+    return token;
+  }
+
+  Token parseConditionalUri(Token token) {
+    listener.beginConditionalUri(token);
+    Token ifKeyword = token;
+    token = expect('if', token);
+    token = expect('(', token);
+    token = parseDottedName(token);
+    Token equalitySign;
+    if (optional('==', token)) {
+      equalitySign = token;
+      token = parseLiteralStringOrRecoverExpression(token.next);
+    }
+    token = expect(')', token);
+    token = parseLiteralStringOrRecoverExpression(token);
+    listener.endConditionalUri(ifKeyword, equalitySign);
+    return token;
+  }
+
+  Token parseDottedName(Token token) {
+    listener.beginDottedName(token);
+    Token firstIdentifier = token;
+    token = parseIdentifier(token);
+    int count = 1;
+    while (optional('.', token)) {
+      token = parseIdentifier(token.next);
+      count++;
+    }
+    listener.endDottedName(count, firstIdentifier);
+    return token;
+  }
+
+  /// export uri conditional-uris* combinator* ';'
   Token parseExport(Token token) {
     Token exportKeyword = token;
     listener.beginExport(exportKeyword);
     assert(optional('export', token));
     token = parseLiteralStringOrRecoverExpression(token.next);
+    token = parseConditionalUris(token);
     token = parseCombinators(token);
     Token semicolon = token;
     token = expect(';', token);
@@ -660,15 +707,27 @@
 
   /**
    * Returns true if the stringValue of the [token] is either [value1],
+   * [value2], or [value3].
+   */
+  bool isOneOf3(Token token, String value1, String value2, String value3) {
+    String stringValue = token.stringValue;
+    return
+        value1 == stringValue ||
+        value2 == stringValue ||
+        value3 == stringValue;
+  }
+
+  /**
+   * Returns true if the stringValue of the [token] is either [value1],
    * [value2], [value3], or [value4].
    */
   bool isOneOf4(Token token,
                 String value1, String value2, String value3, String value4) {
     String stringValue = token.stringValue;
-    return identical(value1, stringValue) ||
-           identical(value2, stringValue) ||
-           identical(value3, stringValue) ||
-           identical(value4, stringValue);
+    return value1 == stringValue ||
+           value2 == stringValue ||
+           value3 == stringValue ||
+           value4 == stringValue;
   }
 
   bool notEofOrValue(String value, Token token) {
@@ -931,6 +990,8 @@
                             Token name) {
 
     Token externalModifier;
+    // TODO(johnniwinther): Move error reporting to resolution to give more
+    // specific error messages.
     for (Token modifier in modifiers) {
       if (externalModifier == null && optional('external', modifier)) {
         externalModifier = modifier;
@@ -954,12 +1015,10 @@
     Token token = parseIdentifier(name);
 
     token = parseFormalParametersOpt(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     token = parseFunctionBody(token, false, externalModifier != null);
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     Token endToken = token;
     token = token.next;
     if (token.kind == BAD_INPUT_TOKEN) {
@@ -1306,6 +1365,8 @@
     Token constModifier;
     int modifierCount = 0;
     int allowedModifierCount = 1;
+    // TODO(johnniwinther): Move error reporting to resolution to give more
+    // specific error messages.
     for (Token modifier in modifiers) {
       if (externalModifier == null && optional('external', modifier)) {
         modifierCount++;
@@ -1337,6 +1398,11 @@
             modifier, MessageKind.EXTRANEOUS_MODIFIER, {'modifier': modifier});
       }
     }
+    if (getOrSet != null &&  constModifier != null) {
+      listener.reportError(
+          constModifier, MessageKind.EXTRANEOUS_MODIFIER,
+          {'modifier': constModifier});
+    }
     parseModifierList(modifiers);
 
     if (type == null) {
@@ -1348,7 +1414,6 @@
     if (optional('operator', name)) {
       token = parseOperatorName(name);
       if (staticModifier != null) {
-        // TODO(ahe): Consider a more specific error message.
         listener.reportError(
             staticModifier, MessageKind.EXTRANEOUS_MODIFIER,
             {'modifier': staticModifier});
@@ -1360,8 +1425,7 @@
     token = parseQualifiedRestOpt(token);
     token = parseFormalParametersOpt(token);
     token = parseInitializersOpt(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
@@ -1369,8 +1433,7 @@
       token = parseFunctionBody(
           token, false, staticModifier == null || externalModifier != null);
     }
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endMethod(getOrSet, start, token);
     return token.next;
   }
@@ -1448,16 +1511,14 @@
     listener.endFunctionName(token);
     token = parseFormalParametersOpt(token);
     token = parseInitializersOpt(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     if (optional('=', token)) {
       token = parseRedirectingFactoryBody(token);
     } else {
       token = parseFunctionBody(token, false, true);
     }
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endFunction(getOrSet, token);
     return token.next;
   }
@@ -1465,13 +1526,11 @@
   Token parseUnnamedFunction(Token token) {
     listener.beginUnnamedFunction(token);
     token = parseFormalParameters(token);
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     bool isBlock = optional('{', token);
     token = parseFunctionBody(token, true, false);
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endUnnamedFunction(token);
     return isBlock ? token.next : token;
   }
@@ -1492,13 +1551,11 @@
     listener.endFunctionName(token);
     token = parseFormalParameters(token);
     listener.handleNoInitializers();
-    bool previousYieldIsKeyword = yieldIsKeyword;
-    bool previousAwaitIsKeyword = awaitIsKeyword;
+    bool previousAsyncAwaitKeywordsEnabled = asyncAwaitKeywordsEnabled;
     token = parseAsyncModifier(token);
     bool isBlock = optional('{', token);
     token = parseFunctionBody(token, true, false);
-    yieldIsKeyword = previousYieldIsKeyword;
-    awaitIsKeyword = previousAwaitIsKeyword;
+    asyncAwaitKeywordsEnabled = previousAsyncAwaitKeywordsEnabled;
     listener.endFunction(null, token);
     return isBlock ? token.next : token;
   }
@@ -1567,14 +1624,12 @@
   Token parseAsyncModifier(Token token) {
     Token async;
     Token star;
-    awaitIsKeyword = false;
-    yieldIsKeyword = false;
+    asyncAwaitKeywordsEnabled = false;
     if (optional('async', token)) {
-      awaitIsKeyword = true;
+      asyncAwaitKeywordsEnabled = true;
       async = token;
       token = token.next;
       if (optional('*', token)) {
-        yieldIsKeyword = true;
         star = token;
         token = token.next;
       }
@@ -1582,7 +1637,7 @@
       async = token;
       token = token.next;
       if (optional('*', token)) {
-        yieldIsKeyword = true;
+        asyncAwaitKeywordsEnabled = true;
         star = token;
         token = token.next;
       } else {
@@ -1606,7 +1661,7 @@
       return parseVariablesDeclaration(token);
     } else if (identical(value, 'if')) {
       return parseIfStatement(token);
-    } else if (awaitIsKeyword && identical(value, 'await')) {
+    } else if (asyncAwaitKeywordsEnabled && identical(value, 'await')) {
       if (identical(token.next.stringValue, 'for')) {
         return parseForStatement(token, token.next);
       } else {
@@ -1637,7 +1692,7 @@
       return parseAssertStatement(token);
     } else if (identical(value, ';')) {
       return parseEmptyStatement(token);
-    } else if (yieldIsKeyword && identical(value, 'yield')) {
+    } else if (asyncAwaitKeywordsEnabled && identical(value, 'yield')) {
       return parseYieldStatement(token);
     } else if (identical(value, 'const')) {
       return parseExpressionStatementOrConstDeclaration(token);
@@ -1919,7 +1974,7 @@
   Token parseUnaryExpression(Token token, bool allowCascades) {
     String value = token.stringValue;
     // Prefix:
-    if (awaitIsKeyword && optional('await', token)) {
+    if (asyncAwaitKeywordsEnabled && optional('await', token)) {
       return parseAwaitExpression(token, allowCascades);
     } else if (identical(value, '+')) {
       // Dart no longer allows prefix-plus.
@@ -1970,44 +2025,47 @@
 
   Token parsePrimary(Token token) {
     final kind = token.kind;
-    if (identical(kind, IDENTIFIER_TOKEN)) {
+    if (kind == IDENTIFIER_TOKEN) {
       return parseSendOrFunctionLiteral(token);
-    } else if (identical(kind, INT_TOKEN)
-        || identical(kind, HEXADECIMAL_TOKEN)) {
+    } else if (kind == INT_TOKEN
+        || kind == HEXADECIMAL_TOKEN) {
       return parseLiteralInt(token);
-    } else if (identical(kind, DOUBLE_TOKEN)) {
+    } else if (kind == DOUBLE_TOKEN) {
       return parseLiteralDouble(token);
-    } else if (identical(kind, STRING_TOKEN)) {
+    } else if (kind == STRING_TOKEN) {
       return parseLiteralString(token);
-    } else if (identical(kind, HASH_TOKEN)) {
+    } else if (kind == HASH_TOKEN) {
       return parseLiteralSymbol(token);
-    } else if (identical(kind, KEYWORD_TOKEN)) {
+    } else if (kind == KEYWORD_TOKEN) {
       final value = token.stringValue;
-      if ((identical(value, 'true')) || (identical(value, 'false'))) {
+      if (value == 'true' || value == 'false') {
         return parseLiteralBool(token);
-      } else if (identical(value, 'null')) {
+      } else if (value == 'null') {
         return parseLiteralNull(token);
-      } else if (identical(value, 'this')) {
+      } else if (value == 'this') {
         return parseThisExpression(token);
-      } else if (identical(value, 'super')) {
+      } else if (value == 'super') {
         return parseSuperExpression(token);
-      } else if (identical(value, 'new')) {
+      } else if (value == 'new') {
         return parseNewExpression(token);
-      } else if (identical(value, 'const')) {
+      } else if (value == 'const') {
         return parseConstExpression(token);
-      } else if (identical(value, 'void')) {
+      } else if (value == 'void') {
         return parseFunctionExpression(token);
+      } else if (asyncAwaitKeywordsEnabled &&
+                 (value == 'yield' || value == 'async')) {
+        return listener.expectedExpression(token);
       } else if (token.isIdentifier()) {
         return parseSendOrFunctionLiteral(token);
       } else {
         return listener.expectedExpression(token);
       }
-    } else if (identical(kind, OPEN_PAREN_TOKEN)) {
+    } else if (kind == OPEN_PAREN_TOKEN) {
       return parseParenthesizedExpressionOrFunctionLiteral(token);
-    } else if ((identical(kind, LT_TOKEN)) ||
-               (identical(kind, OPEN_SQUARE_BRACKET_TOKEN)) ||
-               (identical(kind, OPEN_CURLY_BRACKET_TOKEN)) ||
-               identical(token.stringValue, '[]')) {
+    } else if ((kind == LT_TOKEN) ||
+               (kind == OPEN_SQUARE_BRACKET_TOKEN) ||
+               (kind == OPEN_CURLY_BRACKET_TOKEN) ||
+               token.stringValue == '[]') {
       return parseLiteralListOrMap(token);
     } else {
       return listener.expectedExpression(token);
@@ -2427,7 +2485,7 @@
     if (identical(value, ';')) {
       listener.handleNoExpression(token);
       return token;
-    } else if ((identical(value, 'var')) || (identical(value, 'final'))) {
+    } else if (isOneOf3(token, 'var', 'final', 'const')) {
       return parseVariablesDeclarationNoSemicolon(token);
     }
     Token identifier = peekIdentifierAfterType(token);
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index 5ea0247..fa715aa 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -26,7 +26,13 @@
     Parser;
 
 class ParserTask extends CompilerTask {
-  ParserTask(Compiler compiler) : super(compiler);
+  final bool _enableConditionalDirectives;
+
+  ParserTask(Compiler compiler,
+             {bool enableConditionalDirectives: false})
+      : this._enableConditionalDirectives = enableConditionalDirectives,
+        super(compiler);
+
   String get name => 'Parser';
 
   Node parse(ElementX element) {
@@ -37,7 +43,8 @@
     return measure(() {
       NodeListener listener = new NodeListener(
           const ScannerOptions(), reporter, null);
-      Parser parser = new Parser(listener);
+      Parser parser = new Parser(
+          listener, enableConditionalDirectives: _enableConditionalDirectives);
       try {
         parser.parseUnit(token);
       } on ParserError catch(_) {
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 01de07c..1c7722f 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -20,7 +20,9 @@
     Parser;
 
 class PartialParser extends Parser {
-  PartialParser(Listener listener) : super(listener);
+  PartialParser(Listener listener, {bool enableConditionalDirectives})
+      : super(listener,
+          enableConditionalDirectives: enableConditionalDirectives);
 
   Token parseClassBody(Token token) => skipClassBody(token);
 
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 4edabb3..593b08f 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -159,8 +159,11 @@
 
 class PatchParserTask extends CompilerTask {
   final String name = "Patching Parser";
+  final bool _enableConditionalDirectives;
 
-  PatchParserTask(Compiler compiler): super(compiler);
+  PatchParserTask(Compiler compiler, {bool enableConditionalDirectives})
+      : this._enableConditionalDirectives = enableConditionalDirectives,
+        super(compiler);
 
   /**
    * Scans a library patch file, applies the method patches and
@@ -195,7 +198,9 @@
                                                         compilationUnit,
                                                         idGenerator);
       try {
-        new PartialParser(patchListener).parseUnit(tokens);
+        new PartialParser(patchListener,
+            enableConditionalDirectives: _enableConditionalDirectives)
+            .parseUnit(tokens);
       } on ParserError catch (e) {
         // No need to recover from a parser error in platform libraries, user
         // will never see this if the libraries are tested correctly.
@@ -212,7 +217,8 @@
 
     measure(() => reporter.withCurrentElement(cls, () {
       MemberListener listener = new PatchMemberListener(compiler, cls);
-      Parser parser = new PatchClassElementParser(listener);
+      Parser parser = new PatchClassElementParser(
+          listener, enableConditionalDirectives: _enableConditionalDirectives);
       try {
         Token token = parser.parseTopLevelDeclaration(cls.beginToken);
         assert(identical(token, cls.endToken.next));
@@ -264,7 +270,9 @@
  * declarations.
  */
 class PatchClassElementParser extends PartialParser {
-  PatchClassElementParser(Listener listener) : super(listener);
+  PatchClassElementParser(Listener listener, {bool enableConditionalDirectives})
+      : super(listener,
+          enableConditionalDirectives: enableConditionalDirectives);
 
   Token parseClassBody(Token token) => fullParseClassBody(token);
 }
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 26e7b48b..ce4e93c 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -485,18 +485,19 @@
       MessageKind kind,
       Map arguments,
       {bool isError: false,
-       bool missingConstructor: false}) {
+       bool missingConstructor: false,
+       List<DiagnosticMessage> infos: const <DiagnosticMessage>[]}) {
     if (missingConstructor) {
       registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
     } else {
       registry.registerFeature(Feature.THROW_RUNTIME_ERROR);
     }
+    DiagnosticMessage message =
+        reporter.createMessage(diagnosticNode, kind, arguments);
     if (isError || inConstContext) {
-      reporter.reportErrorMessage(
-          diagnosticNode, kind, arguments);
+      reporter.reportError(message, infos);
     } else {
-      reporter.reportWarningMessage(
-          diagnosticNode, kind, arguments);
+      reporter.reportWarning(message, infos);
     }
     ErroneousElement error = new ErroneousConstructorElementX(
         kind, arguments, name, enclosing);
@@ -616,8 +617,7 @@
     if (send != null) {
       // The type name is of the form [: prefix . identifier :].
       String name = send.receiver.asIdentifier().source;
-      Element element = resolver.reportLookupErrorIfAny(
-          lookupInScope(reporter, send, resolver.scope, name), node, name);
+      Element element = lookupInScope(reporter, send, resolver.scope, name);
       if (element != null && element.isPrefix) {
         prefix = element;
       }
@@ -666,10 +666,8 @@
 
   ConstructorResult visitIdentifier(Identifier node) {
     String name = node.source;
-    Element element = resolver.reportLookupErrorIfAny(
-        lookupInScope(reporter, node, resolver.scope, name), node, name);
+    Element element = lookupInScope(reporter, node, resolver.scope, name);
     registry.useElement(node, element);
-    // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
     return constructorResultForElement(node, name, element);
   }
 
@@ -691,6 +689,15 @@
           resolver.enclosingElement, name,
           MessageKind.CANNOT_RESOLVE,
           {'name': name});
+    } else if (element.isAmbiguous) {
+      AmbiguousElement ambiguous = element;
+      return reportAndCreateErroneousConstructorElement(
+          node,
+          ConstructorResultKind.INVALID_TYPE, null,
+          resolver.enclosingElement, name,
+          ambiguous.messageKind,
+          ambiguous.messageArguments,
+          infos: ambiguous.computeInfos(resolver.enclosingElement, reporter));
     } else if (element.isMalformed) {
       return constructorResultForErroneous(node, element);
     } else if (element.isClass) {
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index c41d5a1..8426021 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -126,7 +126,7 @@
   /// When visiting the type declaration of the variable in a [ForIn] loop,
   /// the initializer of the variable is implicit and we should not emit an
   /// error when verifying that all final variables are initialized.
-  bool allowFinalWithoutInitializer = false;
+  bool inLoopVariable = false;
 
   /// The nodes for which variable access and mutation must be registered in
   /// order to determine when the static type of variables types is promoted.
@@ -3687,8 +3687,14 @@
   }
 
   ResolutionResult visitYield(Yield node) {
-    coreClasses.streamClass.ensureResolved(resolution);
-    coreClasses.iterableClass.ensureResolved(resolution);
+    if (!currentAsyncMarker.isYielding) {
+      reporter.reportErrorMessage(node, MessageKind.INVALID_YIELD);
+    }
+    if (currentAsyncMarker.isAsync) {
+      coreClasses.streamClass.ensureResolved(resolution);
+    } else {
+      coreClasses.iterableClass.ensureResolved(resolution);
+    }
     visit(node.expression);
     return const NoneResult();
   }
@@ -3825,6 +3831,9 @@
   }
 
   ResolutionResult visitAwait(Await node) {
+    if (!currentAsyncMarker.isAsync) {
+      reporter.reportErrorMessage(node, MessageKind.INVALID_AWAIT);
+    }
     coreClasses.futureClass.ensureResolved(resolution);
     visit(node.expression);
     return const NoneResult();
@@ -4350,6 +4359,10 @@
   }
 
   ResolutionResult visitAsyncForIn(AsyncForIn node) {
+    if (!currentAsyncMarker.isAsync) {
+      reporter.reportErrorMessage(
+          node.awaitToken, MessageKind.INVALID_AWAIT_FOR_IN);
+    }
     registry.registerFeature(Feature.ASYNC_FOR_IN);
     registry.registerDynamicUse(
         new DynamicUse(Selectors.current, null));
@@ -4387,10 +4400,10 @@
       Scope blockScope) {
     LibraryElement library = enclosingElement.library;
 
-    bool oldAllowFinalWithoutInitializer = allowFinalWithoutInitializer;
-    allowFinalWithoutInitializer = true;
+    bool oldAllowFinalWithoutInitializer = inLoopVariable;
+    inLoopVariable = true;
     visitIn(declaration, blockScope);
-    allowFinalWithoutInitializer = oldAllowFinalWithoutInitializer;
+    inLoopVariable = oldAllowFinalWithoutInitializer;
 
     Send send = declaration.asSend();
     VariableDefinitions variableDefinitions =
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 4490b88..737b5f0 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -21,6 +21,11 @@
     Compiler;
 import '../compile_time_constants.dart' show
     ConstantCompiler;
+import '../constants/expressions.dart' show
+    ConstantExpression,
+    ConstantExpressionKind,
+    ConstructedConstantExpression,
+    ErroneousConstantExpression;
 import '../constants/values.dart' show
     ConstantValue;
 import '../core_types.dart' show
@@ -856,7 +861,7 @@
     if (lookupElement == null) {
       reporter.internalError(member,
           "No abstract field for accessor");
-    } else if (!identical(lookupElement.kind, ElementKind.ABSTRACT_FIELD)) {
+    } else if (!lookupElement.isAbstractField) {
       if (lookupElement.isMalformed || lookupElement.isAmbiguous) return;
       reporter.internalError(member,
           "Inaccessible abstract field for accessor");
@@ -869,14 +874,14 @@
     if (setter == null) return;
     int getterFlags = getter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
     int setterFlags = setter.modifiers.flags | Modifiers.FLAG_ABSTRACT;
-    if (!identical(getterFlags, setterFlags)) {
+    if (getterFlags != setterFlags) {
       final mismatchedFlags =
         new Modifiers.withFlags(null, getterFlags ^ setterFlags);
-      reporter.reportErrorMessage(
+      reporter.reportWarningMessage(
           field.getter,
           MessageKind.GETTER_MISMATCH,
           {'modifiers': mismatchedFlags});
-      reporter.reportErrorMessage(
+      reporter.reportWarningMessage(
           field.setter,
           MessageKind.SETTER_MISMATCH,
           {'modifiers': mismatchedFlags});
@@ -1061,8 +1066,29 @@
       node.accept(visitor);
       // TODO(johnniwinther): Avoid passing the [TreeElements] to
       // [compileMetadata].
-      annotation.constant =
-          constantCompiler.compileMetadata(annotation, node, registry.mapping);
+      ConstantExpression constant = constantCompiler.compileMetadata(
+          annotation, node, registry.mapping);
+      switch (constant.kind) {
+        case ConstantExpressionKind.CONSTRUCTED:
+          ConstructedConstantExpression constructedConstant = constant;
+          if (constructedConstant.type.isGeneric) {
+            // Const constructor calls cannot have type arguments.
+            // TODO(24312): Remove this.
+            reporter.reportErrorMessage(
+                node, MessageKind.INVALID_METADATA_GENERIC);
+            constant = new ErroneousConstantExpression();
+          }
+          break;
+        case ConstantExpressionKind.VARIABLE:
+        case ConstantExpressionKind.ERRONEOUS:
+          break;
+        default:
+          reporter.reportErrorMessage(node, MessageKind.INVALID_METADATA);
+          constant = new ErroneousConstantExpression();
+          break;
+      }
+      annotation.constant = constant;
+
       constantCompiler.evaluate(annotation.constant);
       // TODO(johnniwinther): Register the relation between the annotation
       // and the annotated element instead. This will allow the backend to
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
index 6f22eed..aec67f3 100644
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ b/pkg/compiler/lib/src/resolution/variables.dart
@@ -60,11 +60,16 @@
     registry.registerTypeUse(
         new TypeUse.instantiation(compiler.coreTypes.nullType));
     if (definitions.modifiers.isConst) {
-      reporter.reportErrorMessage(
-          node, MessageKind.CONST_WITHOUT_INITIALIZER);
+      if (resolver.inLoopVariable) {
+        reporter.reportErrorMessage(
+            node, MessageKind.CONST_LOOP_VARIABLE);
+      } else {
+        reporter.reportErrorMessage(
+            node, MessageKind.CONST_WITHOUT_INITIALIZER);
+      }
     }
     if (definitions.modifiers.isFinal &&
-        !resolver.allowFinalWithoutInitializer) {
+        !resolver.inLoopVariable) {
       reporter.reportErrorMessage(
           node, MessageKind.FINAL_WITHOUT_INITIALIZER);
     }
diff --git a/pkg/compiler/lib/src/tree/nodes.dart b/pkg/compiler/lib/src/tree/nodes.dart
index 7ef28dc..04d46f5 100644
--- a/pkg/compiler/lib/src/tree/nodes.dart
+++ b/pkg/compiler/lib/src/tree/nodes.dart
@@ -22,7 +22,9 @@
   R visitClassNode(ClassNode node) => visitNode(node);
   R visitCombinator(Combinator node) => visitNode(node);
   R visitConditional(Conditional node) => visitExpression(node);
+  R visitConditionalUri(ConditionalUri node) => visitNode(node);
   R visitContinueStatement(ContinueStatement node) => visitGotoStatement(node);
+  R visitDottedName(DottedName node) => visitExpression(node);
   R visitDoWhile(DoWhile node) => visitLoop(node);
   R visitEmptyStatement(EmptyStatement node) => visitStatement(node);
   R visitEnum(Enum node) => visitNode(node);
@@ -34,8 +36,8 @@
   R visitFunctionExpression(FunctionExpression node) => visitExpression(node);
   R visitGotoStatement(GotoStatement node) => visitStatement(node);
   R visitIdentifier(Identifier node) => visitExpression(node);
-  R visitIf(If node) => visitStatement(node);
   R visitImport(Import node) => visitLibraryDependency(node);
+  R visitIf(If node) => visitStatement(node);
   R visitLabel(Label node) => visitNode(node);
   R visitLabeledStatement(LabeledStatement node) => visitStatement(node);
   R visitLibraryDependency(LibraryDependency node) => visitLibraryTag(node);
@@ -159,7 +161,9 @@
   ClassNode asClassNode() => null;
   Combinator asCombinator() => null;
   Conditional asConditional() => null;
+  ConditionalUri asConditionalUri() => null;
   ContinueStatement asContinueStatement() => null;
+  DottedName asDottedName() => null;
   DoWhile asDoWhile() => null;
   EmptyStatement asEmptyStatement() => null;
   Enum asEnum() => null;
@@ -1022,6 +1026,7 @@
 
 class LiteralSymbol extends Expression {
   final Token hashToken;
+  // TODO: this could be a DottedNamed.
   final NodeList identifiers;
 
   LiteralSymbol(this.hashToken, this.identifiers);
@@ -1067,6 +1072,32 @@
   Token getEndToken() => token;
 }
 
+// TODO(floitsch): a dotted identifier isn't really an expression. Should it
+// inherit from Node instead?
+class DottedName extends Expression {
+  final Token token;
+  final NodeList identifiers;
+
+  DottedName(this.token, this.identifiers);
+
+  DottedName asDottedName() => this;
+
+  void visitChildren(Visitor visitor) {
+    identifiers.accept(visitor);
+  }
+
+  accept(Visitor visitor) => visitor.visitDottedName(this);
+
+  Token getBeginToken() => token;
+  Token getEndToken() => identifiers.getEndToken();
+
+  String get slowNameString {
+    Unparser unparser = new Unparser();
+    unparser.unparseNodeListOfIdentifiers(identifiers);
+    return unparser.result;
+  }
+}
+
 class Operator extends Identifier {
   static const COMPLEX_OPERATORS =
       const ["--", "++", '+=', "-=", "*=", "/=", "%=", "&=", "|=", "~/=", "^=",
@@ -1964,14 +1995,18 @@
  */
 abstract class LibraryDependency extends LibraryTag {
   final StringNode uri;
+  final NodeList conditionalUris;
   final NodeList combinators;
 
   LibraryDependency(this.uri,
+                    this.conditionalUris,
                     this.combinators,
                     List<MetadataAnnotation> metadata)
     : super(metadata);
 
   LibraryDependency asLibraryDependency() => this;
+
+  bool get hasConditionalUris => conditionalUris != null;
 }
 
 /**
@@ -1986,11 +2021,11 @@
   final Token importKeyword;
   final bool isDeferred;
 
-  Import(this.importKeyword, StringNode uri,
+  Import(this.importKeyword, StringNode uri, NodeList conditionalUris,
          this.prefix, NodeList combinators,
          List<MetadataAnnotation> metadata,
          {this.isDeferred})
-      : super(uri, combinators, metadata);
+      : super(uri, conditionalUris, combinators, metadata);
 
   bool get isImport => true;
 
@@ -2009,11 +2044,45 @@
   Token getEndToken() {
     if (combinators != null) return combinators.getEndToken().next;
     if (prefix != null) return prefix.getEndToken().next;
+    if (conditionalUris != null) return conditionalUris.getEndToken().next;
     return uri.getEndToken().next;
   }
 }
 
 /**
+ * A conditional uri inside an import or export clause.
+ *
+ * Example:
+ *
+ *     import 'foo.dart'
+ *       if (some.condition == "someValue") 'bar.dart'
+ *       if (other.condition) 'gee.dart';
+ */
+class ConditionalUri extends Node {
+  final Token ifToken;
+  final DottedName key;
+  // Value may be null.
+  final LiteralString value;
+  final StringNode uri;
+
+  ConditionalUri(this.ifToken, this.key, this.value, this.uri);
+
+  ConditionalUri asConditionalUri() => this;
+
+  accept(Visitor visitor) => visitor.visitConditionalUri(this);
+
+  visitChildren(Visitor visitor) {
+    key.accept(visitor);
+    if (value != null) value.accept(visitor);
+    uri.accept(visitor);
+  }
+
+  Token getBeginToken() => ifToken;
+
+  Token getEndToken() => uri.getEndToken();
+}
+
+/**
  * An `enum` declaration.
  *
  * An `enum` defines a number of named constants inside a non-extensible class
@@ -2052,9 +2121,10 @@
 
   Export(this.exportKeyword,
          StringNode uri,
+         NodeList conditionalUris,
          NodeList combinators,
          List<MetadataAnnotation> metadata)
-      : super(uri, combinators, metadata);
+      : super(uri, conditionalUris, combinators, metadata);
 
   bool get isExport => true;
 
@@ -2071,6 +2141,7 @@
 
   Token getEndToken() {
     if (combinators != null) return combinators.getEndToken().next;
+    if (conditionalUris != null) return conditionalUris.getEndToken().next;
     return uri.getEndToken().next;
   }
 }
diff --git a/pkg/compiler/lib/src/tree/prettyprint.dart b/pkg/compiler/lib/src/tree/prettyprint.dart
index 5096e74..552747e 100644
--- a/pkg/compiler/lib/src/tree/prettyprint.dart
+++ b/pkg/compiler/lib/src/tree/prettyprint.dart
@@ -88,10 +88,20 @@
     visitNodeWithChildren(node, "Conditional");
   }
 
+  visitConditionalUri(ConditionalUri node) {
+    visitNodeWithChildren(node, "ConditionalUri");
+  }
+
   visitContinueStatement(ContinueStatement node) {
     visitNodeWithChildren(node, "ContinueStatement");
   }
 
+  visitDottedName(DottedName node) {
+    openNode(node, "DottedName");
+    visitChildNode(node.identifiers, "identifiers");
+    closeNode();
+  }
+
   visitDoWhile(DoWhile node) {
     visitNodeWithChildren(node, "DoWhile");
   }
@@ -380,6 +390,9 @@
   visitExport(Export node) {
     openNode(node, "Export");
     visitChildNode(node.uri, "uri");
+    if (node.conditionalUris != null) {
+      visitChildNode(node.conditionalUris, "conditionalUris");
+    }
     visitChildNode(node.combinators, "combinators");
     closeNode();
   }
@@ -388,6 +401,9 @@
     openNode(node, "Import", {
       "isDeferred" : "${node.isDeferred}"});
     visitChildNode(node.uri, "uri");
+    if (node.conditionalUris != null) {
+      visitChildNode(node.conditionalUris, "conditionalUris");
+    }
     visitChildNode(node.combinators, "combinators");
     if (node.prefix != null) {
       visitChildNode(node.prefix, "prefix");
diff --git a/pkg/compiler/lib/src/tree/unparser.dart b/pkg/compiler/lib/src/tree/unparser.dart
index 6f141fd..807ea05 100644
--- a/pkg/compiler/lib/src/tree/unparser.dart
+++ b/pkg/compiler/lib/src/tree/unparser.dart
@@ -782,9 +782,33 @@
     newline();
   }
 
+  visitConditionalUri(ConditionalUri node) {
+    write(node.ifToken.value);
+    space();
+    write('(');
+    visit(node.key);
+    if (node.value != null) {
+      space();
+      write("==");
+      space();
+      visit(node.value);
+    }
+    write(")");
+    space();
+    visit(node.uri);
+  }
+
+  visitDottedName(DottedName node) {
+    unparseNodeListOfIdentifiers(node.identifiers);
+  }
+
   visitImport(Import node) {
     addToken(node.importKeyword);
     visit(node.uri);
+    if (node.hasConditionalUris) {
+      write(' ');
+      visitNodeList(node.conditionalUris);
+    }
     if (node.isDeferred) {
       write(' deferred');
     }
@@ -803,6 +827,10 @@
   visitExport(Export node) {
     addToken(node.exportKeyword);
     visit(node.uri);
+    if (node.hasConditionalUris) {
+      write(' ');
+      visitNodeList(node.conditionalUris);
+    }
     if (node.combinators != null) {
       write(' ');
       visit(node.combinators);
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 6667ded..ecdbccb 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -8,6 +8,7 @@
 import '../tree_ir_nodes.dart';
 import '../../io/source_information.dart';
 import '../../elements/elements.dart';
+import '../../js/placeholder_safety.dart';
 
 /**
  * Translates to direct-style.
@@ -1140,13 +1141,24 @@
   }
 
   void handleForeignCode(ForeignCode node) {
-    // Arguments will get inserted in a JS code template.  The arguments will
-    // not always be evaluated (e.g. if the template is '# && #').
-    // TODO(asgerf): We could analyze the JS AST to see if arguments are
-    //               definitely evaluated left-to-right.
+    // Some arguments will get inserted in a JS code template.  The arguments
+    // will not always be evaluated (e.g. the second placeholder in the template
+    // '# && #').
+
+    // TODO(sra): Find out which tree_ir expressions are not nullable. It helps
+    // a lot with templates like '#.push(#)'.
+    bool isNullable(e) => true;
+
+    int safeArguments =
+      PlaceholderSafetyAnalysis.analyze(node.codeTemplate.ast, isNullable);
     inEmptyEnvironment(() {
-      _rewriteList(node.arguments);
+      for (int i = node.arguments.length - 1; i >= safeArguments; --i) {
+        node.arguments[i] = visitExpression(node.arguments[i]);
+      }
     });
+    for (int i = safeArguments - 1; i >= 0; --i) {
+      node.arguments[i] = visitExpression(node.arguments[i]);
+    }
   }
 
   @override
diff --git a/pkg/compiler/lib/src/types/abstract_value_domain.dart b/pkg/compiler/lib/src/types/abstract_value_domain.dart
index 14c9939..6512c5a 100644
--- a/pkg/compiler/lib/src/types/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/types/abstract_value_domain.dart
@@ -161,4 +161,9 @@
 
   /// The length property of [value], or `null` if unknown.
   int getContainerLength(AbstractValue value);
-}
\ No newline at end of file
+
+  /// Returns the type of the entry of [container] at a given index.
+  /// Returns `null` if unknown.
+  AbstractValue indexWithConstant(AbstractValue container,
+                                  ConstantValue indexValue);
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 2160dd9..ff080b5 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -121,6 +121,8 @@
 
 [ $compiler == dartanalyzer || $compiler == dart2analyzer ]
 compiler/samples/compile_loop/compile_loop: CompileTimeError  # Issue 16524
+lookup_map/test/version_check_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
+lookup_map/test/lookup_map_test: StaticWarning # https://github.com/dart-lang/http_parser/issues/6
 
 [ $compiler == dart2js && $csp ]
 # This test cannot run under CSP because it is injecting a JavaScript polyfill
diff --git a/pkg/pkg_files.gyp b/pkg/pkg_files.gyp
index 78a751f..afb09cf 100644
--- a/pkg/pkg_files.gyp
+++ b/pkg/pkg_files.gyp
@@ -4,10 +4,13 @@
 
 {
   'targets': [
-    # Other targets depend on pkg files, but have to many inputs, which causes
+    # Other targets depend on pkg files, but have too many inputs, which causes
     # issues on some platforms.
     # This target lists all the files in pkg and third_party/pkg,
-    # and creates a single pkg_files.stamp
+    # and creates the timestamp pkg_files.stamp, which depends on some
+    # intermediate helper timestamps.
+    # We split third_party/pkg up into three groups, based on the last
+    # character before .dart at the end of the filename.
     {
       'target_name': 'pkg_files_stamp',
       'type': 'none',
@@ -17,7 +20,9 @@
           'inputs': [
             '../tools/create_timestamp_file.py',
             '<!@(["python", "../tools/list_files.py", "\\.dart$", "."])',
-            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
           ],
           'outputs': [
             '<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
@@ -28,15 +33,47 @@
           ],
         },
         {
-          'action_name': 'make_third_party_pkg_files_stamp',
+          'action_name': 'make_third_party_pkg_files_1_stamp',
           'inputs': [
             '../tools/create_timestamp_file.py',
             '<!@(["python", "../tools/list_files.py",'
-                '"^(?!.*_test.dart).*dart$",'
+                '"^(?!.*_test\.dart).*[a-k]\.dart$",'
                 '"../third_party/pkg"])',
           ],
           'outputs': [
-            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files.stamp',
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
+          ],
+          'action': [
+            'python', '../tools/create_timestamp_file.py',
+            '<@(_outputs)',
+          ],
+        },
+        {
+          'action_name': 'make_third_party_pkg_files_2_stamp',
+          'inputs': [
+            '../tools/create_timestamp_file.py',
+            '<!@(["python", "../tools/list_files.py",'
+                '"^(?!.*_test\.dart).*[l-r]\.dart$",'
+                '"../third_party/pkg"])',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
+          ],
+          'action': [
+            'python', '../tools/create_timestamp_file.py',
+            '<@(_outputs)',
+          ],
+        },
+        {
+          'action_name': 'make_third_party_pkg_files_3_stamp',
+          'inputs': [
+            '../tools/create_timestamp_file.py',
+            '<!@(["python", "../tools/list_files.py",'
+                '"^(?!.*_test\.dart).*[^a-r]\.dart$",'
+                '"../third_party/pkg"])',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
           ],
           'action': [
             'python', '../tools/create_timestamp_file.py',
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 5ae31ae..7088bed 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -396,6 +396,7 @@
 void _handlePackagesReply(msg) {
   // Make sure to close the _packagePort before any other action.
   _packagesPort.close();
+  _packagesPort = null;
 
   if (_traceLoading) {
     _log("Got packages reply: $msg");
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 29485e2..f8ef12f 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -882,15 +882,6 @@
 "--version\n"
 "  Print the VM version.\n"
 "\n"
-"--debug[:<port number>]\n"
-"  enables debugging and listens on specified port for debugger connections\n"
-"  (default port number is 5858)\n"
-"\n"
-"--break-at=<location>\n"
-"  sets a breakpoint at specified location where <location> is one of :\n"
-"  url:<line_num> e.g. test.dart:10\n"
-"  [<class_name>.]<function_name> e.g. B.foo\n"
-"\n"
 "--snapshot=<file_name>\n"
 "  loads Dart script and generates a snapshot in the specified file\n"
 "\n"
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 987af55..3816aa2 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -28,7 +28,17 @@
 // HTTP server.
 Server server;
 Future<Server> serverFuture;
-HashMap<String, Asset> assets;
+HashMap<String, Asset> _assets;
+HashMap<String, Asset> get assets {
+  if (_assets == null) {
+    try {
+      _assets = Asset.request();
+    } catch (e) {
+      print('Could not load Observatory assets: $e');
+    }
+  }
+  return _assets;
+}
 
 _onShutdown() {
   if (server != null) {
@@ -43,11 +53,6 @@
 }
 
 _bootServer() {
-  try {
-    assets = Asset.request();
-  } catch (e) {
-    print('Could not load Observatory assets: $e');
-  }
   // Lazily create service.
   var service = new VMService();
   service.onShutdown = _onShutdown;
diff --git a/runtime/lib/date.cc b/runtime/lib/date.cc
index 67891b9..cf92809 100644
--- a/runtime/lib/date.cc
+++ b/runtime/lib/date.cc
@@ -14,7 +14,7 @@
 
 static int32_t kMaxAllowedSeconds = 2100000000;
 
-DEFINE_NATIVE_ENTRY(DateNatives_timeZoneName, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneName, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
@@ -26,7 +26,7 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(DateNatives_timeZoneOffsetInSeconds, 1) {
+DEFINE_NATIVE_ENTRY(DateTime_timeZoneOffsetInSeconds, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(
       Integer, dart_seconds, arguments->NativeArgAt(0));
   int64_t seconds = dart_seconds.AsInt64Value();
@@ -38,14 +38,14 @@
 }
 
 
-DEFINE_NATIVE_ENTRY(DateNatives_localTimeZoneAdjustmentInSeconds, 0) {
+DEFINE_NATIVE_ENTRY(DateTime_localTimeZoneAdjustmentInSeconds, 0) {
   int adjustment = OS::GetLocalTimeZoneAdjustmentInSeconds();
   return Integer::New(adjustment);
 }
 
 
-DEFINE_NATIVE_ENTRY(DateNatives_currentTimeMillis, 0) {
-  return Integer::New(OS::GetCurrentTimeMillis());
+DEFINE_NATIVE_ENTRY(DateTime_currentTimeMicros, 0) {
+  return Integer::New(OS::GetCurrentTimeMicros());
 }
 
 }  // namespace dart
diff --git a/runtime/lib/date_patch.dart b/runtime/lib/date_patch.dart
index 6c5c0c2..4697901 100644
--- a/runtime/lib/date_patch.dart
+++ b/runtime/lib/date_patch.dart
@@ -7,28 +7,39 @@
 patch class DateTime {
   // Natives.
   // The natives have been moved up here to work around Issue 10401.
-  static int _getCurrentMs() native "DateNatives_currentTimeMillis";
+  static int _getCurrentMicros() native "DateTime_currentTimeMicros";
 
   static String _timeZoneNameForClampedSeconds(int secondsSinceEpoch)
-      native "DateNatives_timeZoneName";
+      native "DateTime_timeZoneName";
 
   static int _timeZoneOffsetInSecondsForClampedSeconds(int secondsSinceEpoch)
-      native "DateNatives_timeZoneOffsetInSeconds";
+      native "DateTime_timeZoneOffsetInSeconds";
 
   static int _localTimeZoneAdjustmentInSeconds()
-      native "DateNatives_localTimeZoneAdjustmentInSeconds";
+      native "DateTime_localTimeZoneAdjustmentInSeconds";
 
-  static const _MILLISECOND_INDEX = 0;
-  static const _SECOND_INDEX = 1;
-  static const _MINUTE_INDEX = 2;
-  static const _HOUR_INDEX = 3;
-  static const _DAY_INDEX = 4;
-  static const _WEEKDAY_INDEX = 5;
-  static const _MONTH_INDEX = 6;
-  static const _YEAR_INDEX = 7;
+  static const _MICROSECOND_INDEX = 0;
+  static const _MILLISECOND_INDEX = 1;
+  static const _SECOND_INDEX = 2;
+  static const _MINUTE_INDEX = 3;
+  static const _HOUR_INDEX = 4;
+  static const _DAY_INDEX = 5;
+  static const _WEEKDAY_INDEX = 6;
+  static const _MONTH_INDEX = 7;
+  static const _YEAR_INDEX = 8;
 
   List __parts;
 
+  /* patch */ DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+                                                  {bool isUtc: false})
+      : this._withValue(
+          millisecondsSinceEpoch * Duration.MICROSECONDS_PER_MILLISECOND,
+          isUtc: isUtc);
+
+  /* patch */ DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+                                                  {bool isUtc: false})
+      : this._withValue(microsecondsSinceEpoch, isUtc: isUtc);
+
   /* patch */ DateTime._internal(int year,
                                  int month,
                                  int day,
@@ -36,27 +47,29 @@
                                  int minute,
                                  int second,
                                  int millisecond,
+                                 int microsecond,
                                  bool isUtc)
       : this.isUtc = isUtc,
-        this.millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
-            year, month, day, hour, minute, second, millisecond, isUtc) {
-    if (millisecondsSinceEpoch == null) throw new ArgumentError();
+        this._value = _brokenDownDateToValue(
+            year, month, day, hour, minute, second, millisecond, microsecond,
+            isUtc) {
+    if (_value == null) throw new ArgumentError();
     if (isUtc == null) throw new ArgumentError();
   }
 
   /* patch */ DateTime._now()
       : isUtc = false,
-        millisecondsSinceEpoch = _getCurrentMs() {
+        _value = _getCurrentMicros() {
   }
 
   /* patch */ String get timeZoneName {
     if (isUtc) return "UTC";
-    return _timeZoneName(millisecondsSinceEpoch);
+    return _timeZoneName(microsecondsSinceEpoch);
   }
 
   /* patch */ Duration get timeZoneOffset {
     if (isUtc) return new Duration();
-    int offsetInSeconds = _timeZoneOffsetInSeconds(millisecondsSinceEpoch);
+    int offsetInSeconds = _timeZoneOffsetInSeconds(microsecondsSinceEpoch);
     return new Duration(seconds: offsetInSeconds);
   }
 
@@ -66,7 +79,7 @@
       const [const [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
              const [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]];
 
-  static List _computeUpperPart(int localMs) {
+  static List _computeUpperPart(int localMicros) {
     const int DAYS_IN_4_YEARS = 4 * 365 + 1;
     const int DAYS_IN_100_YEARS = 25 * DAYS_IN_4_YEARS - 1;
     const int DAYS_IN_400_YEARS = 4 * DAYS_IN_100_YEARS + 1;
@@ -80,8 +93,8 @@
     int resultDay = 0;
 
     // Always round down.
-    final int daysSince1970 = _flooredDivision(localMs,
-                                               Duration.MILLISECONDS_PER_DAY);
+    final int daysSince1970 = _flooredDivision(localMicros,
+                                               Duration.MICROSECONDS_PER_DAY);
     int days = daysSince1970;
     days += DAYS_OFFSET;
     resultYear = 400 * (days ~/ DAYS_IN_400_YEARS) - YEARS_OFFSET;
@@ -110,16 +123,20 @@
     }
     resultDay = days - daysUntilMonth[resultMonth - 1] + 1;
 
-    int resultMillisecond = localMs % Duration.MILLISECONDS_PER_SECOND;
+    int resultMicrosecond = localMicros % Duration.MICROSECONDS_PER_MILLISECOND;
+    int resultMillisecond =
+        _flooredDivision(localMicros, Duration.MICROSECONDS_PER_MILLISECOND) %
+            Duration.MILLISECONDS_PER_SECOND;
     int resultSecond =
-        _flooredDivision(localMs, Duration.MILLISECONDS_PER_SECOND) %
+        _flooredDivision(localMicros, Duration.MICROSECONDS_PER_SECOND) %
             Duration.SECONDS_PER_MINUTE;
 
-    int resultMinute = _flooredDivision(localMs,
-                                        Duration.MILLISECONDS_PER_MINUTE);
+    int resultMinute = _flooredDivision(localMicros,
+                                        Duration.MICROSECONDS_PER_MINUTE);
     resultMinute %= Duration.MINUTES_PER_HOUR;
 
-    int resultHour = _flooredDivision(localMs, Duration.MILLISECONDS_PER_HOUR);
+    int resultHour =
+        _flooredDivision(localMicros, Duration.MICROSECONDS_PER_HOUR);
     resultHour %= Duration.HOURS_PER_DAY;
 
     // In accordance with ISO 8601 a week
@@ -129,6 +146,7 @@
           DateTime.DAYS_PER_WEEK) + DateTime.MONDAY;
 
     List list = new List(_YEAR_INDEX + 1);
+    list[_MICROSECOND_INDEX] = resultMicrosecond;
     list[_MILLISECOND_INDEX] = resultMillisecond;
     list[_SECOND_INDEX] = resultSecond;
     list[_MINUTE_INDEX] = resultMinute;
@@ -142,11 +160,32 @@
 
   get _parts {
     if (__parts == null) {
-      __parts = _computeUpperPart(_localDateInUtcMs);
+      __parts = _computeUpperPart(_localDateInUtcMicros);
     }
     return __parts;
   }
 
+  /* patch */ DateTime add(Duration duration) {
+    return new DateTime._withValue(
+        _value + duration.inMicroseconds, isUtc: isUtc);
+  }
+
+  /* patch */ DateTime subtract(Duration duration) {
+    return new DateTime._withValue(
+        _value - duration.inMicroseconds, isUtc: isUtc);
+  }
+
+  /* patch */ Duration difference(DateTime other) {
+    return new Duration(microseconds: _value - other._value);
+  }
+
+  /* patch */ int get millisecondsSinceEpoch =>
+      _value ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+
+  /* patch */ int get microsecondsSinceEpoch => _value;
+
+  /* patch */ int get microsecond => _parts[_MICROSECOND_INDEX];
+
   /* patch */ int get millisecond => _parts[_MILLISECOND_INDEX];
 
   /* patch */ int get second => _parts[_SECOND_INDEX];
@@ -164,26 +203,26 @@
   /* patch */ int get year => _parts[_YEAR_INDEX];
 
   /**
-   * Returns the amount of milliseconds in UTC that represent the same values
+   * Returns the amount of microseconds in UTC that represent the same values
    * as [this].
    *
-   * Say [:t:] is the result of this function, then
-   * * [:this.year == new DateTime.fromMillisecondsSinceEpoch(t, true).year:],
-   * * [:this.month == new DateTime.fromMillisecondsSinceEpoch(t, true).month:],
-   * * [:this.day == new DateTime.fromMillisecondsSinceEpoch(t, true).day:],
-   * * [:this.hour == new DateTime.fromMillisecondsSinceEpoch(t, true).hour:],
+   * Say `t` is the result of this function, then
+   * * `this.year == new DateTime.fromMicrosecondsSinceEpoch(t, true).year`,
+   * * `this.month == new DateTime.fromMicrosecondsSinceEpoch(t, true).month`,
+   * * `this.day == new DateTime.fromMicrosecondsSinceEpoch(t, true).day`,
+   * * `this.hour == new DateTime.fromMicrosecondsSinceEpoch(t, true).hour`,
    * * ...
    *
    * Daylight savings is computed as if the date was computed in [1970..2037].
    * If [this] lies outside this range then it is a year with similar
    * properties (leap year, weekdays) is used instead.
    */
-  int get _localDateInUtcMs {
-    int ms = millisecondsSinceEpoch;
-    if (isUtc) return ms;
+  int get _localDateInUtcMicros {
+    int micros = _value;
+    if (isUtc) return micros;
     int offset =
-        _timeZoneOffsetInSeconds(ms) * Duration.MILLISECONDS_PER_SECOND;
-    return ms + offset;
+        _timeZoneOffsetInSeconds(micros) * Duration.MICROSECONDS_PER_SECOND;
+    return micros + offset;
   }
 
   static int _flooredDivision(int a, int b) {
@@ -204,9 +243,10 @@
     return (y % 4 == 0) && ((y % 16 == 0) || (y % 100 != 0));
   }
 
-  /* patch */ static int _brokenDownDateToMillisecondsSinceEpoch(
+  /// Converts the given broken down date to microseconds.
+  /* patch */ static int _brokenDownDateToValue(
       int year, int month, int day,
-      int hour, int minute, int second, int millisecond,
+      int hour, int minute, int second, int millisecond, int microsecond,
       bool isUtc) {
     // Simplify calculations by working with zero-based month.
     --month;
@@ -225,20 +265,21 @@
     int days = day - 1;
     days += _DAYS_UNTIL_MONTH[_isLeapYear(year) ? 1 : 0][month];
     days += _dayFromYear(year);
-    int millisecondsSinceEpoch =
-        days   * Duration.MILLISECONDS_PER_DAY    +
-        hour   * Duration.MILLISECONDS_PER_HOUR   +
-        minute * Duration.MILLISECONDS_PER_MINUTE +
-        second * Duration.MILLISECONDS_PER_SECOND +
-        millisecond;
+    int microsecondsSinceEpoch =
+        days   * Duration.MICROSECONDS_PER_DAY    +
+        hour   * Duration.MICROSECONDS_PER_HOUR   +
+        minute * Duration.MICROSECONDS_PER_MINUTE +
+        second * Duration.MICROSECONDS_PER_SECOND +
+        millisecond * Duration.MICROSECONDS_PER_MILLISECOND +
+        microsecond;
 
     // Since [_timeZoneOffsetInSeconds] will crash if the input is far out of
     // the valid range we do a preliminary test that weeds out values that can
     // not become valid even with timezone adjustments.
     // The timezone adjustment is always less than a day, so adding a security
     // margin of one day should be enough.
-    if (millisecondsSinceEpoch.abs() >
-        (_MAX_MILLISECONDS_SINCE_EPOCH + Duration.MILLISECONDS_PER_DAY)) {
+    if (microsecondsSinceEpoch.abs() >
+        _MAX_MILLISECONDS_SINCE_EPOCH * 1000 + Duration.MICROSECONDS_PER_DAY) {
       return null;
     }
 
@@ -246,15 +287,17 @@
       // Note that we need to remove the local timezone adjustement before
       // asking for the correct zone offset.
       int adjustment = _localTimeZoneAdjustmentInSeconds() *
-          Duration.MILLISECONDS_PER_SECOND;
+          Duration.MICROSECONDS_PER_SECOND;
+
       int zoneOffset =
-          _timeZoneOffsetInSeconds(millisecondsSinceEpoch - adjustment);
-      millisecondsSinceEpoch -= zoneOffset * Duration.MILLISECONDS_PER_SECOND;
+          _timeZoneOffsetInSeconds(microsecondsSinceEpoch - adjustment);
+      microsecondsSinceEpoch -= zoneOffset * Duration.MICROSECONDS_PER_SECOND;
     }
-    if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
+    if (microsecondsSinceEpoch.abs() >
+        _MAX_MILLISECONDS_SINCE_EPOCH * Duration.MICROSECONDS_PER_MILLISECOND) {
       return null;
     }
-    return millisecondsSinceEpoch;
+    return microsecondsSinceEpoch;
   }
 
   static int _weekDay(y) {
@@ -304,25 +347,25 @@
       // According to V8 this fast case works for dates from 1970 to 2099.
       return 1970 + (4 * days + 2) ~/ DAYS_IN_4_YEARS;
     }
-    int ms = secondsSinceEpoch * Duration.MILLISECONDS_PER_SECOND;
-    return _computeUpperPart(ms)[_YEAR_INDEX];
+    int micros = secondsSinceEpoch * Duration.MICROSECONDS_PER_SECOND;
+    return _computeUpperPart(micros)[_YEAR_INDEX];
   }
 
   /**
    * Returns a date in seconds that is equivalent to the current date. An
-   * equivalent date has the same fields ([:month:], [:day:], etc.) as the
-   * [this], but the [:year:] is in the range [1970..2037].
+   * equivalent date has the same fields (`month`, `day`, etc.) as the
+   * [this], but the `year` is in the range [1970..2037].
    *
    * * The time since the beginning of the year is the same.
    * * If [this] is in a leap year then the returned seconds are in a leap
    *   year, too.
    * * The week day of [this] is the same as the one for the returned date.
    */
-  static int _equivalentSeconds(int millisecondsSinceEpoch) {
+  static int _equivalentSeconds(int microsecondsSinceEpoch) {
     const int CUT_OFF_SECONDS = 2100000000;
 
-    int secondsSinceEpoch = _flooredDivision(millisecondsSinceEpoch,
-                                             Duration.MILLISECONDS_PER_SECOND);
+    int secondsSinceEpoch = _flooredDivision(microsecondsSinceEpoch,
+                                             Duration.MICROSECONDS_PER_SECOND);
 
     if (secondsSinceEpoch < 0 || secondsSinceEpoch >= CUT_OFF_SECONDS) {
       int year = _yearsFromSecondsSinceEpoch(secondsSinceEpoch);
@@ -335,13 +378,13 @@
     return secondsSinceEpoch;
   }
 
-  static int _timeZoneOffsetInSeconds(int millisecondsSinceEpoch) {
-    int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
+  static int _timeZoneOffsetInSeconds(int microsecondsSinceEpoch) {
+    int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
     return _timeZoneOffsetInSecondsForClampedSeconds(equivalentSeconds);
   }
 
-  static String _timeZoneName(int millisecondsSinceEpoch) {
-    int equivalentSeconds = _equivalentSeconds(millisecondsSinceEpoch);
+  static String _timeZoneName(int microsecondsSinceEpoch) {
+    int equivalentSeconds = _equivalentSeconds(microsecondsSinceEpoch);
     return _timeZoneNameForClampedSeconds(equivalentSeconds);
   }
 }
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 53af2c4..24e6d71 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1206,6 +1206,11 @@
 DEFINE_NATIVE_ENTRY(ClassMirror_type_variables, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(0));
   const Class& klass = Class::Handle(ref.GetClassReferent());
+  const Error& error = Error::Handle(zone, klass.EnsureIsFinalized(thread));
+  if (!error.IsNull()) {
+    Exceptions::PropagateError(error);
+    UNREACHABLE();
+  }
   return CreateTypeVariableList(klass);
 }
 
diff --git a/runtime/lib/stopwatch.cc b/runtime/lib/stopwatch.cc
index 7d8464a..ce8951de 100644
--- a/runtime/lib/stopwatch.cc
+++ b/runtime/lib/stopwatch.cc
@@ -11,7 +11,7 @@
 
 DEFINE_NATIVE_ENTRY(Stopwatch_now, 0) {
   // TODO(iposva): investigate other hi-res time sources such as cycle count.
-  return Integer::New(OS::GetCurrentTimeMicros());
+  return Integer::New(OS::GetCurrentMonotonicMicros());
 }
 
 
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index 39fa28b..f0e5982 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -32,7 +32,7 @@
 
 
 DEFINE_NATIVE_ENTRY(Timeline_getTraceClock, 0) {
-  return Integer::New(OS::GetCurrentTraceMicros(), Heap::kNew, true);
+  return Integer::New(OS::GetCurrentMonotonicMicros(), Heap::kNew, true);
 }
 
 
diff --git a/runtime/tools/create_archive.py b/runtime/tools/create_archive.py
index 0a3d756..f2fe6c1 100644
--- a/runtime/tools/create_archive.py
+++ b/runtime/tools/create_archive.py
@@ -19,6 +19,8 @@
   for input_file_name in files:
     # Chop off client_root.
     archive_file_name = input_file_name[ len(client_root) : ]
+    # Replace back slash with forward slash. So we do not have Windows paths.
+    archive_file_name = archive_file_name.replace("\\", "/")
     # Open input file and add it to the archive.
     with open(input_file_name, 'rb') as input_file:
       tarInfo = tarfile.TarInfo(name=archive_file_name)
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 315ce85..76413a6 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -145,10 +145,10 @@
   V(Random_setupSeed, 1)                                                       \
   V(Random_initialSeed, 0)                                                     \
   V(SecureRandom_getBytes, 1)                                                  \
-  V(DateNatives_currentTimeMillis, 0)                                          \
-  V(DateNatives_timeZoneName, 1)                                               \
-  V(DateNatives_timeZoneOffsetInSeconds, 1)                                    \
-  V(DateNatives_localTimeZoneAdjustmentInSeconds, 0)                           \
+  V(DateTime_currentTimeMicros, 0)                                             \
+  V(DateTime_timeZoneName, 1)                                                  \
+  V(DateTime_timeZoneOffsetInSeconds, 1)                                       \
+  V(DateTime_localTimeZoneAdjustmentInSeconds, 0)                              \
   V(AssertionError_throwNew, 2)                                                \
   V(Async_rethrow, 2)                                                          \
   V(StackTrace_current, 0)                                                     \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index d8434d9..9ca3731 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1269,7 +1269,8 @@
   for (intptr_t i = 0; i < num_type_params; i++) {
     type_param ^= type_params.TypeAt(i);
     bound = type_param.bound();
-    if (bound.IsFinalized() || bound.IsBeingFinalized()) {
+    // Bound may be finalized, but not canonical yet.
+    if (bound.IsCanonical() || bound.IsBeingFinalized()) {
       // A bound involved in F-bounded quantification may form a cycle.
       continue;
     }
@@ -2231,7 +2232,10 @@
   FinalizeTypeParameters(cls);  // May change super type.
   super_class = cls.SuperClass();
   ASSERT(super_class.IsNull() || super_class.is_type_finalized());
-  ResolveUpperBounds(cls);
+  // Only resolving rather than finalizing the upper bounds here would result in
+  // instantiated type parameters of the super type to temporarily have
+  // unfinalized bounds. It is more efficient to finalize them early.
+  FinalizeUpperBounds(cls);
   // Finalize super type.
   AbstractType& super_type = AbstractType::Handle(cls.super_type());
   if (!super_type.IsNull()) {
@@ -2344,6 +2348,7 @@
 void ClassFinalizer::FinalizeClass(const Class& cls) {
   Thread* thread = Thread::Current();
   HANDLESCOPE(thread);
+  ASSERT(cls.is_type_finalized());
   if (cls.is_finalized()) {
     return;
   }
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index c42072f..493cc0e 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -309,6 +309,17 @@
   // also allows us to reset the marked_for_parsing state in case we see an
   // error.
   VMTagScope tagScope(thread, VMTag::kCompileClassTagId);
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "CompileClass");
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(
+        0,
+        "class",
+        const_cast<char*>(cls.ToCString()));
+  }
+
   GrowableHandlePtrArray<const Class> parse_list(thread->zone(), 4);
   GrowableHandlePtrArray<const Class> patch_list(thread->zone(), 4);
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 5971023..f607b18 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -5560,7 +5560,7 @@
 
 
 DART_EXPORT int64_t Dart_TimelineGetMicros() {
-  return OS::GetCurrentTraceMicros();
+  return OS::GetCurrentMonotonicMicros();
 }
 
 
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 5a252e5..4ae6851 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -167,15 +167,15 @@
     while (!cls.IsNull()) {
       function ^= cls.LookupDynamicFunction(getter_name);
       if (!function.IsNull()) {
-        // Getters don't have a stack overflow check, so do one in C++.
-
         Isolate* isolate = Isolate::Current();
-#if defined(USING_SIMULATOR)
-        uword stack_pos = Simulator::Current()->get_register(SPREG);
-#else
-        uword stack_pos = Isolate::GetCurrentStackPointer();
+        uword c_stack_pos = Isolate::GetCurrentStackPointer();
+        uword c_stack_limit = OSThread::Current()->stack_base() -
+                              OSThread::GetSpecifiedStackSize();
+#if !defined(USING_SIMULATOR)
+        ASSERT(c_stack_limit == isolate->saved_stack_limit());
 #endif
-        if (stack_pos < isolate->saved_stack_limit()) {
+
+        if (c_stack_pos < c_stack_limit) {
           const Instance& exception =
             Instance::Handle(isolate->object_store()->stack_overflow());
           return UnhandledException::New(exception, Stacktrace::Handle());
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 134d85c..658e973 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -43,7 +43,7 @@
       deopt_reason_(ICData::kDeoptUnknown),
       deopt_flags_(0),
       thread_(Thread::Current()),
-      timeline_event_(NULL),
+      deopt_start_micros_(0),
       deferred_slots_(NULL),
       deferred_objects_count_(0),
       deferred_objects_(NULL),
@@ -99,14 +99,7 @@
   if (dest_options != kDestIsAllocated) {
     // kDestIsAllocated is used by the debugger to generate a stack trace
     // and does not signal a real deopt.
-    Isolate* isolate = Isolate::Current();
-    TimelineStream* compiler_stream = isolate->GetCompilerStream();
-    ASSERT(compiler_stream != NULL);
-    timeline_event_ = compiler_stream->StartEvent();
-    if (timeline_event_ != NULL) {
-      timeline_event_->DurationBegin("Deoptimize");
-      timeline_event_->SetNumArguments(3);
-    }
+    deopt_start_micros_ = OS::GetCurrentMonotonicMicros();
   }
 
   if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
@@ -143,24 +136,28 @@
   delete[] deferred_objects_;
   deferred_objects_ = NULL;
   deferred_objects_count_ = 0;
-  if (timeline_event_ != NULL) {
-    const Code& code = Code::Handle(zone(), code_);
-    const Function& function = Function::Handle(zone(), code.function());
-    timeline_event_->CopyArgument(
-        0,
-        "function",
-        const_cast<char*>(function.QualifiedUserVisibleNameCString()));
-    timeline_event_->CopyArgument(
-        1,
-        "reason",
-        const_cast<char*>(DeoptReasonToCString(deopt_reason())));
-    timeline_event_->FormatArgument(
-        2,
-        "deoptimizationCount",
-        "%d",
-        function.deoptimization_counter());
-    timeline_event_->DurationEnd();
-    timeline_event_->Complete();
+  if (deopt_start_micros_ != 0) {
+    Isolate* isolate = Isolate::Current();
+    TimelineStream* compiler_stream = isolate->GetCompilerStream();
+    ASSERT(compiler_stream != NULL);
+    if (compiler_stream->Enabled()) {
+      const Code& code = Code::Handle(zone(), code_);
+      const Function& function = Function::Handle(zone(), code.function());
+      const char* function_name = function.QualifiedUserVisibleNameCString();
+      const char* reason = DeoptReasonToCString(deopt_reason());
+      int counter = function.deoptimization_counter();
+      TimelineEvent* timeline_event = compiler_stream->StartEvent();
+      if (timeline_event != NULL) {
+        timeline_event->Duration("Deoptimize",
+                                 deopt_start_micros_,
+                                 OS::GetCurrentMonotonicMicros());
+        timeline_event->SetNumArguments(3);
+        timeline_event->CopyArgument(0, "function", function_name);
+        timeline_event->CopyArgument(1, "reason", reason);
+        timeline_event->FormatArgument(2, "deoptimizationCount", "%d", counter);
+        timeline_event->Complete();
+      }
+    }
   }
 }
 
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index cf357d0..79c206e 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -224,7 +224,7 @@
   uint32_t deopt_flags_;
   intptr_t caller_fp_;
   Thread* thread_;
-  TimelineEvent* timeline_event_;
+  int64_t deopt_start_micros_;
 
   DeferredSlot* deferred_slots_;
 
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 878dba1..8d6e6c1 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -8,6 +8,7 @@
 #include "vm/intermediate_language.h"
 
 #include "vm/cpu.h"
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -2379,6 +2380,7 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 7707e0b..7f85d09 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -7,6 +7,7 @@
 
 #include "vm/intermediate_language.h"
 
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -2102,6 +2103,7 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index c005041..16c4367 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -7,6 +7,7 @@
 
 #include "vm/intermediate_language.h"
 
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -2233,6 +2234,7 @@
 
   Label slow_path, done;
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 3d30dc0..07f30fb 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -7,6 +7,7 @@
 
 #include "vm/intermediate_language.h"
 
+#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -2117,6 +2118,7 @@
 
   Label slow_path, done;
   if (compiler->is_optimizing() &&
+      !Compiler::always_optimize() &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 169b42e..2799c1b 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3787,11 +3787,11 @@
     }
     // Check for reflexivity.
     if (thsi.raw() == other.raw()) {
-      const intptr_t num_type_args = thsi.NumTypeArguments();
-      if (num_type_args == 0) {
+      const intptr_t num_type_params = thsi.NumTypeParameters();
+      if (num_type_params == 0) {
         return true;
       }
-      const intptr_t num_type_params = thsi.NumTypeParameters();
+      const intptr_t num_type_args = thsi.NumTypeArguments();
       const intptr_t from_index = num_type_args - num_type_params;
       // Since we do not truncate the type argument vector of a subclass (see
       // below), we only check a subvector of the proper length.
@@ -9370,9 +9370,7 @@
   // Library::LoadedScripts() can find it without having to iterate
   // over the members of each class.
   ASSERT(i < num_classes);  // We must have found a class.
-  Class& pc = Class::Handle();
-  pc ^= patch_classes.At(i);
-  const Script& patch_script = Script::Handle(pc.script());
+  const Script& patch_script = Script::Handle(cls.script());
   patch_classes.SetAt(i, patch_script);
 }
 
@@ -9816,7 +9814,7 @@
         owner_script = Class::Cast(entry).script();
       }  else {
         ASSERT(entry.IsScript());
-        owner_script ^= Script::Cast(entry).raw();
+        owner_script = Script::Cast(entry).raw();
       }
       AddScriptIfUnique(scripts, owner_script);
     }
@@ -13379,7 +13377,7 @@
   VerifiedMemory::Accept(region.start(), region.size());
   CPU::FlushICache(instrs.EntryPoint(), instrs.size());
 
-  code.set_compile_timestamp(OS::GetCurrentTraceMicros());
+  code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
   CodeObservers::NotifyAll(name,
                            instrs.EntryPoint(),
                            assembler->prologue_offset(),
@@ -15630,8 +15628,8 @@
                             const AbstractType& other,
                             Error* bound_error,
                             Heap::Space space) const {
-  ASSERT(IsResolved());
-  ASSERT(other.IsResolved());
+  ASSERT(IsFinalized());
+  ASSERT(other.IsFinalized());
   if (IsMalformed() || other.IsMalformed()) {
     // Malformed types involved in subtype tests should be handled specially
     // by the caller. Malformed types should only be encountered here in a
@@ -15685,6 +15683,15 @@
       }
     }
     const AbstractType& bound = AbstractType::Handle(type_param.bound());
+    // We may be checking bounds at finalization time and can encounter
+    // a still unfinalized bound.
+    if (!bound.IsFinalized() && !bound.IsBeingFinalized()) {
+      ClassFinalizer::FinalizeType(
+          Class::Handle(type_param.parameterized_class()),
+          bound,
+          ClassFinalizer::kCanonicalize);
+      type_param.set_bound(bound);
+    }
     if (bound.IsMoreSpecificThan(other, bound_error)) {
       return true;
     }
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index 5285ec8..a403df2 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -48,7 +48,7 @@
   static int64_t GetCurrentTimeMicros();
 
   // Returns the current time used by the tracing infrastructure.
-  static int64_t GetCurrentTraceMicros();
+  static int64_t GetCurrentMonotonicMicros();
 
   // Returns a cleared aligned array of type T with n entries.
   // Alignment must be >= 16 and a power of two.
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 1d448d0..5c09baf 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -179,7 +179,7 @@
 }
 
 
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 25c64b7..7924be1 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -396,7 +396,7 @@
 }
 
 
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
   struct timespec ts;
   if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
     UNREACHABLE();
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 1a338f4..d2db92d 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -90,7 +90,7 @@
 }
 
 
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
 #if TARGET_OS_IOS
   // On iOS mach_absolute_time stops while the device is sleeping. Instead use
   // now - KERN_BOOTTIME to get a time difference that is not impacted by clock
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 5af6c71..917ee6f 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -123,7 +123,7 @@
 
 static int64_t qpc_ticks_per_second = 0;
 
-int64_t OS::GetCurrentTraceMicros() {
+int64_t OS::GetCurrentMonotonicMicros() {
   if (qpc_ticks_per_second == 0) {
     // QueryPerformanceCounter not supported, fallback.
     return GetCurrentTimeMicros();
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index e20ff43..89cf988 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -453,6 +453,17 @@
   ASSERT(thread->long_jump_base()->IsSafeToJump());
   CSTAT_TIMER_SCOPE(thread, parser_timer);
   VMTagScope tagScope(thread, VMTag::kCompileTopLevelTagId);
+  TimelineDurationScope tds(thread,
+                            thread->isolate()->GetCompilerStream(),
+                            "CompileTopLevel");
+  if (tds.enabled()) {
+    tds.SetNumArguments(1);
+    tds.CopyArgument(
+        0,
+        "script",
+        const_cast<char*>(String::Handle(script.url()).ToCString()));
+  }
+
   Parser parser(script, library, 0);
   parser.ParseTopLevel();
 }
@@ -1696,6 +1707,8 @@
         is_match = opening_token == Token::kLBRACK;
         break;
       case Token::kEOS:
+        opening_token = token_stack.RemoveLast();
+        opening_pos = token_pos_stack.RemoveLast();
         unexpected_token_found = true;
         break;
       default:
@@ -3967,7 +3980,7 @@
   if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) {
     func.set_is_reflectable(false);
   }
-  if (method->metadata_pos > 0) {
+  if (FLAG_enable_mirrors && (method->metadata_pos > 0)) {
     library_.AddFunctionMetadata(func, method->metadata_pos);
   }
   if (method->has_native) {
@@ -4067,7 +4080,7 @@
     class_field.set_has_initializer(has_initializer);
     members->AddField(class_field);
     field->field_ = &class_field;
-    if (field->metadata_pos >= 0) {
+    if (FLAG_enable_mirrors && (field->metadata_pos >= 0)) {
       library_.AddFieldMetadata(class_field, field->metadata_pos);
     }
 
@@ -4464,7 +4477,7 @@
   library_.AddClass(cls);
   cls.set_is_synthesized_class();
   cls.set_is_enum_class();
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddClassMetadata(cls, tl_owner, metadata_pos);
   }
   cls.set_super_type(Type::Handle(Z, Type::ObjectType()));
@@ -4587,7 +4600,7 @@
   if (is_abstract) {
     cls.set_is_abstract();
   }
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddClassMetadata(cls, tl_owner, metadata_pos);
   }
 
@@ -5020,7 +5033,7 @@
   }
   ExpectSemicolon();
   pending_classes.Add(mixin_application, Heap::kOld);
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos);
   }
 }
@@ -5186,7 +5199,7 @@
   ASSERT(!function_type_alias.IsCanonicalSignatureClass());
   ASSERT(!function_type_alias.is_finalized());
   pending_classes.Add(function_type_alias, Heap::kOld);
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddClassMetadata(function_type_alias,
                               tl_owner,
                               metadata_pos);
@@ -5309,7 +5322,7 @@
                                           declaration_pos);
       type_parameters_array.Add(
           &AbstractType::ZoneHandle(Z, type_parameter.raw()));
-      if (metadata_pos >= 0) {
+      if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
         library_.AddTypeParameterMetadata(type_parameter, metadata_pos);
       }
       index++;
@@ -5468,7 +5481,7 @@
     field.SetStaticValue(Object::null_instance(), true);
     top_level->AddField(field);
     library_.AddObject(field, var_name);
-    if (metadata_pos >= 0) {
+    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
       library_.AddFieldMetadata(field, metadata_pos);
     }
     if (CurrentToken() == Token::kASSIGN) {
@@ -5659,7 +5672,7 @@
     toplevel_cls.RemoveFunction(replaced_func);
     library_.ReplaceObject(func, func_name);
   }
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddFunctionMetadata(func, metadata_pos);
   }
 }
@@ -5824,7 +5837,7 @@
     toplevel_cls.RemoveFunction(replaced_func);
     library_.ReplaceObject(func, accessor_name);
   }
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     library_.AddFunctionMetadata(func, metadata_pos);
   }
 }
@@ -5986,7 +5999,7 @@
 
   Namespace& ns = Namespace::Handle(Z,
       Namespace::New(library, show_names, hide_names));
-  if (metadata_pos >= 0) {
+  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
     ns.AddMetadata(tl_owner, metadata_pos);
   }
 
@@ -6072,7 +6085,7 @@
       ReportError("patch cannot override library name");
     }
     ParseLibraryName();
-    if (metadata_pos >= 0) {
+    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
       library_.AddLibraryMetadata(tl_owner, metadata_pos);
     }
     rewind_pos = TokenPos();
@@ -7661,7 +7674,7 @@
                                             innermost_function(),
                                             function_pos);
     function.set_result_type(result_type);
-    if (metadata_pos >= 0) {
+    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
       library_.AddFunctionMetadata(function, metadata_pos);
     }
   }
@@ -8655,7 +8668,7 @@
 
   // Parse stream expression.
   ExpectToken(Token::kIN);
-  const intptr_t stream_pos = TokenPos();
+  const intptr_t stream_expr_pos = TokenPos();
   AstNode* stream_expr =
       ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
   ExpectToken(Token::kRPAREN);
@@ -8674,19 +8687,19 @@
       Function::ZoneHandle(Z, stream_iterator_cls.LookupFunction(
           Symbols::StreamIteratorConstructor()));
   ASSERT(!iterator_ctor.IsNull());
-  ArgumentListNode* ctor_args = new (Z) ArgumentListNode(Scanner::kNoSourcePos);
+  ArgumentListNode* ctor_args = new (Z) ArgumentListNode(stream_expr_pos);
   ctor_args->Add(stream_expr);
   ConstructorCallNode* ctor_call =
-      new (Z) ConstructorCallNode(Scanner::kNoSourcePos,
+      new (Z) ConstructorCallNode(stream_expr_pos,
                               TypeArguments::ZoneHandle(Z),
                               iterator_ctor,
                               ctor_args);
   const AbstractType& iterator_type = Type::ZoneHandle(Z, Type::DynamicType());
   LocalVariable* iterator_var = new(Z) LocalVariable(
-      stream_pos, Symbols::ForInIter(), iterator_type);
+      stream_expr_pos, Symbols::ForInIter(), iterator_type);
   current_block_->scope->AddVariable(iterator_var);
   AstNode* iterator_init =
-      new(Z) StoreLocalNode(stream_pos, iterator_var, ctor_call);
+      new(Z) StoreLocalNode(stream_expr_pos, iterator_var, ctor_call);
   current_block_->statements->Add(iterator_init);
 
   // We need to ensure that the stream is cancelled after the loop.
@@ -8724,15 +8737,15 @@
                          &async_saved_try_ctx,
                          &outer_saved_try_ctx,
                          &outer_async_saved_try_ctx);
-  ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_pos);
+  ArgumentListNode* no_args = new(Z) ArgumentListNode(stream_expr_pos);
   AstNode* iterator_moveNext = new(Z) InstanceCallNode(
-      stream_pos,
-      new(Z) LoadLocalNode(stream_pos, iterator_var),
+      stream_expr_pos,
+      new(Z) LoadLocalNode(stream_expr_pos, iterator_var),
                            Symbols::MoveNext(),
                            no_args);
   OpenBlock();
   AstNode* await_moveNext =
-      new(Z) AwaitNode(stream_pos,
+      new(Z) AwaitNode(stream_expr_pos,
                        iterator_moveNext,
                        saved_try_ctx,
                        async_saved_try_ctx,
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index af80f9f..9f820b0 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -820,7 +820,7 @@
   Isolate* isolate = thread->isolate();
   ASSERT(sample_buffer != NULL);
   Sample* sample = sample_buffer->ReserveSample();
-  sample->Init(isolate, OS::GetCurrentTraceMicros(), tid);
+  sample->Init(isolate, OS::GetCurrentMonotonicMicros(), tid);
   uword vm_tag = thread->vm_tag();
 #if defined(USING_SIMULATOR)
   // When running in the simulator, the runtime entry function address
@@ -898,7 +898,7 @@
       return;
     }
 
-    Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
     sample->SetAllocationCid(cid);
     ProfilerNativeStackWalker native_stack_walker(isolate,
                                                   sample,
@@ -910,7 +910,7 @@
                                                   sp);
     native_stack_walker.walk();
   } else if (exited_dart_code) {
-    Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
     sample->SetAllocationCid(cid);
     ProfilerDartExitStackWalker dart_exit_stack_walker(thread,
                                                        isolate,
@@ -920,7 +920,7 @@
   } else {
     // Fall back.
     uintptr_t pc = GetProgramCounter();
-    Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+    Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
     sample->SetAllocationCid(cid);
     sample->SetAt(0, pc);
   }
@@ -1000,7 +1000,7 @@
   }
 
   // Setup sample.
-  Sample* sample = SetupSample(thread, sample_buffer, os_thread->id());
+  Sample* sample = SetupSample(thread, sample_buffer, os_thread->trace_id());
   // Increment counter for vm tag.
   VMTagCounters* counters = isolate->vm_tag_counters();
   ASSERT(counters != NULL);
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 331fb52..60cde39 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -189,44 +189,45 @@
 
 void TimelineEvent::AsyncBegin(const char* label, int64_t async_id) {
   Init(kAsyncBegin, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(OS::GetCurrentMonotonicMicros());
   // Overload timestamp1_ with the async_id.
-  timestamp1_ = async_id;
+  set_timestamp1(async_id);
 }
 
 
 void TimelineEvent::AsyncInstant(const char* label,
                                  int64_t async_id) {
   Init(kAsyncInstant, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(OS::GetCurrentMonotonicMicros());
   // Overload timestamp1_ with the async_id.
-  timestamp1_ = async_id;
+  set_timestamp1(async_id);
 }
 
 
 void TimelineEvent::AsyncEnd(const char* label,
                              int64_t async_id) {
   Init(kAsyncEnd, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(OS::GetCurrentMonotonicMicros());
   // Overload timestamp1_ with the async_id.
-  timestamp1_ = async_id;
+  set_timestamp1(async_id);
 }
 
 
 void TimelineEvent::DurationBegin(const char* label) {
   Init(kDuration, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(OS::GetCurrentMonotonicMicros());
 }
 
 
 void TimelineEvent::DurationEnd() {
-  timestamp1_ = OS::GetCurrentTraceMicros();
+  ASSERT(timestamp1_ == 0);
+  set_timestamp1(OS::GetCurrentMonotonicMicros());
 }
 
 
 void TimelineEvent::Instant(const char* label) {
   Init(kInstant, label);
-  timestamp0_ = OS::GetCurrentTraceMicros();
+  set_timestamp0(OS::GetCurrentMonotonicMicros());
 }
 
 
@@ -234,22 +235,22 @@
                              int64_t start_micros,
                              int64_t end_micros) {
   Init(kDuration, label);
-  timestamp0_ = start_micros;
-  timestamp1_ = end_micros;
+  set_timestamp0(start_micros);
+  set_timestamp1(end_micros);
 }
 
 
 void TimelineEvent::Begin(const char* label,
                           int64_t micros) {
   Init(kBegin, label);
-  timestamp0_ = micros;
+  set_timestamp0(micros);
 }
 
 
 void TimelineEvent::End(const char* label,
                         int64_t micros) {
   Init(kEnd, label);
-  timestamp0_ = micros;
+  set_timestamp0(micros);
 }
 
 
@@ -453,7 +454,7 @@
 int64_t TimelineEvent::TimeDuration() const {
   if (timestamp1_ == 0) {
     // This duration is still open, use current time as end.
-    return OS::GetCurrentTraceMicros() - timestamp0_;
+    return OS::GetCurrentMonotonicMicros() - timestamp0_;
   }
   return timestamp1_ - timestamp0_;
 }
@@ -529,7 +530,7 @@
     return;
   }
   ASSERT(event != NULL);
-  event->Duration(label_, timestamp_, OS::GetCurrentTraceMicros());
+  event->Duration(label_, timestamp_, OS::GetCurrentMonotonicMicros());
   event->StealArguments(arguments_length_, arguments_);
   event->Complete();
   arguments_length_ = 0;
@@ -545,7 +546,7 @@
     // Stream is not enabled, do nothing.
     return;
   }
-  timestamp_ = OS::GetCurrentTraceMicros();
+  timestamp_ = OS::GetCurrentMonotonicMicros();
   enabled_ = true;
 }
 
@@ -675,6 +676,12 @@
   // We are accessing the thread's timeline block- so take the lock here.
   // This lock will be held until the call to |CompleteEvent| is made.
   thread_block_lock->Lock();
+#if defined(DEBUG)
+  Thread* T = Thread::Current();
+  if (T != NULL) {
+    T->IncrementNoSafepointScopeDepth();
+  }
+#endif  // defined(DEBUG)
 
   TimelineEventBlock* thread_block = thread->timeline_block();
 
@@ -699,6 +706,11 @@
     return event;
   }
   // Drop lock here as no event is being handed out.
+#if defined(DEBUG)
+  if (T != NULL) {
+    T->DecrementNoSafepointScopeDepth();
+  }
+#endif  // defined(DEBUG)
   thread_block_lock->Unlock();
   return NULL;
 }
@@ -714,6 +726,12 @@
   // Unlock the thread's block lock.
   Mutex* thread_block_lock = thread->timeline_block_lock();
   ASSERT(thread_block_lock != NULL);
+#if defined(DEBUG)
+  Thread* T = Thread::Current();
+  if (T != NULL) {
+    T->DecrementNoSafepointScopeDepth();
+  }
+#endif  // defined(DEBUG)
   thread_block_lock->Unlock();
 }
 
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 1c61814..fa55f75 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -129,10 +129,10 @@
                 int64_t end_micros);
 
   void Begin(const char* label,
-             int64_t micros = OS::GetCurrentTraceMicros());
+             int64_t micros = OS::GetCurrentMonotonicMicros());
 
   void End(const char* label,
-           int64_t micros = OS::GetCurrentTraceMicros());
+           int64_t micros = OS::GetCurrentMonotonicMicros());
 
   void SerializedJSON(const char* json);
 
@@ -236,16 +236,6 @@
   const char* GetSerializedJSON() const;
 
  private:
-  int64_t timestamp0_;
-  int64_t timestamp1_;
-  TimelineEventArgument* arguments_;
-  intptr_t arguments_length_;
-  uword state_;
-  const char* label_;
-  const char* category_;
-  ThreadId thread_;
-  Dart_Port isolate_id_;
-
   void FreeArguments();
 
   void StreamInit(TimelineStream* stream);
@@ -257,6 +247,15 @@
     state_ = EventTypeField::update(event_type, state_);
   }
 
+  void set_timestamp0(int64_t value) {
+    ASSERT(timestamp0_ == 0);
+    timestamp0_ = value;
+  }
+  void set_timestamp1(int64_t value) {
+    ASSERT(timestamp1_ == 0);
+    timestamp1_ = value;
+  }
+
   enum StateBits {
     kEventTypeBit = 0,  // reserve 4 bits for type.
     kNextBit = 4,
@@ -264,6 +263,16 @@
 
   class EventTypeField : public BitField<EventType, kEventTypeBit, 4> {};
 
+  int64_t timestamp0_;
+  int64_t timestamp1_;
+  TimelineEventArgument* arguments_;
+  intptr_t arguments_length_;
+  uword state_;
+  const char* label_;
+  const char* category_;
+  ThreadId thread_;
+  Dart_Port isolate_id_;
+
   friend class TimelineEventRecorder;
   friend class TimelineEventEndlessRecorder;
   friend class TimelineEventRingRecorder;
diff --git a/sdk/lib/_internal/js_runtime/lib/core_patch.dart b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
index 9dd31a4..dfed0df 100644
--- a/sdk/lib/_internal/js_runtime/lib/core_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/core_patch.dart
@@ -186,6 +186,18 @@
 @patch
 class DateTime {
   @patch
+  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+                                      {bool isUtc: false})
+      : this._withValue(millisecondsSinceEpoch, isUtc: isUtc);
+
+  @patch
+  DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+                                      {bool isUtc: false})
+      : this._withValue(
+          _microsecondInRoundedMilliseconds(microsecondsSinceEpoch),
+          isUtc: isUtc);
+
+  @patch
   DateTime._internal(int year,
                      int month,
                      int day,
@@ -193,26 +205,38 @@
                      int minute,
                      int second,
                      int millisecond,
+                     int microsecond,
                      bool isUtc)
         // checkBool is manually inlined here because dart2js doesn't inline it
         // and [isUtc] is usually a constant.
       : this.isUtc = isUtc is bool
             ? isUtc
             : throw new ArgumentError.value(isUtc, 'isUtc'),
-        millisecondsSinceEpoch = checkInt(Primitives.valueFromDecomposedDate(
-            year, month, day, hour, minute, second, millisecond, isUtc));
+        _value = checkInt(Primitives.valueFromDecomposedDate(
+            year, month, day, hour, minute, second,
+            millisecond + _microsecondInRoundedMilliseconds(microsecond),
+            isUtc));
 
   @patch
   DateTime._now()
       : isUtc = false,
-        millisecondsSinceEpoch = Primitives.dateNow();
+        _value = Primitives.dateNow();
+
+  /// Rounds the given [microsecond] to the nearest milliseconds value.
+  ///
+  /// For example, invoked with argument `2600` returns `3`.
+  static int _microsecondInRoundedMilliseconds(int microsecond) {
+    return (microsecond / 1000).round();
+  }
 
   @patch
-  static int _brokenDownDateToMillisecondsSinceEpoch(
+  static int _brokenDownDateToValue(
       int year, int month, int day, int hour, int minute, int second,
-      int millisecond, bool isUtc) {
+      int millisecond, int microsecond, bool isUtc) {
     return Primitives.valueFromDecomposedDate(
-        year, month, day, hour, minute, second, millisecond, isUtc);
+        year, month, day, hour, minute, second,
+        millisecond + _microsecondInRoundedMilliseconds(microsecond),
+        isUtc);
   }
 
   @patch
@@ -228,6 +252,29 @@
   }
 
   @patch
+  DateTime add(Duration duration) {
+    return new DateTime._withValue(
+        _value + duration.inMilliseconds, isUtc: isUtc);
+  }
+
+  @patch
+  DateTime subtract(Duration duration) {
+    return new DateTime._withValue(
+        _value - duration.inMilliseconds, isUtc: isUtc);
+  }
+
+  @patch
+  Duration difference(DateTime other) {
+    return new Duration(milliseconds: _value - other._value);
+  }
+
+  @patch
+  int get millisecondsSinceEpoch => _value;
+
+  @patch
+  int get microsecondsSinceEpoch => _value * 1000;
+
+  @patch
   int get year => Primitives.getYear(this);
 
   @patch
@@ -249,6 +296,9 @@
   int get millisecond => Primitives.getMilliseconds(this);
 
   @patch
+  int get microsecond => 0;
+
+  @patch
   int get weekday => Primitives.getWeekday(this);
 }
 
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index fdc1ee2..d6dd538 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -891,9 +891,9 @@
         // an identifier, we use that instead of the very generic 'Object'.
         var objectConstructor = JS('', '#.constructor', object);
         if (JS('bool', 'typeof # == "function"', objectConstructor)) {
-          var decompiledName =
-              JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)[1]',
-                  JS('var', r'String(#)', objectConstructor));
+          var match = JS('var', r'#.match(/^\s*function\s*([\w$]*)\s*\(/)',
+              JS('var', r'String(#)', objectConstructor));
+          var decompiledName = match == null ? null : JS('var', r'#[1]', match);
           if (decompiledName is String &&
               JS('bool', r'/^\w+$/.test(#)', decompiledName)) {
             name = decompiledName;
@@ -2898,10 +2898,9 @@
   bool operator==(other) {
     if (identical(this, other)) return true;
     if (other is! BoundClosure) return false;
-    return JS('bool', '# === # && # === # && # === #',
-        _self, other._self,
-        _target, other._target,
-        _receiver, other._receiver);
+    return JS('bool', '# === #', _self, other._self) &&
+           JS('bool', '# === #', _target, other._target) &&
+           JS('bool', '# === #', _receiver, other._receiver);
   }
 
   int get hashCode {
diff --git a/sdk/lib/async/future_impl.dart b/sdk/lib/async/future_impl.dart
index 35dfd119..f27b34d 100644
--- a/sdk/lib/async/future_impl.dart
+++ b/sdk/lib/async/future_impl.dart
@@ -187,20 +187,16 @@
     _asyncCompleteError(error, stackTrace);
   }
 
-  bool get _mayComplete => _state == _INCOMPLETE;
-  bool get _isChained => _state == _CHAINED;
-  bool get _isComplete => _state >= _VALUE;
-  bool get _hasValue => _state == _VALUE;
-  bool get _hasError => _state == _ERROR;
+  bool get _mayComplete       => _state == _INCOMPLETE;
+  bool get _isPendingComplete => _state == _PENDING_COMPLETE;
+  bool get _isChained         => _state == _CHAINED;
+  bool get _isComplete        => _state >= _VALUE;
+  bool get _hasValue          => _state == _VALUE;
+  bool get _hasError          => _state == _ERROR;
 
-  set _isChained(bool value) {
-    if (value) {
-      assert(!_isComplete);
-      _state = _CHAINED;
-    } else {
-      assert(_isChained);
-      _state = _INCOMPLETE;
-    }
+  void _setChained() {
+    assert(!_isComplete);
+    _state = _CHAINED;
   }
 
   Future then(f(T value), { Function onError }) {
@@ -304,14 +300,15 @@
   }
 
   // Take the value (when completed) of source and complete target with that
-  // value (or error). This function can chain all Futures, but is slower
-  // for _Future than _chainCoreFuture - Use _chainCoreFuture in that case.
+  // value (or error). This function could chain all Futures, but is slower
+  // for _Future than _chainCoreFuture, so you must use _chainCoreFuture
+  // in that case.
   static void _chainForeignFuture(Future source, _Future target) {
     assert(!target._isComplete);
     assert(source is! _Future);
 
     // Mark the target as chained (and as such half-completed).
-    target._isChained = true;
+    target._setChained();
     try {
       source.then((value) {
           assert(target._isChained);
@@ -343,7 +340,7 @@
     assert(source is _Future);
 
     // Mark the target as chained (and as such half-completed).
-    target._isChained = true;
+    target._setChained();
     _FutureListener listener = new _FutureListener.chain(target);
     if (source._isComplete) {
       _propagateToListeners(source, listener);
@@ -404,7 +401,7 @@
       Future<T> typedFuture = value;
       if (typedFuture is _Future) {
         _Future<T> coreFuture = typedFuture;
-        if (coreFuture._isComplete && coreFuture._hasError) {
+        if (coreFuture._hasError) {
           // Case 1 from above. Delay completion to enable the user to register
           // callbacks.
           _markPendingCompletion();
@@ -467,21 +464,16 @@
       }
       _FutureListener listener = listeners;
       // Do the actual propagation.
-      // Set initial state of listenerHasValue and listenerValueOrError. These
-      // variables are updated, with the outcome of potential callbacks.
-      bool listenerHasValue = true;
-      final sourceValue = hasError ? null : source._value;
-      var listenerValueOrError = sourceValue;
-      // Set to true if a whenComplete needs to wait for a future.
-      // The whenComplete action will resume the propagation by itself.
-      bool isPropagationAborted = false;
-      // TODO(floitsch): mark the listener as pending completion. Currently
-      // we can't do this, since the markPendingCompletion verifies that
-      // the future is not already marked (or chained).
+      // Set initial state of listenerHasError and listenerValueOrError. These
+      // variables are updated with the outcome of potential callbacks.
+      bool listenerHasError = hasError;
+      final sourceResult = source._resultOrListeners;
+      var listenerValueOrError = sourceResult;
+
       // Only if we either have an error or callbacks, go into this, somewhat
       // expensive, branch. Here we'll enter/leave the zone. Many futures
-      // doesn't have callbacks, so this is a significant optimization.
-      if (hasError || (listener.handlesValue || listener.handlesComplete)) {
+      // don't have callbacks, so this is a significant optimization.
+      if (hasError || listener.handlesValue || listener.handlesComplete) {
         Zone zone = listener._zone;
         if (hasError && !source._zone.inSameErrorZone(zone)) {
           // Don't cross zone boundaries with errors.
@@ -497,14 +489,15 @@
           oldZone = Zone._enter(zone);
         }
 
-        bool handleValueCallback() {
+        void handleValueCallback() {
+          assert(!hasError);
           try {
             listenerValueOrError = zone.runUnary(listener._onValue,
-                                                 sourceValue);
-            return true;
+                                                 sourceResult);
+            listenerHasError = false;
           } catch (e, s) {
             listenerValueOrError = new AsyncError(e, s);
-            return false;
+            listenerHasError = true;
           }
         }
 
@@ -516,9 +509,10 @@
             try {
               matchesTest = zone.runUnary(test, asyncError.error);
             } catch (e, s) {
-              listenerValueOrError = identical(asyncError.error, e) ?
-                  asyncError : new AsyncError(e, s);
-              listenerHasValue = false;
+              listenerValueOrError = identical(asyncError.error, e)
+                  ? asyncError
+                  : new AsyncError(e, s);
+              listenerHasError = true;
               return;
             }
           }
@@ -533,21 +527,18 @@
                 listenerValueOrError = zone.runUnary(errorCallback,
                                                      asyncError.error);
               }
+              listenerHasError = false;
             } catch (e, s) {
-              listenerValueOrError = identical(asyncError.error, e) ?
-                  asyncError : new AsyncError(e, s);
-              listenerHasValue = false;
-              return;
+              listenerValueOrError = identical(asyncError.error, e)
+                  ? asyncError
+                  : new AsyncError(e, s);
+              listenerHasError = true;
             }
-            listenerHasValue = true;
-          } else {
-            // Copy over the error from the source.
-            listenerValueOrError = asyncError;
-            listenerHasValue = false;
           }
         }
 
         void handleWhenCompleteCallback() {
+          assert(!listener.handlesError);
           var completeResult;
           try {
             completeResult = zone.run(listener._whenCompleteAction);
@@ -557,49 +548,50 @@
             } else {
               listenerValueOrError = new AsyncError(e, s);
             }
-            listenerHasValue = false;
+            listenerHasError = true;
             return;
           }
           if (completeResult is Future) {
-            _Future result = listener.result;
-            result._isChained = true;
-            isPropagationAborted = true;
-            completeResult.then((ignored) {
-              _propagateToListeners(source, new _FutureListener.chain(result));
-            }, onError: (error, [stackTrace]) {
-              // When there is an error, we have to make the error the new
-              // result of the current listener.
-              if (completeResult is! _Future) {
-                // This should be a rare case.
-                completeResult = new _Future();
-                completeResult._setError(error, stackTrace);
+            if (completeResult is _Future && completeResult._isComplete) {
+              if (completeResult._hasError) {
+                listenerValueOrError = completeResult._error;
+                listenerHasError = true;
               }
-              _propagateToListeners(completeResult,
-                                    new _FutureListener.chain(result));
-            });
+              // Otherwise use the existing result of source.
+              return;
+            }
+            // We have to wait for the completeResult future to complete
+            // before knowing if it's an error or we should use the result
+            // of source.
+            var originalSource = source;
+            listenerValueOrError = completeResult.then((_) => originalSource);
+            listenerHasError = false;
           }
         }
 
-        if (!hasError) {
+        if (listener.handlesComplete) {
+          // The whenComplete-handler is not combined with normal value/error
+          // handling. This means at most one handleX method is called per
+          // listener.
+          assert(!listener.handlesValue);
+          assert(!listener.handlesError);
+          handleWhenCompleteCallback();
+        } else if (!hasError) {
           if (listener.handlesValue) {
-            listenerHasValue = handleValueCallback();
+            handleValueCallback();
           }
         } else {
-          handleError();
+          if (listener.handlesError) {
+            handleError();
+          }
         }
-        if (listener.handlesComplete) {
-          handleWhenCompleteCallback();
-        }
+
         // If we changed zone, oldZone will not be null.
         if (oldZone != null) Zone._leave(oldZone);
 
-        if (isPropagationAborted) return;
         // If the listener's value is a future we need to chain it. Note that
-        // this can only happen if there is a callback. Since 'is' checks
-        // can be expensive, we're trying to avoid it.
-        if (listenerHasValue &&
-            !identical(sourceValue, listenerValueOrError) &&
-            listenerValueOrError is Future) {
+        // this can only happen if there is a callback.
+        if (listenerValueOrError is Future) {
           Future chainSource = listenerValueOrError;
           // Shortcut if the chain-source is already completed. Just continue
           // the loop.
@@ -607,7 +599,7 @@
           if (chainSource is _Future) {
             if (chainSource._isComplete) {
               // propagate the value (simulating a tail call).
-              result._isChained = true;
+              result._setChained();
               source = chainSource;
               listeners = new _FutureListener.chain(result);
               continue;
@@ -622,7 +614,7 @@
       }
       _Future result = listener.result;
       listeners = result._removeListeners();
-      if (listenerHasValue) {
+      if (!listenerHasError) {
         result._setValue(listenerValueOrError);
       } else {
         AsyncError asyncError = listenerValueOrError;
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index ae003e3..dff5b18 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -906,7 +906,7 @@
    * Skips data events if they are equal to the previous data event.
    *
    * The returned stream provides the same events as this stream, except
-   * that it never provides two consequtive data events that are equal.
+   * that it never provides two consecutive data events that are equal.
    *
    * Equality is determined by the provided [equals] method. If that is
    * omitted, the '==' operator on the last provided data element is used.
@@ -1459,7 +1459,7 @@
 /**
  * Abstract interface for a "sink" accepting multiple entire streams.
  *
- * A consumer can accept a number of consequtive streams using [addStream],
+ * A consumer can accept a number of consecutive streams using [addStream],
  * and when no further data need to be added, the [close] method tells the
  * consumer to complete its work and shut down.
  *
@@ -1493,7 +1493,7 @@
   Future addStream(Stream<S> stream);
 
   /**
-   * Tells the consumer that no futher streams will be added.
+   * Tells the consumer that no further streams will be added.
    *
    * This allows the consumer to complete any remaining work and release
    * resources that are no longer needed
@@ -1527,7 +1527,7 @@
  */
 abstract class StreamSink<S> implements EventSink<S>, StreamConsumer<S> {
   /**
-   * Tells the stream sink that no futher streams will be added.
+   * Tells the stream sink that no further streams will be added.
    *
    * This allows the stream sink to complete any remaining work and release
    * resources that are no longer needed
diff --git a/sdk/lib/collection/collections.dart b/sdk/lib/collection/collections.dart
index fb9a94b..5756544 100644
--- a/sdk/lib/collection/collections.dart
+++ b/sdk/lib/collection/collections.dart
@@ -12,7 +12,13 @@
  */
 class UnmodifiableListView<E> extends UnmodifiableListBase<E> {
   final Iterable<E> _source;
-  /** Create an unmodifiable list backed by [source]. */
+
+  /**
+   * Creates an unmodifiable list backed by [source].
+   *
+   * The [source] of the elements may be a [List] or any [Iterable] with
+   * efficient [Iterable.length] and [Iterable.elementAt].
+   */
   UnmodifiableListView(Iterable<E> source) : _source = source;
   int get length => _source.length;
   E operator[](int index) => _source.elementAt(index);
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index 1e89080..28ece3f 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -129,17 +129,13 @@
   static const int MONTHS_PER_YEAR = 12;
 
   /**
-   * The number of milliseconds since
-   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   * The value of this DateTime.
    *
-   * This value is independent of the time zone.
-   *
-   * This value is at most
-   * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
-   * In other words: [:millisecondsSinceEpoch.abs() <= 8640000000000000:].
-   *
+   * The content of this field is implementation dependent. On JavaScript it is
+   * equal to [millisecondsSinceEpoch]. On the VM it is equal to
+   * [microsecondsSinceEpoch].
    */
-  final int millisecondsSinceEpoch;
+  final int _value;
 
   /**
    * True if this [DateTime] is set to UTC time.
@@ -164,9 +160,11 @@
             int hour = 0,
             int minute = 0,
             int second = 0,
-            int millisecond = 0])
+            int millisecond = 0,
+            int microsecond = 0])
       : this._internal(
-            year, month, day, hour, minute, second, millisecond, false);
+            year, month, day, hour, minute, second, millisecond, microsecond,
+            false);
 
   /**
    * Constructs a [DateTime] instance specified in the UTC time zone.
@@ -179,9 +177,11 @@
                 int hour = 0,
                 int minute = 0,
                 int second = 0,
-                int millisecond = 0])
+                int millisecond = 0,
+                int microsecond = 0])
     : this._internal(
-          year, month, day, hour, minute, second, millisecond, true);
+          year, month, day, hour, minute, second, millisecond, microsecond,
+          true);
 
   /**
    * Constructs a [DateTime] instance with current date and time in the
@@ -256,7 +256,7 @@
      * time_opt ::= <empty> | (' ' | 'T') hour minutes_opt
      * minutes_opt ::= <empty> | colon_opt digit{2} seconds_opt
      * seconds_opt ::= <empty> | colon_opt digit{2} millis_opt
-     * millis_opt ::= <empty> | '.' digit{1,6}
+     * micros_opt ::= <empty> | '.' digit{1,6}
      * timezone_opt ::= <empty> | space_opt timezone
      * space_opt :: ' ' | <empty>
      * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
@@ -274,35 +274,20 @@
         return int.parse(matched);
       }
 
-      // Parses fractional second digits of '.(\d{1,6})' into milliseconds.
-      // Uses first three digits (assumed to be zero if not there), and
-      // rounds up if fourth digit is 5 or greater.
-      // Should be equivalent to `(double.parse(".$matchd")*1000).round()`.
-      int parseMilliseconds(String matched) {
+      // Parses fractional second digits of '.(\d{1,6})' into the combined
+      // microseconds.
+      int parseMilliAndMicroseconds(String matched) {
         if (matched == null) return 0;
         int length = matched.length;
         assert(length >= 1);
         assert(length <= 6);
 
-        int result = (matched.codeUnitAt(0) ^ 0x30);
-        if (length <= 3) {
-          int i = 1;
-          while (i < length) {
-            result *= 10;
+        int result = 0;
+        for (int i = 0; i < 6; i++) {
+          result *= 10;
+          if (i < matched.length) {
             result += matched.codeUnitAt(i) ^ 0x30;
-            i++;
           }
-          while (i < 3) {
-            result *= 10;
-            i++;
-          }
-          return result;
-        }
-        // Parse the prefix from 0..3 without creating a new substring.
-        result = result * 10 + (matched.codeUnitAt(1) ^ 0x30);
-        result = result * 10 + (matched.codeUnitAt(2) ^ 0x30);
-        if (matched.codeUnitAt(3) >= 0x35) {
-          result += 1;
         }
         return result;
       }
@@ -314,11 +299,11 @@
       int minute = parseIntOrZero(match[5]);
       int second = parseIntOrZero(match[6]);
       bool addOneMillisecond = false;
-      int millisecond = parseMilliseconds(match[7]);
-      if (millisecond == 1000) {
-        addOneMillisecond = true;
-        millisecond = 999;
-      }
+      int milliAndMicroseconds = parseMilliAndMicroseconds(match[7]);
+      int millisecond =
+          milliAndMicroseconds ~/ Duration.MICROSECONDS_PER_MILLISECOND;
+      int microsecond =
+          milliAndMicroseconds.remainder(Duration.MICROSECONDS_PER_MILLISECOND);
       bool isUtc = false;
       if (match[8] != null) {  // timezone part
         isUtc = true;
@@ -331,14 +316,13 @@
           minute -= sign * minuteDifference;
         }
       }
-      int millisecondsSinceEpoch = _brokenDownDateToMillisecondsSinceEpoch(
-          years, month, day, hour, minute, second, millisecond, isUtc);
-      if (millisecondsSinceEpoch == null) {
+      int value = _brokenDownDateToValue(
+          years, month, day, hour, minute, second, millisecond, microsecond,
+          isUtc);
+      if (value == null) {
         throw new FormatException("Time out of range", formattedString);
       }
-      if (addOneMillisecond) millisecondsSinceEpoch++;
-      return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
-                                                     isUtc: isUtc);
+      return new DateTime._withValue(value, isUtc: isUtc);
     } else {
       throw new FormatException("Invalid date format", formattedString);
     }
@@ -356,11 +340,31 @@
    * 1970-01-01T00:00:00Z + [millisecondsSinceEpoch] ms in the given
    * time zone (local or UTC).
    */
-  DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
-                                      {bool isUtc: false})
-      : this.millisecondsSinceEpoch = millisecondsSinceEpoch,
-        this.isUtc = isUtc {
-    if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH) {
+  external DateTime.fromMillisecondsSinceEpoch(int millisecondsSinceEpoch,
+                                              {bool isUtc: false});
+
+  /**
+   * Constructs a new [DateTime] instance
+   * with the given [microsecondsSinceEpoch].
+   *
+   * If [isUtc] is false then the date is in the local time zone.
+   *
+   * The constructed [DateTime] represents
+   * 1970-01-01T00:00:00Z + [microsecondsSinceEpoch] us in the given
+   * time zone (local or UTC).
+   */
+  external DateTime.fromMicrosecondsSinceEpoch(int microsecondsSinceEpoch,
+                                               {bool isUtc: false});
+
+  /**
+   * Constructs a new [DateTime] instance with the given value.
+   *
+   * If [isUtc] is false then the date is in the local time zone.
+   */
+  DateTime._withValue(this._value, {this.isUtc}) {
+    if (millisecondsSinceEpoch.abs() > _MAX_MILLISECONDS_SINCE_EPOCH ||
+        (millisecondsSinceEpoch.abs() == _MAX_MILLISECONDS_SINCE_EPOCH &&
+         microsecond != 0)) {
       throw new ArgumentError(millisecondsSinceEpoch);
     }
     if (isUtc == null) throw new ArgumentError(isUtc);
@@ -379,8 +383,7 @@
    */
   bool operator ==(other) {
     if (!(other is DateTime)) return false;
-    return (millisecondsSinceEpoch == other.millisecondsSinceEpoch &&
-            isUtc == other.isUtc);
+    return (_value == other._value && isUtc == other.isUtc);
   }
 
   /**
@@ -396,7 +399,7 @@
    *
    */
   bool isBefore(DateTime other) {
-    return millisecondsSinceEpoch < other.millisecondsSinceEpoch;
+    return _value < other._value;
   }
 
   /**
@@ -412,7 +415,7 @@
    *
    */
   bool isAfter(DateTime other) {
-    return millisecondsSinceEpoch > other.millisecondsSinceEpoch;
+    return _value > other._value;
   }
 
   /**
@@ -427,7 +430,7 @@
    *     assert(berlinWallFell.isAtSameMomentAs(moonLanding) == false);
    */
   bool isAtSameMomentAs(DateTime other) {
-    return millisecondsSinceEpoch == other.millisecondsSinceEpoch;
+    return _value == other._value;
   }
 
   /**
@@ -438,10 +441,9 @@
    * if this DateTime is smaller (earlier) than [other],
    * or a positive integer if it is greater (later).
    */
-  int compareTo(DateTime other)
-      => millisecondsSinceEpoch.compareTo(other.millisecondsSinceEpoch);
+  int compareTo(DateTime other) => _value.compareTo(other._value);
 
-  int get hashCode => millisecondsSinceEpoch;
+  int get hashCode => (_value ^ (_value >> 30)) & 0x3FFFFFFF;
 
   /**
    * Returns this DateTime value in the local time zone.
@@ -449,13 +451,12 @@
    * Returns [this] if it is already in the local time zone.
    * Otherwise this method is equivalent to:
    *
-   *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
+   *     new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
    *                                             isUtc: false)
    */
   DateTime toLocal() {
     if (isUtc) {
-      return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
-                                                     isUtc: false);
+      return new DateTime._withValue(_value, isUtc: false);
     }
     return this;
   }
@@ -466,13 +467,12 @@
    * Returns [this] if it is already in UTC.
    * Otherwise this method is equivalent to:
    *
-   *     new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
+   *     new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch,
    *                                             isUtc: true)
    */
   DateTime toUtc() {
     if (isUtc) return this;
-    return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
-                                                   isUtc: true);
+    return new DateTime._withValue(_value, isUtc: true);
   }
 
   static String _fourDigits(int n) {
@@ -522,18 +522,19 @@
     String min = _twoDigits(minute);
     String sec = _twoDigits(second);
     String ms = _threeDigits(millisecond);
+    String us = microsecond == 0 ? "" : _threeDigits(microsecond);
     if (isUtc) {
-      return "$y-$m-$d $h:$min:$sec.${ms}Z";
+      return "$y-$m-$d $h:$min:$sec.$ms${us}Z";
     } else {
-      return "$y-$m-$d $h:$min:$sec.$ms";
+      return "$y-$m-$d $h:$min:$sec.$ms$us";
     }
   }
 
   /**
    * Returns an ISO-8601 full-precision extended format representation.
    *
-   * The format is `yyyy-MM-ddTHH:mm:ss.sssZ` for UTC time, and
-   * `yyyy-MM-ddTHH:mm:ss.sss` (no trailing "Z") for local/non-UTC time,
+   * The format is `yyyy-MM-ddTHH:mm:ss.mmmuuuZ` for UTC time, and
+   * `yyyy-MM-ddTHH:mm:ss.mmmuuu` (no trailing "Z") for local/non-UTC time,
    * where:
    *
    * * `yyyy` is a, possibly negative, four digit representation of the year,
@@ -543,8 +544,10 @@
    * * `dd` is the day of the month in the range 01 to 31,
    * * `HH` are hours in the range 00 to 23,
    * * `mm` are minutes in the range 00 to 59,
-   * * `ss` are seconds in the range 00 to 59 (no leap seconds), and
-   * * `sss` are milliseconds in the range 000 to 999.
+   * * `ss` are seconds in the range 00 to 59 (no leap seconds),
+   * * `mmm` are microseconds in the range 000 to 999, and
+   * * `uuu` are microseconds in the range 001 to 999. If [microsecond] equals
+   *   0, then this part is omitted.
    *
    * The resulting string can be parsed back using [parse].
    */
@@ -557,10 +560,11 @@
     String min = _twoDigits(minute);
     String sec = _twoDigits(second);
     String ms = _threeDigits(millisecond);
+    String us = microsecond == 0 ? "" : _threeDigits(microsecond);
     if (isUtc) {
-      return "$y-$m-${d}T$h:$min:$sec.${ms}Z";
+      return "$y-$m-${d}T$h:$min:$sec.$ms${us}Z";
     } else {
-      return "$y-$m-${d}T$h:$min:$sec.$ms";
+      return "$y-$m-${d}T$h:$min:$sec.$ms$us";
     }
   }
 
@@ -570,39 +574,49 @@
    *     DateTime today = new DateTime.now();
    *     DateTime sixtyDaysFromNow = today.add(new Duration(days: 60));
    */
-  DateTime add(Duration duration) {
-    int ms = millisecondsSinceEpoch;
-    return new DateTime.fromMillisecondsSinceEpoch(
-        ms + duration.inMilliseconds, isUtc: isUtc);
-  }
+  external DateTime add(Duration duration);
 
   /**
    * Returns a new [DateTime] instance with [duration] subtracted from [this].
    *
    *     DateTime today = new DateTime.now();
-   *     DateTime sixtyDaysAgo = today.subtract(new Duration(days: 60));
+   *     DateTime sixtyDaysAgo = today.subtract(new Duration(days: 30));
+   *
+   * Notice that duration being subtracted is actually 30 * 24 * 60 * 60 seconds
+   * and if that crosses a daylight saving time change, the resulting `DateTime`
+   * won't have the same time of day as `today`, and may not actually hit the
+   * calendar date 30 days earlier. Be careful when working with dates in local
+   * time.
    */
-  DateTime subtract(Duration duration) {
-    int ms = millisecondsSinceEpoch;
-    return new DateTime.fromMillisecondsSinceEpoch(
-        ms - duration.inMilliseconds, isUtc: isUtc);
-  }
+  external DateTime subtract(Duration duration);
 
   /**
    * Returns a [Duration] with the difference between [this] and [other].
    *
-   *     DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
-   *     DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
+   *     DateTime berlinWallFell = new DateTime.utc(1989, DateTime.NOVEMBER, 9);
+   *     DateTime dDay = new DateTime.utc(1944, DateTime.JUNE, 6);
    *
    *     Duration difference = berlinWallFell.difference(dDay);
    *     assert(difference.inDays == 16592);
+   *
+   * The difference is measured in seconds and fractions of seconds.
+   * The difference above counts the number of fractional seconds between
+   * midnight at the beginning of those dates.
+   * If the dates above had been in local time, not UTC, then the difference
+   * between two midnights may not be a multiple of 24 hours due to daylight
+   * saving differences.
+   *
+   * For example, in Australia, similar code using local time instead of UTC:
+   *
+   *     DateTime berlinWallFell = new DateTime(1989, DateTime.NOVEMBER, 9);
+   *     DateTime dDay = new DateTime(1944, DateTime.JUNE, 6);
+   *     Duration difference = berlinWallFell.difference(dDay);
+   *     assert(difference.inDays == 16592);
+   *
+   * will fail because the difference is actually 16591 days and 23 hours, and
+   * [Duration.inDays] only returns the number of whole days.
    */
-
-  Duration difference(DateTime other) {
-    int ms = millisecondsSinceEpoch;
-    int otherMs = other.millisecondsSinceEpoch;
-    return new Duration(milliseconds: ms - otherMs);
-  }
+  external Duration difference(DateTime other);
 
   external DateTime._internal(int year,
                               int month,
@@ -611,13 +625,43 @@
                               int minute,
                               int second,
                               int millisecond,
+                              int microsecond,
                               bool isUtc);
+
   external DateTime._now();
-  /// Returns the time as milliseconds since epoch, or null if the
-  /// values are out of range.
-  external static int _brokenDownDateToMillisecondsSinceEpoch(
+
+  /// Returns the time as value (millisecond or microsecond since epoch), or
+  /// null if the values are out of range.
+  external static int _brokenDownDateToValue(
       int year, int month, int day, int hour, int minute, int second,
-      int millisecond, bool isUtc);
+      int millisecond, int microsecond, bool isUtc);
+
+  /**
+   * The number of milliseconds since
+   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   *
+   * This value is independent of the time zone.
+   *
+   * This value is at most
+   * 8,640,000,000,000,000ms (100,000,000 days) from the Unix epoch.
+   * In other words: `millisecondsSinceEpoch.abs() <= 8640000000000000`.
+   */
+  external int get millisecondsSinceEpoch;
+
+  /**
+   * The number of microseconds since
+   * the "Unix epoch" 1970-01-01T00:00:00Z (UTC).
+   *
+   * This value is independent of the time zone.
+   *
+   * This value is at most
+   * 8,640,000,000,000,000,000us (100,000,000 days) from the Unix epoch.
+   * In other words: `microsecondsSinceEpoch.abs() <= 8640000000000000000`.
+   *
+   * Note that this value does not fit into 53 bits (the size of a IEEE double).
+   * A JavaScript number is not able to hold this value.
+   */
+  external int get microsecondsSinceEpoch;
 
   /**
    * The abbreviated time zone name&mdash;for example,
@@ -695,6 +739,14 @@
   external int get millisecond;
 
   /**
+   * The microsecond [0...999].
+   *
+   *     DateTime moonLanding = DateTime.parse("1969-07-20 20:18:00");
+   *     assert(moonLanding.microsecond == 0);
+   */
+  external int get microsecond;
+
+  /**
    * The day of the week [MONDAY]..[SUNDAY].
    *
    * In accordance with ISO 8601
diff --git a/sdk/lib/core/int.dart b/sdk/lib/core/int.dart
index 98f7da8..fdc7727 100644
--- a/sdk/lib/core/int.dart
+++ b/sdk/lib/core/int.dart
@@ -170,7 +170,7 @@
    * non-negative number (i.e. unsigned representation).  The returned value has
    * zeros in all bit positions higher than [width].
    *
-   *     (-1).toUnsigned(5) == 32   // 11111111  ->  00011111
+   *     (-1).toUnsigned(5) == 31   // 11111111  ->  00011111
    *
    * This operation can be used to simulate arithmetic from low level languages.
    * For example, to increment an 8 bit quantity:
diff --git a/sdk/lib/core/list.dart b/sdk/lib/core/list.dart
index 7f4ab18..9d25927 100644
--- a/sdk/lib/core/list.dart
+++ b/sdk/lib/core/list.dart
@@ -192,17 +192,26 @@
    *
    * The [compare] function must act as a [Comparator].
    *
-   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     List<String> numbers = ['two', 'three', 'four'];
    *     // Sort from shortest to longest.
-   *     numbers.sort((x, y) => x.length.compareTo(y.length));
-   *     numbers.join(', '); // 'one, two, four, three'
+   *     numbers.sort((a, b) => a.length.compareTo(b.length));
+   *     print(numbers);  // [two, four, three]
    *
    * The default List implementations use [Comparable.compare] if
    * [compare] is omitted.
    *
    *     List<int> nums = [13, 2, -11];
    *     nums.sort();
-   *     nums.join(', '); // '-11, 2, 13'
+   *     print(nums);  // [-11, 2, 13]
+   *
+   * A [Comparator] may compare objects as equal (return zero), even if they
+   * are distinct objects.
+   * The sort function is not guaranteed to be stable, so distinct objects
+   * that compare as equal may occur in any order in the result:
+   *
+   *     List<String> numbers = ['one', 'two', 'three', 'four'];
+   *     numbers.sort((a, b) => a.length.compareTo(b.length));
+   *     print(numbers);  // [one, two, four, three] OR [two, one, four, three]
    */
   void sort([int compare(E a, E b)]);
 
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 56ccac3..f17ea2f 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -104,8 +104,6 @@
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t01: CompileTimeError # Please triage this failure
 Language/Interfaces/Superinterfaces/Inheritance_and_Overriding/same_name_method_and_getter_t02: CompileTimeError # Please triage this failure
 Language/Libraries_and_Scripts/Imports/namespace_changes_t10: CompileTimeError # Please triage this failure
-Language/Libraries_and_Scripts/Imports/same_name_t08: fail # Issue 21171
-Language/Libraries_and_Scripts/Imports/same_name_t18: fail # Issue 21171
 Language/Libraries_and_Scripts/URIs/syntax_t04: CompileTimeError # Please triage this failure
 Language/Libraries_and_Scripts/URIs/syntax_t05: CompileTimeError # Please triage this failure
 Language/Libraries_and_Scripts/URIs/syntax_t09: CompileTimeError # Please triage this failure
@@ -119,7 +117,6 @@
 Language/Metadata/before_type_param_t01: CompileTimeError # Please triage this failure
 Language/Metadata/before_typedef_t01: RuntimeError # Please triage this failure
 Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure
-Language/Metadata/compilation_t10: MissingCompileTimeError # Please triage this failure
 Language/Mixins/Mixin_Application/error_t01: MissingCompileTimeError # Please triage this failure
 Language/Mixins/Mixin_Application/error_t02: MissingCompileTimeError # Please triage this failure
 Language/Mixins/Mixin_Application/wrong_mixin_type_t01: MissingCompileTimeError # Please triage this failure
@@ -631,6 +628,7 @@
 LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/backgrounds/multiple-backgrounds-computed-style_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/borders/border-width-percent_t01: RuntimeError # Issue 25155
 LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # Please triage this failure
@@ -750,6 +748,7 @@
 LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/background-serialize_t01: RuntimeError # https://github.com/dart-lang/co19/issues/14
+LayoutTests/fast/css/css-selector-text_t01: RuntimeError # co19 Issue 15
 LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # Please triage this failure
@@ -842,6 +841,7 @@
 LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/DOMException/XPathException_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # Please triage this failure
@@ -879,8 +879,10 @@
 LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # Issue 18010
 LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLObjectElement/form/test1_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # Please triage this failure
@@ -934,6 +936,7 @@
 LayoutTests/fast/dom/fragment-activation-focuses-target_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/getElementsByClassName/011_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/getElementsByClassName/dumpNodeList_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/getelementsbyname-invalidation-cache_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
@@ -941,6 +944,7 @@
 LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
 LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
 LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: Skip # API not supported.
+LayoutTests/fast/dom/object-plugin-hides-properties_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/option-properties_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
@@ -954,6 +958,7 @@
 LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadow-disable_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/dom/shadow/shadow-element-inactive_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: Pass, RuntimeError # Please triage this failure
@@ -963,6 +968,7 @@
 LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dynamic/crash-generated-text_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dynamic/insertAdjacentElement_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dynamic/insertAdjacentHTML-allowed-parents_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/encoding/css-charset-dom_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # Please triage this failure
@@ -1010,13 +1016,16 @@
 LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/button/button-disabled-blur_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/checkValidity-001_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/clone-input-with-dirty-value_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/date/input-valueasdate-date_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/datetimelocal/input-valueasdate-datetimelocal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/fieldset/fieldset-elements_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/form-attribute_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Please triage this failure
@@ -1036,11 +1045,14 @@
 LayoutTests/fast/forms/select-clientheight-with-multiple-attr_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/forms/select-max-length_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/setCustomValidity-existence_t01: RuntimeError # Issue 25155
 LayoutTests/fast/forms/setrangetext_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/submit-form-attributes_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/forms/textarea-paste-newline_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/forms/validationMessage_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/validity-property_t01: RuntimeError # Issue 25155
+LayoutTests/fast/forms/willvalidate_t01: RuntimeError # Issue 25155
 LayoutTests/fast/html/hidden-attr_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/html/imports/import-events_t01: RuntimeError # Please triage this failure
@@ -1063,6 +1075,7 @@
 LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/masking/parsing-clip-path-iri_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/masking/parsing-mask_t01: RuntimeError # Please triage this failure
@@ -1104,6 +1117,7 @@
 LayoutTests/fast/replaced/table-percent-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/ruby/ruby-line-height_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/parsing/parsing-shape-lengths_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-big-box-border-radius_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-diamond-margin-polygon_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-ellipse-margin-left_t01: RuntimeError # Please triage this failure
@@ -1236,6 +1250,7 @@
 LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # Issue 16395
 LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Please triage this failure
+LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Issue 25155
 LibTest/html/Element/marginEdge_A01_t01: RuntimeError # Issue 16574
 LibTest/html/Element/mouseWheelEvent_A01_t01: Skip # Times out. Please triage this failure
 LibTest/html/Element/onMouseWheel_A01_t01: Skip # Times out. Please triage this failure
@@ -1243,6 +1258,7 @@
 LibTest/html/Element/paddingEdge_A01_t01: RuntimeError # Issue 16574
 LibTest/html/Element/querySelectorAll_A01_t02: RuntimeError # Please triage this failure
 LibTest/html/Element/replaceWith_A01_t02: RuntimeError # Please triage this failure
+LibTest/html/Element/tagName_A01_t01: RuntimeError # Issue 25155
 LibTest/html/Element/transitionEndEvent_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/getAllResponseHeaders_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/HttpRequest/getResponseHeader_A01_t01: RuntimeError # Please triage this failure
@@ -1313,6 +1329,12 @@
 WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: RuntimeError # Issue 25155
 WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # Please triage this failure
 WebPlatformTest/dom/EventTarget/dispatchEvent_A03_t01: Skip # Times out. Please triage this failure
 WebPlatformTest/dom/events/type_A01_t01: RuntimeError # Please triage this failure
@@ -1360,7 +1382,6 @@
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out. Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # Please triage this failure
@@ -1453,6 +1474,8 @@
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: RuntimeError # Issue 25155
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: RuntimeError # Issue 25155
 WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
 
@@ -1625,25 +1648,6 @@
 LayoutTests/fast/text/regional-indicator-symobls_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
 
-[ $compiler == dart2js && $runtime == chrome && $system == windows ]
-LayoutTests/fast/canvas/canvas-blending-color-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-color-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-fill-style_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-global-alpha_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-gradient-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-image-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-color_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-gradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-pattern-over-pattern_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-blending-transforms_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: RuntimeError # Please triage this failure
-
 [ $compiler == dart2js && $runtime == chrome && $system != linux ]
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Issue 24398
 
@@ -3167,6 +3171,9 @@
 LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
 
+[ $compiler == dart2js && $runtime == ff && $system == linux]
+LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # co19 issue 16
+
 [ $compiler == dart2js && $runtime == safari ]
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
@@ -9615,10 +9622,6 @@
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
 [ $compiler == dart2js && $cps_ir ]
-Language/Expressions/Instance_Creation/New/evaluation_t12: RuntimeError # Please triage this failure.
-Language/Expressions/Method_Invocation/Super_Invocation/syntax_t01: RuntimeError # Cannot read property 'call' of undefined
-Language/Expressions/Identifier_Reference/evaluation_variable_or_parameter_t03.dart: Crash # (i=0): For-loop variable captured in loop header
-Language/Statements/For/syntax_t07: Crash # unsupported operation on erroneous element
 Language/Statements/Labels/scope_t04: Crash # (switch (i){L:case 0:flag=true;break;case 2:continue L;}): continue to a labeled switch case
 Language/Statements/Continue/label_t12: Crash # (switch (2){L:case 1:flag=true;break;case 2:continue L;}): continue to a labeled switch case
 Language/Statements/Continue/label_t13: Crash # (switch (2){case 2:continue L;L:case 1:flag=true;}): continue to a labeled switch case
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index b9f872a..c5bfba7 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -23,6 +23,7 @@
 
 
 LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
+LibTest/core/DateTime/parse_A01_t02: Fail # co19 issue 17.
 
 LibTest/core/DateTime/DateTime.now_A01_t02: Pass, Fail # co19 issue 709
 
diff --git a/tests/compiler/dart2js/async_await_syntax_test.dart b/tests/compiler/dart2js/async_await_syntax_test.dart
index fd21a0d..af4ae5a 100644
--- a/tests/compiler/dart2js/async_await_syntax_test.dart
+++ b/tests/compiler/dart2js/async_await_syntax_test.dart
@@ -14,9 +14,9 @@
 /// includes the multitest in 'language/async_await_syntax_test.dart' but
 /// expects the subtests 'a03b' and 'a04c' to fail.
 const Map<String, List<String>> TESTS = const <String, List<String>>{
-  'language/async_await_syntax_test.dart': const ['a05h', 'c11a', 'c11b'],
+  'language/async_await_syntax_test.dart': const [],
 };
 
 void main(List<String> arguments) {
-  check(TESTS, arguments: arguments, options: ['--enable-async']);
+  check(TESTS, arguments: arguments, options: []);
 }
diff --git a/tests/compiler/dart2js/js_safety_test.dart b/tests/compiler/dart2js/js_safety_test.dart
new file mode 100644
index 0000000..140f4b6
--- /dev/null
+++ b/tests/compiler/dart2js/js_safety_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:compiler/src/js/js.dart' as js;
+import 'package:compiler/src/js/placeholder_safety.dart';
+
+void test(String source, int expected, {List notNull: const[]}) {
+  var predicate = (int pos) => ! notNull.contains(pos);
+  js.Template template = js.js.parseForeignJS(source);
+  int actual = PlaceholderSafetyAnalysis.analyze(template.ast, predicate);
+  Expect.equals(expected, actual, 'source: "$source", notNull: $notNull');
+}
+
+
+void main() {
+  test('0', 0);
+
+  test('#.x', 1);
+  test('!!#.x', 1);
+  test('#.x + 1', 1);
+  test('1 + #.x', 1);
+  test('#[#] + 2', 2);
+  test('2 + #[#]', 2);
+  test('(# & #) >>> 0', 2);
+
+  test('#.a + #.b + #.c', 1);
+  test('#.b + #.b + #.c', 2, notNull: [0]);
+  test('#.c + #.b + #.c', 3, notNull: [0, 1]);
+  test('#.d + #.b + #.c', 1, notNull: [1]);
+
+  test('typeof(#) == "string"', 1);
+  test('"object" === typeof #', 1);
+
+  test('# == 1 || # == 2 || # == 3', 1);
+  test('# != 1 && # != 2 && # != 3', 1);
+
+  test('#.x == 1 || # == 1', 1);
+  test('# == 1 || #.x == 1', 1);
+
+  test('(# || 1, #)', 1);  // Could also be 2.
+
+  test('(#, null.a, #)', 1);
+  test('(#, undefined.a, #)', 1);
+  test('(#, (void 0).a, #)', 1);
+  test('(#, "a".a, #)', 2);
+  test('((#, "a").a, #)', 2);
+
+  test('#[#][#][#][#]', 2);
+  test('#[#][#][#][#]', 3, notNull: [0]);
+  test('#[#][#][#][#]', 3, notNull: [0, 1, 2, 3]);
+
+  test('#.a = #', 2);
+  test('#.a.b = #', 1);
+  test('#[1] = #', 2);
+  test('#[1][1] = #', 1);
+
+  test('#.a = #.a + #.a + #.a', 2);
+  test('#.a = #.a + #.a + #.a', 2, notNull: [0]);
+  test('#.a = #.a + #.a + #.a', 3, notNull: [1]);
+  test('#.a = #.a + #.a + #.a', 4, notNull: [1, 2]);
+
+  test('#()', 1);
+  test('#(#, #)', 3);
+  test('#.f(#, #)', 1);
+  test('#.f(#, #)', 3, notNull: [0]);
+
+  test('(#.a+=1, #)', 1);
+  test('(#.a++, #)', 1);
+  test('(++#.a, #)', 1);
+
+  test('new Array(#)', 1);
+  test('new Date(#)', 1);
+  test('new Function(#)', 1);
+  test('new RegExp(#)', 1);
+  test('new xxx(#)', 0);
+  test('String(#)', 1);
+  test('# in #', 2);
+
+  test('Object.keys(#)', 1);
+
+  test('typeof #', 1);
+  test('typeof #.foo', 1);
+  test('typeof foo.#', 0);
+  test('typeof Array.#', 1);
+
+  test('throw #', 1);
+  test('throw #.x', 1);
+
+  test('(function(){})()', 0);
+  test('(function(a,b){#})(#, #)', 0);
+  // Placeholders in an immediate call are ok.
+  test('(function(a,b){a++;b++;return a+b})(#, #)', 2);
+
+  test('# ? # : #', 1);
+  test('(# ? 1 : #, #)', 1);
+  test('(# ? # : 2, #)', 1);
+  test('(# ? 1 : 2, #)', 1);  // Could also be 4.
+
+  test('{A:#, B:#, C:#}', 3);
+  test('[#,#,#,#]', 4);
+  test('[,,,,#,#,,,]', 2);
+}
diff --git a/tests/compiler/dart2js/mirrors_helper.dart b/tests/compiler/dart2js/mirrors_helper.dart
index 30910d5..7ffae11 100644
--- a/tests/compiler/dart2js/mirrors_helper.dart
+++ b/tests/compiler/dart2js/mirrors_helper.dart
@@ -15,10 +15,9 @@
 }
 
 /// Singleline doc comment.
-@Metadata // This is intentionally the type literal.
+@Metadata(null)
 // Singleline comment 1.
 // Singleline comment 2.
-@Metadata(null)
 @Metadata(true)
 @Metadata(false)
 @Metadata(0)
diff --git a/tests/compiler/dart2js/mirrors_test.dart b/tests/compiler/dart2js/mirrors_test.dart
index 7d3c48c..ef815e9 100644
--- a/tests/compiler/dart2js/mirrors_test.dart
+++ b/tests/compiler/dart2js/mirrors_test.dart
@@ -169,7 +169,7 @@
 
   var metadataList = fooClass.metadata;
   Expect.isNotNull(metadataList);
-  Expect.equals(16, metadataList.length);
+  Expect.equals(14, metadataList.length);
   var metadataListIndex = 0;
   var metadata;
 
@@ -192,28 +192,17 @@
   Expect.stringEquals(
       "Singleline doc comment.", metadata.trimmedText);
 
-  // @Metadata
+  // @Metadata(null)
   metadata = metadataList[metadataListIndex++];
+  var metadataType = metadata.type;
   Expect.isTrue(metadata is InstanceMirror);
   Expect.isFalse(metadata.hasReflectee);
   Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is TypeInstanceMirror);
-  var metadataType = metadata.representedType;
-  Expect.isNotNull(metadataType);
-  Expect.equals(#Metadata, metadataType.simpleName);
-
-  // // This is intentionally the type literal.
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is CommentInstanceMirror);
-  Expect.equals(commentType.originalDeclaration, metadata.type);
-  Expect.isFalse(metadata.isDocComment);
-  Expect.stringEquals(
-      "// This is intentionally the type literal.", metadata.text);
-  Expect.stringEquals(
-      "This is intentionally the type literal.", metadata.trimmedText);
+  Expect.isTrue(metadataType.isOriginalDeclaration);
+  InstanceMirror data = metadata.getField(#data);
+  Expect.isNotNull(data);
+  Expect.isTrue(data.hasReflectee);
+  Expect.isNull(data.reflectee);
 
   // Singleline comment 1.
   metadata = metadataList[metadataListIndex++];
@@ -241,17 +230,6 @@
   Expect.stringEquals(
       "Singleline comment 2.", metadata.trimmedText);
 
-  // @Metadata(null)
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  InstanceMirror data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.isNull(data.reflectee);
-
   // @Metadata(true)
   metadata = metadataList[metadataListIndex++];
   Expect.isTrue(metadata is InstanceMirror);
@@ -398,7 +376,7 @@
   // leading comment.
   Expect.equals(376, fooClassLocation.offset, "Unexpected offset");
   // Expect the location to end with the class body.
-  Expect.equals(351, fooClassLocation.length, "Unexpected length");
+  Expect.equals(298, fooClassLocation.length, "Unexpected length");
   Expect.equals(18, fooClassLocation.line, "Unexpected line");
   Expect.equals(1, fooClassLocation.column, "Unexpected column");
 
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index eeba1f9..202e6f2 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -102,7 +102,7 @@
   NodeListener listener = new NodeListener(
       new ScannerOptions(canUseNative: true),
       reporter, library.entryCompilationUnit);
-  Parser parser = new Parser(listener);
+  Parser parser = new Parser(listener, enableConditionalDirectives: true);
   Token endToken = parseMethod(parser, tokens);
   assert(endToken.kind == EOF_TOKEN);
   Node node = listener.popNode();
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index d0e7db5..9406ea9 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -2600,8 +2600,7 @@
   NodeListener listener = new NodeListener(
       const ScannerOptions(), compiler.reporter, null);
   Parser parser = new Parser(listener,
-      yieldIsKeyword: element.asyncMarker.isYielding,
-      awaitIsKeyword: element.asyncMarker.isAsync);
+      asyncAwaitKeywordsEnabled: element.asyncMarker != AsyncMarker.SYNC);
   parser.parseStatement(tokens);
   Node node = listener.popNode();
   TreeElements elements = compiler.resolveNodeStatement(node, element);
diff --git a/tests/compiler/dart2js/unparser_test.dart b/tests/compiler/dart2js/unparser_test.dart
index 4b9a815..e19ed0d 100644
--- a/tests/compiler/dart2js/unparser_test.dart
+++ b/tests/compiler/dart2js/unparser_test.dart
@@ -98,6 +98,57 @@
   testUnparseTopLevelWithMetadata('export "søhest";');
 }
 
+testConditionalImport() {
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(some.dotted.id)"other";');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(id=="some str")"other";');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2";');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(some.dotted.id)"other" as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(id=="some str")"other" as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(some.dotted.id)"other" deferred as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest" if(id=="some str")"other" deferred as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' deferred as fiskehest;');
+  testUnparseTopLevelWithMetadata(
+      'import "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' deferred as fiskehest'
+      ' show foo,bar;');
+}
+
+testConditionalExport() {
+  testUnparseTopLevelWithMetadata(
+      'export "søhest" if(some.dotted.id)"other";');
+  testUnparseTopLevelWithMetadata(
+      'export "søhest" if(id=="some str")"other";');
+  testUnparseTopLevelWithMetadata(
+      'export "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2";');
+  testUnparseTopLevelWithMetadata(
+      'export "søhest"'
+      ' if(id=="some str")"other"'
+      ' if(id)"other2"'
+      ' show foo,bar;');
+}
+
 testPart() {
   testUnparseTopLevelWithMetadata('part "søhest";');
 }
@@ -383,6 +434,8 @@
   testLibraryName();
   testImport();
   testExport();
+  testConditionalImport();
+  testConditionalExport();
   testPart();
   testPartOf();
   testCombinators();
diff --git a/tests/compiler/dart2js_extra/23828_test.dart b/tests/compiler/dart2js_extra/23828_test.dart
index b6312a3..53c2221 100644
--- a/tests/compiler/dart2js_extra/23828_test.dart
+++ b/tests/compiler/dart2js_extra/23828_test.dart
@@ -6,7 +6,9 @@
 // Used to fail when methods contain a name starting with `get`
 import 'package:expect/expect.dart';
 
-confuse(x) { return x; return x; }
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 class MA {
   noSuchMethod(i) => Expect.equals(i.positionalArguments.length, 1);
diff --git a/tests/compiler/dart2js_extra/consistent_add_error_test.dart b/tests/compiler/dart2js_extra/consistent_add_error_test.dart
new file mode 100644
index 0000000..22927e2
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_add_error_test.dart
@@ -0,0 +1,187 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that optimized '+' and slow path '+' produce the same error.
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+  if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntPlusNull {
+  static f1() {
+    return confuse(1) + confuse(null);
+  }
+
+  static f2() {
+    return confuse(1) + null;
+  }
+
+  static f3() {
+    return (confuse(1) as int) + confuse(null);
+  }
+
+  static f4() {
+    return (confuse(1) as int) + null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + null;
+  }
+
+  static f7() {
+    return 1 + null;
+  }
+
+  static test() {
+    check('IntPlusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class StringPlusNull {
+  static f1() {
+    return confuse('a') + confuse(null);
+  }
+
+  static f2() {
+    return confuse('a') + null;
+  }
+
+  static f3() {
+    return (confuse('a') as String) + confuse(null);
+  }
+
+  static f4() {
+    return (confuse('a') as String) + null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + null;
+  }
+
+  static f7() {
+    return 'a' + null;
+  }
+
+  static test() {
+    check('StringPlusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class IntPlusString {
+  static f1() {
+    return confuse(1) + confuse('a');
+  }
+
+  static f2() {
+    return confuse(1) + 'a';
+  }
+
+  static f3() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + confuse('a');
+  }
+
+  static f4() {
+    return (confuse(1) as int) + confuse('a');
+  }
+
+  static f5() {
+    return (confuse(1) as int) + 'a';
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a + 'a';
+  }
+
+  static f7() {
+    return 1 + 'a';
+  }
+
+  static test() {
+    check('IntPlusString', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class StringPlusInt {
+  static f1() {
+    return confuse('a') + confuse(1);
+  }
+
+  static f2() {
+    return confuse('a') + 1;
+  }
+
+  static f3() {
+    return (confuse('a') as String) + confuse(1);
+  }
+
+  static f4() {
+    return (confuse('a') as String) + 1;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + confuse(1);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + 1;
+  }
+
+  static f7() {
+    return 'a' + 1;
+  }
+
+  static test() {
+    check('StringPlusInt', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+main() {
+  IntPlusNull.test();
+  StringPlusNull.test();
+  IntPlusString.test();
+  StringPlusInt.test();
+}
diff --git a/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart b/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart
new file mode 100644
index 0000000..2c47018
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_null_add_error_test.dart
@@ -0,0 +1,82 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that optimized 'null + x' and slow path '+' produce the same error.
+//
+// They don't, sometimes we generate null.$add, sometimes JSNull_methods.$add.
+
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+}
+
+
+class NullPlusInt {
+  static f1() {
+    return confuse(null) + confuse(1);
+  }
+
+  static f2() {
+    return confuse(null) + 1;
+  }
+
+  static f3() {
+    return (confuse(null) as int) + confuse(1);
+  }
+
+  static f4() {
+    return (confuse(null) as int) + 1;
+  }
+
+  static f5() {
+    var a = null;
+    return a + confuse(1);
+  }
+
+  static f6() {
+    var a = null;
+    return a + 1;
+  }
+
+  static test() {
+    // Sometimes we generate null.$add, sometimes JSNull_methods.$add. The best
+    // we can do is check there is an error.
+    check('NullPlusInt', f1, f1);
+    check('NullPlusInt', f2, f2);
+    check('NullPlusInt', f3, f3);
+    check('NullPlusInt', f4, f4);
+    check('NullPlusInt', f5, f5);
+    check('NullPlusInt', f6, f6);
+  }
+}
+
+main() {
+  NullPlusInt.test();
+}
diff --git a/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart b/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart
new file mode 100644
index 0000000..757c37d
--- /dev/null
+++ b/tests/compiler/dart2js_extra/consistent_subtract_error_test.dart
@@ -0,0 +1,113 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+// Test that optimized '-' and slow path '-' produce the same error.
+
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+  if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntMinusNull {
+  static f1() {
+    return confuse(1) - confuse(null);
+  }
+
+  static f2() {
+    return confuse(1) - null;
+  }
+
+  static f3() {
+    return (confuse(1) as int) - confuse(null);
+  }
+
+  static f4() {
+    return (confuse(1) as int) - null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - null;
+  }
+
+  static f7() {
+    return 1 - null;
+  }
+
+  static test() {
+    check('IntMinusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class IntMinusString {
+  static f1() {
+    return confuse(1) - confuse('a');
+  }
+
+  static f2() {
+    return confuse(1) - 'a';
+  }
+
+  static f3() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - confuse('a');
+  }
+
+  static f4() {
+    return (confuse(1) as int) - confuse('a');
+  }
+
+  static f5() {
+    return (confuse(1) as int) - 'a';
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2;  // Small int with unknown value.
+    return a - 'a';
+  }
+
+  static f7() {
+    return 1 - 'a';
+  }
+
+  static test() {
+    check('IntMinusString', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+main() {
+  IntMinusNull.test();
+  IntMinusString.test();
+}
diff --git a/tests/compiler/dart2js_extra/hash_code_test.dart b/tests/compiler/dart2js_extra/hash_code_test.dart
index 0c5c4b3..3329a38 100644
--- a/tests/compiler/dart2js_extra/hash_code_test.dart
+++ b/tests/compiler/dart2js_extra/hash_code_test.dart
@@ -7,9 +7,11 @@
 // dart2js specific test to make sure hashCode on intercepted types behaves as
 // intended.
 
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 class Hasher {
-  confuse(x) => [1, 'x', true, null, x].last;
   hash(x) => confuse(x).hashCode;
 }
 
diff --git a/tests/compiler/dart2js_extra/many_constants_test.dart b/tests/compiler/dart2js_extra/many_constants_test.dart
new file mode 100644
index 0000000..5027b50
--- /dev/null
+++ b/tests/compiler/dart2js_extra/many_constants_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This program has many similar constants that should all have distinct
+// identities. They are sufficiently similar to have name collisions and need
+// ordering by constant value.
+
+import "package:expect/expect.dart";
+
+enum E { A, B, C, D }
+
+class Z {
+  final a, b, c, d, e, f;
+  const Z({this.a: 1, this.b: 1, this.c: 1, this.d: 1, this.e: 1, this.f: 1});
+}
+
+const c1 = const {};
+const c2 = const <int, int>{};
+const c3 = const <dynamic, int>{};
+const c4 = const <int, dynamic>{};
+const l1 = const [];
+const l2 = const <int>[];
+const l3 = const <String>[];
+const l4 = const <num>[];
+
+const ll1 = const [1, 2, 3, 4, 5, 6, 7];
+const ll2 = const [1, 8, 3, 4, 5, 6, 7];
+const ll3 = const [1, 2, 8, 4, 5, 6, 7];
+const ll4 = const [1, 2, 3, 4, 8, 6, 7];
+
+const m1 = const {1: 1, 2: 2};
+const m2 = const {1: 2, 2: 1};
+const m3 = const {1: 1, 2: 1};
+const m4 = const {1: 2, 2: 2};
+const m5 = const {2: 1, 1: 2};
+const m6 = const {2: 2, 1: 1};
+const m7 = const {2: 1, 1: 1};
+const m8 = const {2: 2, 1: 2};
+const m9 = const <int,int>{1: 1, 2: 2};
+const mA = const <int,int>{1: 2, 2: 1};
+const mB = const <int,int>{1: 1, 2: 1};
+const mC = const <int,int>{1: 2, 2: 2};
+
+const mE1 = const {E.A: E.B};
+const mE2 = const {E.A: E.C};
+const mE3 = const {E.A: 0, E.B: 0};
+const mE4 = const {E.A: 0, E.C: 0};
+const mE5 = const {E.A: 0, E.B: 0, E.C: 4};
+const mE6 = const {E.A: 0, E.B: 0, E.C: 2};
+const mE7 = const {E.A: 0, E.B: 0, E.C: 3};
+const mE8 = const {E.A: 0, E.B: 0, E.C: 1};
+
+const z1 = const Z(f: 3);
+const z2 = const Z(f: 2);
+const z3 = const Z(f: 1);
+const z4 = const Z(e: 2);
+const z5 = const Z(d: 3);
+const z6 = const Z(d: 2);
+
+makeAll() => {
+  'E.A': E.A, 'E.B': E.B, 'E.C': E.C, 'E.D': E.D,
+  'c1': c1, 'c2': c2, 'c3': c3, 'c4': c4,
+  'l1': l1, 'l2': l2, 'l3': l3, 'l4': l4,
+  'll1': ll1, 'll2': ll2, 'll3': ll3, 'l4': ll4,
+  'm1': m1, 'm2': m2, 'm3': m3, 'm4': m4,
+  'm5': m5, 'm6': m6, 'm7': m7, 'm8': m8,
+  'm9': m9, 'mA': mA, 'mB': mB, 'mC': mC,
+  'mE1': mE1, 'mE2': mE2, 'mE3': mE3, 'mE4': mE4,
+  'mE5': mE5, 'mE6': mE6, 'mE7': mE7, 'mE8': mE8,
+  'z1': z1, 'z2': z2, 'z3': z3, 'z4': z4, 'z5': z5, 'z6': z6,
+};
+
+main() {
+  var all1 = makeAll();
+  var all2 = makeAll();
+
+  for (var name1 in all1.keys) {
+    var e1 = all1[name1];
+    for (var name2 in all2.keys) {
+      if (name1 == name2) continue;
+      var e2 = all2[name2];
+      Expect.isFalse(identical(e1, e2),
+                     'Different instances  $name1: $e1  $name2: $e2');
+    }
+  }
+}
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
index 9b6d8d2..49b74cf 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke2_test.dart
@@ -17,7 +17,7 @@
 class C {
   foo() => 1;
 
-  @DontInline
+  @NoInline()
   // Use a closure to prevent inlining until the annotation is implemented.
   bar() => () => 2;
 }
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
index e142253..4236b3f 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke3_test.dart
@@ -17,7 +17,7 @@
 class C {
   static foo() => 1;
 
-  @DontInline
+  @NoInline()
   // Use a closure to prevent inlining until the annotation is implemented.
   static bar() => () => 2;
 }
diff --git a/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart b/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
index 09e8d65..35df0e0 100644
--- a/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
+++ b/tests/compiler/dart2js_extra/mirror_invalid_invoke_test.dart
@@ -16,7 +16,7 @@
 
 foo() => 1;
 
-@DontInline
+@NoInline()
 // Use a closure to prevent inlining until the annotation is implemented.
 bar() => () => 2;
 
diff --git a/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart b/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
index 28c19a8..12551cf 100644
--- a/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
+++ b/tests/compiler/dart2js_extra/mirrors_used_closure_test.dart
@@ -18,12 +18,9 @@
   bar() => 33;
 }
 
-// Uses DateTime.now to make it impossible to predict.
-// Uses recursive call to make it harder to inline.
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x + 1);
-  return x;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 main() {
   var f = [new A(), new B()][confuse(0)].bar;
diff --git a/tests/corelib/apply_test.dart b/tests/corelib/apply_test.dart
index e06cf6d..0ad85b1 100644
--- a/tests/corelib/apply_test.dart
+++ b/tests/corelib/apply_test.dart
@@ -25,14 +25,9 @@
   int call(int x, int y) => x + y;
 }
 
-confuse() {
-  try {
-    throw [Function.apply];
-  } catch (e) {
-    return e[0];
-  }
-  return null;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 main() {
   testMap(res, func, map) {
@@ -62,7 +57,7 @@
   testList(42, cfoo, [32]);
 
   // Test that apply works even with a different name.
-  var app = confuse();
+  var app = confuse(Function.apply);
   Expect.equals(42, app(test2, [22, 20]));
 
   // Test that apply can itself be applied.
diff --git a/tests/corelib/date_time4_test.dart b/tests/corelib/date_time4_test.dart
index 7e936ff..46c1c10 100644
--- a/tests/corelib/date_time4_test.dart
+++ b/tests/corelib/date_time4_test.dart
@@ -6,11 +6,21 @@
 
 // Test fromString with 6 digits after the decimal point.
 
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
+
 main() {
+  if (supportsMicroseconds) {
+    testMicrosecondPrecision();
+  } else {
+    testMillisecondPrecision();
+  }
+}
+
+void testMillisecondPrecision() {
   // We only support milliseconds. If the user supplies more data (the "51"
   // here), we round.
-  // If (eventually) we support more than just milliseconds this test could
-  // fail. Please update the test in this case.
   DateTime dt1 = DateTime.parse("1999-01-02 23:59:59.999519");
   Expect.equals(1999, dt1.year);
   Expect.equals(1, dt1.month);
@@ -48,5 +58,48 @@
   Expect.equals(13, dt1.second);
   Expect.equals(752, dt1.millisecond);
   Expect.equals(true, dt1.isUtc);
-  
+}
+
+void testMicrosecondPrecision() {
+  DateTime dt1 = DateTime.parse("1999-01-02 23:59:59.999519");
+  Expect.equals(1999, dt1.year);
+  Expect.equals(1, dt1.month);
+  Expect.equals(2, dt1.day);
+  Expect.equals(23, dt1.hour);
+  Expect.equals(59, dt1.minute);
+  Expect.equals(59, dt1.second);
+  Expect.equals(999, dt1.millisecond);
+  Expect.equals(519, dt1.microsecond);
+  Expect.equals(false, dt1.isUtc);
+  dt1 = DateTime.parse("1999-01-02 23:58:59.999519Z");
+  Expect.equals(1999, dt1.year);
+  Expect.equals(1, dt1.month);
+  Expect.equals(2, dt1.day);
+  Expect.equals(23, dt1.hour);
+  Expect.equals(58, dt1.minute);
+  Expect.equals(59, dt1.second);
+  Expect.equals(999, dt1.millisecond);
+  Expect.equals(519, dt1.microsecond);
+  Expect.equals(true, dt1.isUtc);
+  dt1 = DateTime.parse("0009-09-09 09:09:09.009411Z");
+  Expect.equals(9, dt1.year);
+  Expect.equals(9, dt1.month);
+  Expect.equals(9, dt1.day);
+  Expect.equals(9, dt1.hour);
+  Expect.equals(9, dt1.minute);
+  Expect.equals(9, dt1.second);
+  Expect.equals(9, dt1.millisecond);
+  Expect.equals(411, dt1.microsecond);
+  Expect.equals(true, dt1.isUtc);
+  String svnDate = "2012-03-30T04:28:13.752341Z";
+  dt1 = DateTime.parse(svnDate);
+  Expect.equals(2012, dt1.year);
+  Expect.equals(3, dt1.month);
+  Expect.equals(30, dt1.day);
+  Expect.equals(4, dt1.hour);
+  Expect.equals(28, dt1.minute);
+  Expect.equals(13, dt1.second);
+  Expect.equals(752, dt1.millisecond);
+  Expect.equals(341, dt1.microsecond);
+  Expect.equals(true, dt1.isUtc);
 }
diff --git a/tests/corelib/date_time_parse_test.dart b/tests/corelib/date_time_parse_test.dart
index 2f48923..85f183a 100644
--- a/tests/corelib/date_time_parse_test.dart
+++ b/tests/corelib/date_time_parse_test.dart
@@ -9,10 +9,19 @@
   Expect.equals(expected, actual);  // Only checks if they are at the same time.
   Expect.equals(expected.isUtc, actual.isUtc);
 }
+
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
 main() {
   check(new DateTime(2012, 02, 27, 13, 27), "2012-02-27 13:27:00");
-  check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123),
-        "2012-02-27 13:27:00.123456z");
+  if (supportsMicroseconds) {
+    check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+          "2012-02-27 13:27:00.123456z");
+  } else {
+    check(new DateTime.utc(2012, 02, 27, 13, 27, 0, 123, 456),
+          "2012-02-27 13:27:00.123z");
+  }
   check(new DateTime(2012, 02, 27, 13, 27), "20120227 13:27:00");
   check(new DateTime(2012, 02, 27, 13, 27), "20120227T132700");
   check(new DateTime(2012, 02, 27), "20120227");
@@ -31,8 +40,15 @@
   check(new DateTime.utc(2015, 02, 14, 13, 0, 0, 0),
         "2015-02-15T00:00:00+11:00");
 
-  check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 501),
-        "2015-02-15T00:00:00.5005Z");
-  check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 512),
-        "2015-02-15T00:00:00.5115Z");
+  if (supportsMicroseconds) {
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 500, 500),
+        "2015-02-15T00:00:00.500500Z");
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 511, 500),
+        "2015-02-15T00:00:00.511500Z");
+  } else {
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 501),
+        "2015-02-15T00:00:00.501Z");
+    check(new DateTime.utc(2015, 02, 15, 0, 0, 0, 512),
+        "2015-02-15T00:00:00.512Z");
+  }
 }
diff --git a/tests/corelib/date_time_test.dart b/tests/corelib/date_time_test.dart
index 79dcdd9..efb2206 100644
--- a/tests/corelib/date_time_test.dart
+++ b/tests/corelib/date_time_test.dart
@@ -6,6 +6,9 @@
 
 // Dart test program for DateTime.
 
+bool get supportsMicroseconds =>
+    new DateTime.fromMicrosecondsSinceEpoch(1).microsecondsSinceEpoch == 1;
+
 // Identical to _MAX_MILLISECONDS_SINCE_EPOCH in date_time.dart
 const int _MAX_MILLISECONDS = 8640000000000000;
 
@@ -26,13 +29,25 @@
   Expect.isFalse(t1.isUtc);
 }
 
-void testValue() {
+void testMillisecondsSinceEpoch() {
   var dt1 = new DateTime.now();
   var millisecondsSinceEpoch = dt1.millisecondsSinceEpoch;
   var dt2 = new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
   Expect.equals(millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
 }
 
+void testMicrosecondsSinceEpoch() {
+  var dt1 = new DateTime.fromMillisecondsSinceEpoch(1);
+  var microsecondsSinceEpoch = dt1.microsecondsSinceEpoch;
+  var dt2 = new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch);
+  Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+
+  dt1 = new DateTime.now();
+  microsecondsSinceEpoch = dt1.microsecondsSinceEpoch;
+  dt2 = new DateTime.fromMicrosecondsSinceEpoch(microsecondsSinceEpoch);
+  Expect.equals(microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+}
+
 void testFarAwayDates() {
   DateTime dt =
       new DateTime.fromMillisecondsSinceEpoch(1000000000000001, isUtc: true);
@@ -43,6 +58,7 @@
   Expect.equals(46, dt.minute);
   Expect.equals(40, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001, isUtc: true);
   Expect.equals(-29719, dt.year);
   Expect.equals(4, dt.month);
@@ -51,6 +67,7 @@
   Expect.equals(13, dt.minute);
   Expect.equals(19, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   // Same with local zone.
   dt = new DateTime.fromMillisecondsSinceEpoch(1000000000000001);
   Expect.equals(33658, dt.year);
@@ -62,6 +79,7 @@
   Expect.equals(true, dt.minute % 15 == 46 % 15);
   Expect.equals(40, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-1000000000000001);
   Expect.equals(-29719, dt.year);
   Expect.equals(4, dt.month);
@@ -72,6 +90,52 @@
   Expect.equals(true, dt.minute % 15 == 13);
   Expect.equals(19, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  if (!supportsMicroseconds) return;
+  dt =
+      new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001, isUtc: true);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(27, dt.day);
+  Expect.equals(1, dt.hour);
+  Expect.equals(46, dt.minute);
+  Expect.equals(40, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(
+      -1000000000000000001, isUtc: true);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(5, dt.day);
+  Expect.equals(22, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
+  // Same with local zone.
+  dt = new DateTime.fromMicrosecondsSinceEpoch(1000000000000000001);
+  Expect.equals(33658, dt.year);
+  Expect.equals(9, dt.month);
+  Expect.equals(true, dt.day == 27 || dt.day == 26);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 46 % 15);
+  Expect.equals(40, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-1000000000000000001);
+  Expect.equals(-29719, dt.year);
+  Expect.equals(4, dt.month);
+  Expect.equals(true, 5 == dt.day || 6 == dt.day);
+  // Not much we can test for local hour.
+  Expect.equals(true, dt.hour >= 0 && dt.hour < 24);
+  // Timezones can have offsets down to 15 minute.
+  Expect.equals(true, dt.minute % 15 == 13);
+  Expect.equals(19, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
 }
 
 void testEquivalentYears() {
@@ -86,6 +150,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-63108000000, isUtc: true);
   Expect.equals(1968, dt.year);
   Expect.equals(1, dt.month);
@@ -94,6 +159,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-94644000000, isUtc: true);
   Expect.equals(1967, dt.year);
   Expect.equals(1, dt.month);
@@ -102,6 +168,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-126180000000, isUtc: true);
   Expect.equals(1966, dt.year);
   Expect.equals(1, dt.month);
@@ -110,6 +177,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-157716000000, isUtc: true);
   Expect.equals(1965, dt.year);
   Expect.equals(1, dt.month);
@@ -118,6 +186,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-2177402400000, isUtc: true);
   Expect.equals(1901, dt.year);
   Expect.equals(1, dt.month);
@@ -126,6 +195,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-5333076000000, isUtc: true);
   Expect.equals(1801, dt.year);
   Expect.equals(1, dt.month);
@@ -134,6 +204,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-8520285600000, isUtc: true);
   Expect.equals(1700, dt.year);
   Expect.equals(1, dt.month);
@@ -142,6 +213,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-14831719200000, isUtc: true);
   Expect.equals(1500, dt.year);
   Expect.equals(1, dt.month);
@@ -150,6 +222,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-59011408800000, isUtc: true);
   Expect.equals(100, dt.year);
   Expect.equals(1, dt.month);
@@ -158,6 +231,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-62011408800000, isUtc: true);
   Expect.equals(4, dt.year);
   Expect.equals(12, dt.month);
@@ -166,6 +240,7 @@
   Expect.equals(40, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-64011408800000, isUtc: true);
   Expect.equals(-59, dt.year);
   Expect.equals(7, dt.month);
@@ -174,6 +249,7 @@
   Expect.equals(6, dt.minute);
   Expect.equals(40, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   final int SECONDS_YEAR_2035 = 2051222400;
   dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 + 1,
                                            isUtc: true);
@@ -184,6 +260,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(SECONDS_YEAR_2035 * 1000 - 1,
                                            isUtc: true);
   Expect.equals(2034, dt.year);
@@ -193,6 +270,8 @@
   Expect.equals(59, dt.minute);
   Expect.equals(59, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
   dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 1);
   Expect.equals(SECONDS_YEAR_2035 * 1000 + 1, dt.millisecondsSinceEpoch);
   dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999);
@@ -211,6 +290,8 @@
                       (2034 == dt.year && 12 == dt.month && 31 == dt.day));
   Expect.equals(59, dt.second);
   Expect.equals(999, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
   dt2 = new DateTime(
       dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
       dt.millisecond);
@@ -223,6 +304,8 @@
   Expect.equals(20, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
   // Internally this will use the maximum value for the native calls.
   dt = new DateTime(2036, 7, 18, 13, 20);
   Expect.equals(2036, dt.year);
@@ -232,7 +315,46 @@
   Expect.equals(20, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   Expect.equals("2036-07-18 13:20:00.000", dt.toString());
+
+  if (!supportsMicroseconds) return;
+
+  dt = new DateTime.utc(2035, 1, 1, 0, 0, 0, 0, 1);
+  Expect.equals(SECONDS_YEAR_2035 * 1000000 + 1, dt.microsecondsSinceEpoch);
+  dt = new DateTime.utc(2034, 12, 31, 23, 59, 59, 999, 999);
+  Expect.equals(SECONDS_YEAR_2035 * 1000000 - 1, dt.microsecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(SECONDS_YEAR_2035 * 1000000 + 1);
+  Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+                      (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
+  dt2 = new DateTime(
+      dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+      dt.millisecond, dt.microsecond);
+  Expect.equals(dt.microsecondsSinceEpoch, dt2.microsecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(SECONDS_YEAR_2035 * 1000000 - 1);
+  Expect.equals(true, (2035 == dt.year && 1 == dt.month && 1 == dt.day) ||
+                      (2034 == dt.year && 12 == dt.month && 31 == dt.day));
+  Expect.equals(59, dt.second);
+  Expect.equals(999, dt.millisecond);
+  Expect.equals(999, dt.microsecond);
+
+  dt2 = new DateTime(
+      dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
+      dt.millisecond, dt.microsecond);
+  Expect.equals(dt.millisecondsSinceEpoch, dt2.millisecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(2100000000 * 1000000,
+      isUtc: true);
+  Expect.equals(2036, dt.year);
+  Expect.equals(7, dt.month);
+  Expect.equals(18, dt.day);
+  Expect.equals(13, dt.hour);
+  Expect.equals(20, dt.minute);
+  Expect.equals(0, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
 }
 
 void testExtremes() {
@@ -245,6 +367,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
   Expect.equals(-271821, dt.year);
   Expect.equals(4, dt.month);
@@ -253,6 +376,7 @@
   Expect.equals(0, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   // Make sure that we can build the extreme dates in local too.
   dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
   dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
@@ -280,6 +404,35 @@
   dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
   Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
                                    dt.hour, dt.minute, 0, -1));
+
+  if (!supportsMicroseconds) return;
+
+  dt = new DateTime.fromMicrosecondsSinceEpoch(_MAX_MILLISECONDS * 1000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-_MAX_MILLISECONDS * 1000);
+  dt = new DateTime(dt.year, dt.month, dt.day, dt.hour, dt.minute);
+  Expect.equals(-_MAX_MILLISECONDS * 1000, dt.microsecondsSinceEpoch);
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      _MAX_MILLISECONDS * 1000 + 1, isUtc: true));
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      -_MAX_MILLISECONDS * 1000 - 1, isUtc: true));
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      _MAX_MILLISECONDS * 1000 + 1));
+  Expect.throws(() => new DateTime.fromMicrosecondsSinceEpoch(
+      -_MAX_MILLISECONDS * 1000 - 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS);
+  Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+                               dt.hour, dt.minute, 0, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+                                   dt.hour, dt.minute, 0, 0, 1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS);
+  Expect.throws(() => new DateTime(dt.year, dt.month, dt.day,
+                               dt.hour, dt.minute, 0, 0, -1));
+  dt = new DateTime.fromMillisecondsSinceEpoch(-_MAX_MILLISECONDS, isUtc: true);
+  Expect.throws(() => new DateTime.utc(dt.year, dt.month, dt.day,
+                                   dt.hour, dt.minute, 0, 0, -1));
 }
 
 void testUTCGetters() {
@@ -291,6 +444,7 @@
   Expect.equals(58, dt.minute);
   Expect.equals(35, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
   Expect.equals(true, dt.isUtc);
   Expect.equals(1305140315000, dt.millisecondsSinceEpoch);
   dt = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
@@ -301,12 +455,26 @@
   Expect.equals(13, dt.minute);
   Expect.equals(20, dt.second);
   Expect.equals(1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  if (!supportsMicroseconds) return;
+
+  dt = new DateTime.fromMicrosecondsSinceEpoch(-9999999999, isUtc: true);
+  Expect.equals(1969, dt.year);
+  Expect.equals(12, dt.month);
+  Expect.equals(31, dt.day);
+  Expect.equals(21, dt.hour);
+  Expect.equals(13, dt.minute);
+  Expect.equals(20, dt.second);
+  Expect.equals(0, dt.millisecond);
+  Expect.equals(1, dt.microsecond);
 }
 
 void testLocalGetters() {
   var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
   var dt2 = new DateTime.utc(dt1.year, dt1.month, dt1.day,
-                         dt1.hour, dt1.minute, dt1.second, dt1.millisecond);
+                         dt1.hour, dt1.minute, dt1.second, dt1.millisecond,
+                         dt1.microsecond);
   Duration zoneOffset = dt1.difference(dt2);
   Expect.equals(true, zoneOffset.inDays == 0);
   Expect.equals(true, zoneOffset.inHours.abs() <= 12);
@@ -321,34 +489,40 @@
                 ((dt1.minute - dt2.minute).abs() == 15));
   Expect.equals(dt1.second, dt2.second);
   Expect.equals(dt1.millisecond, dt2.millisecond);
+  Expect.equals(dt1.microsecond, dt2.microsecond);
 }
 
 void testConstructors() {
-  var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0);
-  var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0).toLocal();
+  var dt0 = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0, 0);
+  var dt0b = new DateTime.utc(2011, 5, 11, 18, 58, 35, 0, 0).toLocal();
   Expect.equals(1305140315000, dt0.millisecondsSinceEpoch);
   var dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000);
   Expect.equals(dt1.millisecondsSinceEpoch, dt0.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt0.microsecondsSinceEpoch);
   Expect.equals(false, dt1 == dt0);
   Expect.equals(true, dt1 == dt0b);
   var dt3 = new DateTime(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
-                     dt1.second, dt1.millisecond);
+                     dt1.second, dt1.millisecond, dt1.microsecond);
   Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   Expect.equals(false, dt3 == dt0);
   Expect.equals(true, dt1 == dt3);
   dt3 = new DateTime(
       dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
-      dt1.second, dt1.millisecond);
+      dt1.second, dt1.millisecond, dt1.microsecond);
   Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   Expect.equals(true, dt1 == dt3);
   var dt2 = dt1.toLocal();
-  dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0);
+  dt3 = new DateTime(2011, 5, dt1.day, dt1.hour, dt1.minute, 35, 0, 0);
   Expect.equals(dt2.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt2.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   Expect.equals(true, dt2 == dt3);
   dt1 = new DateTime.fromMillisecondsSinceEpoch(-9999999, isUtc: true);
   dt3 = new DateTime.utc(dt1.year, dt1.month, dt1.day, dt1.hour, dt1.minute,
                      dt1.second, dt1.millisecond);
   Expect.equals(dt1.millisecondsSinceEpoch, dt3.millisecondsSinceEpoch);
+  Expect.equals(dt1.microsecondsSinceEpoch, dt3.microsecondsSinceEpoch);
   dt3 = new DateTime.utc(99, 1, 2, 10, 11, 12, 0);
   Expect.equals(99, dt3.year);
   Expect.equals(1, dt3.month);
@@ -357,6 +531,7 @@
   Expect.equals(11, dt3.minute);
   Expect.equals(12, dt3.second);
   Expect.equals(0, dt3.millisecond);
+  Expect.equals(0, dt3.microsecond);
   Expect.equals(true, dt3.isUtc);
   var dt4 = new DateTime(99, 1, 2);
   Expect.equals(99, dt4.year);
@@ -366,6 +541,7 @@
   Expect.equals(0, dt4.minute);
   Expect.equals(0, dt4.second);
   Expect.equals(0, dt4.millisecond);
+  Expect.equals(0, dt4.microsecond);
   Expect.isFalse(dt4.isUtc);
   var dt5 = new DateTime.utc(99, 1, 2);
   Expect.equals(99, dt5.year);
@@ -375,6 +551,7 @@
   Expect.equals(0, dt5.minute);
   Expect.equals(0, dt5.second);
   Expect.equals(0, dt5.millisecond);
+  Expect.equals(0, dt5.microsecond);
   Expect.isTrue(dt5.isUtc);
   var dt6 = new DateTime(2012, 2, 27, 13, 27, 0);
   Expect.equals(2012, dt6.year);
@@ -384,6 +561,7 @@
   Expect.equals(27, dt6.minute);
   Expect.equals(0, dt6.second);
   Expect.equals(0, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   Expect.isFalse(dt6.isUtc);
   var dt7 = new DateTime.utc(2012, 2, 27, 13, 27, 0);
   Expect.equals(2012, dt7.year);
@@ -393,6 +571,7 @@
   Expect.equals(27, dt7.minute);
   Expect.equals(0, dt7.second);
   Expect.equals(0, dt7.millisecond);
+  Expect.equals(0, dt7.microsecond);
   Expect.isTrue(dt7.isUtc);
 }
 
@@ -409,6 +588,7 @@
   Expect.equals(dt2.minute, dt3.minute);
   Expect.equals(dt2.second, dt3.second);
   Expect.equals(dt2.millisecond, dt3.millisecond);
+  Expect.equals(dt2.microsecond, dt3.microsecond);
   var dt4 = dt3.toLocal();
   Expect.equals(dt1.year, dt4.year);
   Expect.equals(dt1.month, dt4.month);
@@ -417,6 +597,7 @@
   Expect.equals(dt1.minute, dt4.minute);
   Expect.equals(dt1.second, dt4.second);
   Expect.equals(dt1.millisecond, dt4.millisecond);
+  Expect.equals(dt1.microsecond, dt4.microsecond);
 }
 
 void testSubAdd() {
@@ -430,19 +611,39 @@
   Expect.equals(dt1.minute, dt2.minute);
   Expect.equals(dt1.second + 3, dt2.second);
   Expect.equals(dt1.millisecond + 5, dt2.millisecond);
+  Expect.equals(dt1.microsecond, dt2.microsecond);
   var dt3 = dt2.subtract(new Duration(milliseconds:
       3 * Duration.MILLISECONDS_PER_SECOND + 5));
   Expect.equals(true, dt1 == dt3);
   Expect.equals(false, dt1 == dt2);
+
+  if (!supportsMicroseconds) return;
+
+  dt1 = new DateTime.fromMillisecondsSinceEpoch(1305140315000, isUtc: true);
+  dt2 = dt1.add(new Duration(microseconds:
+      3 * Duration.MICROSECONDS_PER_SECOND + 5));
+  Expect.equals(dt1.year, dt2.year);
+  Expect.equals(dt1.month, dt2.month);
+  Expect.equals(dt1.day, dt2.day);
+  Expect.equals(dt1.hour, dt2.hour);
+  Expect.equals(dt1.minute, dt2.minute);
+  Expect.equals(dt1.second + 3, dt2.second);
+  Expect.equals(dt1.millisecond, dt2.millisecond);
+  Expect.equals(dt1.microsecond + 5, dt2.microsecond);
+  dt3 = dt2.subtract(new Duration(microseconds:
+      3 * Duration.MICROSECONDS_PER_SECOND + 5));
+  Expect.equals(true, dt1 == dt3);
+  Expect.equals(false, dt1 == dt2);
 }
 
 void testUnderflowAndOverflow() {
-  final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500);
+  int microsecond = supportsMicroseconds ? 499 : 0;
+  final dtBase = new DateTime(2012, 6, 20, 12, 30, 30, 500, microsecond);
 
   // Millisecond
   print("  >>> Millisecond+");
   var dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                    dtBase.minute, dtBase.second, 1000);
+                    dtBase.minute, dtBase.second, 1000, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -450,10 +651,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second + 1, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Millisecond-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                dtBase.minute, dtBase.second, -1000);
+                dtBase.minute, dtBase.second, -1000, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -461,11 +663,12 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second - 1, dt.second);
   Expect.equals(0, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Second
   print("  >>> Second+");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                dtBase.minute, 60, dtBase.millisecond);
+                dtBase.minute, 60, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -473,10 +676,11 @@
   Expect.equals(dtBase.minute + 1, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Second-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
-                dtBase.minute, -60, dtBase.millisecond);
+                dtBase.minute, -60, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -484,11 +688,12 @@
   Expect.equals(dtBase.minute - 1, dt.minute);
   Expect.equals(0, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Minute
   print("  >>> Minute+");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, 60,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -496,10 +701,11 @@
   Expect.equals(0, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Minute-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour, -60,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -507,11 +713,12 @@
   Expect.equals(0, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Hour
   print("  >>> Hour+");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, 24, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day + 1, dt.day);
@@ -519,10 +726,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Hour-");
   dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, -24, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month, dt.month);
   Expect.equals(dtBase.day - 1, dt.day);
@@ -530,11 +738,12 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Day
   print("  >>> Day+");
   dt = new DateTime(dtBase.year, dtBase.month, 31, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month + 1, dt.month);
   Expect.equals(1, dt.day);
@@ -542,10 +751,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Day-");
   dt = new DateTime(dtBase.year, dtBase.month, -30, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year, dt.year);
   Expect.equals(dtBase.month - 1, dt.month);
   Expect.equals(1, dt.day);
@@ -553,11 +763,12 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Month
   print("  >>> Month+");
   dt = new DateTime(dtBase.year, 13, dtBase.day, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year + 1, dt.year);
   Expect.equals(1, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -565,10 +776,11 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   print("  >>> Month-");
   dt = new DateTime(dtBase.year, -11, dtBase.day, dtBase.hour, dtBase.minute,
-                dtBase.second, dtBase.millisecond);
+                dtBase.second, dtBase.millisecond, dtBase.microsecond);
   Expect.equals(dtBase.year - 1, dt.year);
   Expect.equals(1, dt.month);
   Expect.equals(dtBase.day, dt.day);
@@ -576,13 +788,14 @@
   Expect.equals(dtBase.minute, dt.minute);
   Expect.equals(dtBase.second, dt.second);
   Expect.equals(dtBase.millisecond, dt.millisecond);
+  Expect.equals(dtBase.microsecond, dt.microsecond);
 
   // Flowing all the way up the chain.
   print("  >>> Flow+");
-  var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999);
+  var dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999, 000);
   var dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
                         dtBase1.hour, dtBase1.minute, dtBase1.second,
-                        dtBase1.millisecond + 1);
+                        dtBase1.millisecond + 1, dtBase1.microsecond);
   Expect.equals(dtBase1.year + 1, dtTick.year);
   Expect.equals(1, dtTick.month);
   Expect.equals(1, dtTick.day);
@@ -590,11 +803,13 @@
   Expect.equals(0, dtTick.minute);
   Expect.equals(0, dtTick.second);
   Expect.equals(0, dtTick.millisecond);
+  Expect.equals(0, dtTick.microsecond);
 
   print("  >>> Flow-");
   dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0);
   dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
-                    dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1);
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond - 1,
+                    dtBase1.microsecond);
   Expect.equals(dtBase1.year - 1, dtTick.year);
   Expect.equals(12, dtTick.month);
   Expect.equals(31, dtTick.day);
@@ -602,10 +817,12 @@
   Expect.equals(59, dtTick.minute);
   Expect.equals(59, dtTick.second);
   Expect.equals(999, dtTick.millisecond);
+  Expect.equals(0, dtTick.microsecond);
 
   print("  >>> extra underflow");
   dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, -17520,
-                    dtBase1.minute, dtBase1.second, dtBase1.millisecond);
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond,
+                    dtBase1.microsecond);
   Expect.equals(dtBase1.year - 2, dtTick.year);
   Expect.equals(dtBase1.month, dtTick.month);
   Expect.equals(dtBase1.day, dtTick.day);
@@ -613,6 +830,63 @@
   Expect.equals(dtBase1.minute, dtTick.minute);
   Expect.equals(dtBase1.second, dtTick.second);
   Expect.equals(dtBase1.millisecond, dtTick.millisecond);
+  Expect.equals(dtBase1.microsecond, dtTick.microsecond);
+
+  if (!supportsMicroseconds) return;
+
+  // Microsecond
+  print("  >>> Microsecond+");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                    dtBase.minute, dtBase.second, dtBase.millisecond, 1000);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond + 1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  print("  >>> Microsecond-");
+  dt = new DateTime(dtBase.year, dtBase.month, dtBase.day, dtBase.hour,
+                dtBase.minute, dtBase.second, dtBase.millisecond, -1000);
+  Expect.equals(dtBase.year, dt.year);
+  Expect.equals(dtBase.month, dt.month);
+  Expect.equals(dtBase.day, dt.day);
+  Expect.equals(dtBase.hour, dt.hour);
+  Expect.equals(dtBase.minute, dt.minute);
+  Expect.equals(dtBase.second, dt.second);
+  Expect.equals(dtBase.millisecond - 1, dt.millisecond);
+  Expect.equals(0, dt.microsecond);
+
+  // Flowing all the way up the chain.
+  print("  >>> Flow+ 2");
+  dtBase1 = new DateTime(2012, 12, 31, 23, 59, 59, 999, 999);
+  dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day,
+                        dtBase1.hour, dtBase1.minute, dtBase1.second,
+                        dtBase1.millisecond, dtBase1.microsecond + 1);
+  Expect.equals(dtBase1.year + 1, dtTick.year);
+  Expect.equals(1, dtTick.month);
+  Expect.equals(1, dtTick.day);
+  Expect.equals(0, dtTick.hour);
+  Expect.equals(0, dtTick.minute);
+  Expect.equals(0, dtTick.second);
+  Expect.equals(0, dtTick.millisecond);
+  Expect.equals(0, dtTick.microsecond);
+
+  print("  >>> Flow- 2");
+  dtBase1 = new DateTime(2012, 1, 1, 0, 0, 0, 0, 0);
+  dtTick = new DateTime(dtBase1.year, dtBase1.month, dtBase1.day, dtBase1.hour,
+                    dtBase1.minute, dtBase1.second, dtBase1.millisecond,
+                    dtBase1.microsecond - 1);
+  Expect.equals(dtBase1.year - 1, dtTick.year);
+  Expect.equals(12, dtTick.month);
+  Expect.equals(31, dtTick.day);
+  Expect.equals(23, dtTick.hour);
+  Expect.equals(59, dtTick.minute);
+  Expect.equals(59, dtTick.second);
+  Expect.equals(999, dtTick.millisecond);
+  Expect.equals(999, dtTick.microsecond);
 }
 
 void testDateStrings() {
@@ -640,6 +914,7 @@
   Expect.equals(0, dt4.minute);
   Expect.equals(0, dt4.second);
   Expect.equals(0, dt4.millisecond);
+  Expect.equals(0, dt4.microsecond);
   Expect.isTrue(dt4.isUtc);
   var dt5 = DateTime.parse("0099-01-02");
   Expect.equals(99, dt5.year);
@@ -649,17 +924,23 @@
   Expect.equals(0, dt5.minute);
   Expect.equals(0, dt5.second);
   Expect.equals(0, dt5.millisecond);
+  Expect.equals(0, dt5.microsecond);
   Expect.isFalse(dt5.isUtc);
   var dt6 = DateTime.parse("2012-01-01 00:00:10.012");
   Expect.equals(12, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.003");
   Expect.equals(3, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.5");
   Expect.equals(500, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.003Z");
   Expect.equals(3, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   dt6 = DateTime.parse("2012-01-01 00:00:10.5z");
   Expect.equals(500, dt6.millisecond);
+  Expect.equals(0, dt6.microsecond);
   var dt7 = DateTime.parse("2011-05-11T18:58:35Z");
   Expect.equals(1305140315000, dt7.millisecondsSinceEpoch);
   var dt8 = DateTime.parse("-1234-01-01T00:00:00Z");
@@ -670,6 +951,7 @@
   Expect.equals(0, dt8.minute);
   Expect.equals(0, dt8.second);
   Expect.equals(0, dt8.millisecond);
+  Expect.equals(0, dt8.microsecond);
   Expect.isTrue(dt8.isUtc);
   var dt9 = DateTime.parse("-1234-01-01T00:00:00");
   Expect.equals(-1234, dt9.year);
@@ -679,6 +961,7 @@
   Expect.equals(0, dt9.minute);
   Expect.equals(0, dt9.second);
   Expect.equals(0, dt9.millisecond);
+  Expect.equals(0, dt9.microsecond);
   Expect.isFalse(dt9.isUtc);
   var dt10 = DateTime.parse("-12340101");
   Expect.equals(-1234, dt10.year);
@@ -688,6 +971,7 @@
   Expect.equals(0, dt10.minute);
   Expect.equals(0, dt10.second);
   Expect.equals(0, dt10.millisecond);
+  Expect.equals(0, dt10.microsecond);
   Expect.isFalse(dt10.isUtc);
   dt1 = DateTime.parse("2012-02-27 13:27:00");
   Expect.equals(2012, dt1.year);
@@ -697,6 +981,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("2012-02-27 13:27:00.423z");
   Expect.equals(2012, dt1.year);
@@ -706,6 +991,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(423, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(true, dt1.isUtc);
   dt1 = DateTime.parse("20120227 13:27:00");
   Expect.equals(2012, dt1.year);
@@ -715,6 +1001,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("20120227T132700");
   Expect.equals(2012, dt1.year);
@@ -724,6 +1011,7 @@
   Expect.equals(27, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("20120227");
   Expect.equals(2012, dt1.year);
@@ -733,6 +1021,7 @@
   Expect.equals(0, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("2012-02-27T14Z");
   Expect.equals(2012, dt1.year);
@@ -742,6 +1031,7 @@
   Expect.equals(0, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(true, dt1.isUtc);
   dt1 = DateTime.parse("-123450101 00:00:00 Z");
   Expect.equals(-12345, dt1.year);
@@ -751,28 +1041,51 @@
   Expect.equals(0, dt1.minute);
   Expect.equals(0, dt1.second);
   Expect.equals(0, dt1.millisecond);
+  Expect.equals(0, dt1.microsecond);
   Expect.equals(true, dt1.isUtc);
-  // We only support millisecond. If the user supplies more data (the "51"
-  // here), we round.
-  // If (eventually) we support more than just millisecond this test could
-  // fail. Please update the test in this case.
   dt1 = DateTime.parse("1999-01-02 23:59:59.99951");
-  Expect.equals(1999, dt1.year);
-  Expect.equals(1, dt1.month);
-  Expect.equals(3, dt1.day);
-  Expect.equals(0, dt1.hour);
-  Expect.equals(0, dt1.minute);
-  Expect.equals(0, dt1.second);
-  Expect.equals(0, dt1.millisecond);
+  if (supportsMicroseconds) {
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(2, dt1.day);
+    Expect.equals(23, dt1.hour);
+    Expect.equals(59, dt1.minute);
+    Expect.equals(59, dt1.second);
+    Expect.equals(999, dt1.millisecond);
+    Expect.equals(510, dt1.microsecond);
+  } else {
+    // We only support millisecond. If the user supplies more data (the "51"
+    // here), we round.
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(3, dt1.day);
+    Expect.equals(0, dt1.hour);
+    Expect.equals(0, dt1.minute);
+    Expect.equals(0, dt1.second);
+    Expect.equals(0, dt1.millisecond);
+    Expect.equals(0, dt1.microsecond);
+  }
   Expect.equals(false, dt1.isUtc);
   dt1 = DateTime.parse("1999-01-02 23:58:59.99951Z");
-  Expect.equals(1999, dt1.year);
-  Expect.equals(1, dt1.month);
-  Expect.equals(2, dt1.day);
-  Expect.equals(23, dt1.hour);
-  Expect.equals(59, dt1.minute);
-  Expect.equals(0, dt1.second);
-  Expect.equals(0, dt1.millisecond);
+  if (supportsMicroseconds) {
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(2, dt1.day);
+    Expect.equals(23, dt1.hour);
+    Expect.equals(58, dt1.minute);
+    Expect.equals(59, dt1.second);
+    Expect.equals(999, dt1.millisecond);
+    Expect.equals(510, dt1.microsecond);
+  } else {
+    Expect.equals(1999, dt1.year);
+    Expect.equals(1, dt1.month);
+    Expect.equals(2, dt1.day);
+    Expect.equals(23, dt1.hour);
+    Expect.equals(59, dt1.minute);
+    Expect.equals(0, dt1.second);
+    Expect.equals(0, dt1.millisecond);
+    Expect.equals(0, dt1.microsecond);
+  }
   Expect.equals(true, dt1.isUtc);
   dt1 = DateTime.parse("0009-09-09 09:09:09.009Z");
   Expect.equals(9, dt1.year);
@@ -866,11 +1179,22 @@
                 (e) => e is FormatException);
   Expect.throws(() => DateTime.parse("275760-09-13T00:00:00.001Z"),
                 (e) => e is FormatException);
+  if (supportsMicroseconds) {
+    Expect.throws(() => DateTime.parse("275760-09-13T00:00:00.000001Z"),
+                  (e) => e is FormatException);
+  } else {
+    dt1 = DateTime.parse("275760-09-13T00:00:00.000001Z");
+  }
 
   // first valid time; should not throw.
   dt1 = DateTime.parse("-271821-04-20T00:00:00.000Z");
   Expect.throws(() => DateTime.parse("-271821-04-19T23:59:59.999Z"),
                 (e) => e is FormatException);
+
+  if (supportsMicroseconds) {
+    Expect.throws(() => DateTime.parse("-271821-04-19T23:59:59.999999Z"),
+                  (e) => e is FormatException);
+  }
 }
 
 void testWeekday() {
@@ -932,6 +1256,14 @@
   test("1970-01-01", "00:00:00.000");
   test("1969-12-31", "23:59:59.999");
   test("1969-09-09", "00:09:09.009");
+
+  if (supportsMicroseconds) {
+    test("2000-01-01", "12:00:00.000001");
+    test("-2000-01-01", "12:00:00.000001");
+    test("1970-01-01", "00:00:00.000001");
+    test("1969-12-31", "23:59:59.999999");
+    test("1969-09-09", "00:09:09.009999");
+  }
 }
 
 void testIsoString() {
@@ -952,11 +1284,50 @@
   Expect.equals("+010000-01-01T23:59:59.999Z", d.toIso8601String());
   d = new DateTime.utc(-10000, 1, 1, 23, 59, 59, 999);
   Expect.equals("-010000-01-01T23:59:59.999Z", d.toIso8601String());
+
+  if (!supportsMicroseconds) return;
+
+  d = new DateTime(9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("9999-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime(-9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-9999-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime.utc(9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("9999-01-01T23:59:59.999999Z", d.toIso8601String());
+  d = new DateTime.utc(-9999, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-9999-01-01T23:59:59.999999Z", d.toIso8601String());
+
+  d = new DateTime(10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("+010000-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime(-10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-010000-01-01T23:59:59.999999", d.toIso8601String());
+  d = new DateTime.utc(10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("+010000-01-01T23:59:59.999999Z", d.toIso8601String());
+  d = new DateTime.utc(-10000, 1, 1, 23, 59, 59, 999, 999);
+  Expect.equals("-010000-01-01T23:59:59.999999Z", d.toIso8601String());
+
+  d = new DateTime(9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("9999-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime(-9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-9999-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime.utc(9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("9999-01-01T23:49:59.989979Z", d.toIso8601String());
+  d = new DateTime.utc(-9999, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-9999-01-01T23:49:59.989979Z", d.toIso8601String());
+
+  d = new DateTime(10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("+010000-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime(-10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-010000-01-01T23:49:59.989979", d.toIso8601String());
+  d = new DateTime.utc(10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("+010000-01-01T23:49:59.989979Z", d.toIso8601String());
+  d = new DateTime.utc(-10000, 1, 1, 23, 49, 59, 989, 979);
+  Expect.equals("-010000-01-01T23:49:59.989979Z", d.toIso8601String());
 }
 
 void main() {
   testNow();
-  testValue();
+  testMillisecondsSinceEpoch();
+  testMicrosecondsSinceEpoch();
   testConstructors();
   testUTCGetters();
   testLocalGetters();
diff --git a/tests/corelib/int_parse_radix_test.dart b/tests/corelib/int_parse_radix_test.dart
index ce68a79..fbe9205 100644
--- a/tests/corelib/int_parse_radix_test.dart
+++ b/tests/corelib/int_parse_radix_test.dart
@@ -20,7 +20,6 @@
 
   for (int i = 0; i < whiteSpace.length; i++) {
     var ws = whiteSpace[i];
-    print(ws.codeUnitAt(0).toRadixString(16));
     Expect.equals(0, int.parse("${ws}0${ws}", radix: 2));
   }
 
@@ -55,8 +54,8 @@
     Expect.equals(-result, int.parse("-$zeros$radixString", radix: radix), m);
   }
 
-  for (int i = 0; i <= 36 * 36; i++) {
-    for (int r = 2; r <= 36; r++) {
+  for (int r = 2; r <= 36; r++) {
+    for (int i = 0; i <= r * r; i++) {
       String radixString = i.toRadixString(r);
       testParse(i, radixString, r);
     }
@@ -89,13 +88,14 @@
   void testFails(String source, int radix) {
     Expect.throws(() { throw int.parse(source, radix: radix,
                                        onError: (s) { throw "FAIL"; }); },
-                  (e) => e == "FAIL",
+                  isFail,
                   "$source/$radix");
     Expect.equals(-999, int.parse(source, radix: radix, onError: (s) => -999));
   }
   for (int i = 2; i < 36; i++) {
-    testFails(i.toRadixString(36).toLowerCase(), i);
-    testFails(i.toRadixString(36).toUpperCase(), i);
+    var char = i.toRadixString(36);
+    testFails(char.toLowerCase(), i);
+    testFails(char.toUpperCase(), i);
   }
   testFails("", 2);
   testFails("+ 1", 2);  // No space between sign and digits.
@@ -141,3 +141,5 @@
   Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
   Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
 }
+
+bool isFail(e) => e == "FAIL";
diff --git a/tests/html/html.status b/tests/html/html.status
index b5f2cf3..afe5400 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -106,6 +106,10 @@
 element_animate_test/omit_timing: RuntimeError # Also timing out on MacOS. Issue 23507
 element_animate_test/timing_dict: RuntimeError # Also timing out on MacOS. Issue 23507
 element_animate_test/simple_timing: RuntimeError # Please triage this failure
+element_types_test/supported_object: RuntimeError # Issue 25155
+element_types_test/supported_embed: RuntimeError # Issue 25155
+event_test: Pass, RuntimeError # Issue 25158 Passes on 46, fails on 47
+history_test/history: Pass, RuntimeError # Issue 25158, passes on 46 fails on 47
 
 [ $runtime == chrome && $system == macos ]
 canvasrenderingcontext2d_test/drawImage_video_element: Skip # Times out. Please triage this failure.
diff --git a/tests/html/websocket_test.dart b/tests/html/websocket_test.dart
index f8ba1ba..1715c88 100644
--- a/tests/html/websocket_test.dart
+++ b/tests/html/websocket_test.dart
@@ -35,6 +35,16 @@
 
         return socket.onMessage.first.then((MessageEvent e) {
           expect(e.data, 'hello!');
+          socket.close();
+        });
+      });
+
+      test('error handling', () {
+        var socket = new WebSocket('ws://${window.location.host}/ws');
+        socket.onOpen.first.then((_) => socket.send('close-with-error'));
+        return socket.onError.first.then((e) {
+          print('$e was caught, yay!');
+          socket.close();
         });
       });
     }
diff --git a/tests/language/config_import_lib1a.dart b/tests/language/config_import_lib1a.dart
new file mode 100644
index 0000000..814c15e
--- /dev/null
+++ b/tests/language/config_import_lib1a.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib1() => "a";
diff --git a/tests/language/config_import_lib1b.dart b/tests/language/config_import_lib1b.dart
new file mode 100644
index 0000000..59212de
--- /dev/null
+++ b/tests/language/config_import_lib1b.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib1() => "b";
diff --git a/tests/language/config_import_lib1c.dart b/tests/language/config_import_lib1c.dart
new file mode 100644
index 0000000..86fd9e9
--- /dev/null
+++ b/tests/language/config_import_lib1c.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib1() => "c";
diff --git a/tests/language/config_import_lib2a.dart b/tests/language/config_import_lib2a.dart
new file mode 100644
index 0000000..00665dd
--- /dev/null
+++ b/tests/language/config_import_lib2a.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib2() => "a";
diff --git a/tests/language/config_import_lib2b.dart b/tests/language/config_import_lib2b.dart
new file mode 100644
index 0000000..6d91daf
--- /dev/null
+++ b/tests/language/config_import_lib2b.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib2() => "b";
diff --git a/tests/language/config_import_lib2c.dart b/tests/language/config_import_lib2c.dart
new file mode 100644
index 0000000..6ed0235
--- /dev/null
+++ b/tests/language/config_import_lib2c.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib2() => "c";
diff --git a/tests/language/config_import_lib3a.dart b/tests/language/config_import_lib3a.dart
new file mode 100644
index 0000000..c2f9fec
--- /dev/null
+++ b/tests/language/config_import_lib3a.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib3() => "a";
diff --git a/tests/language/config_import_lib3b.dart b/tests/language/config_import_lib3b.dart
new file mode 100644
index 0000000..b6d5afc
--- /dev/null
+++ b/tests/language/config_import_lib3b.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib3() => "b";
diff --git a/tests/language/config_import_lib3c.dart b/tests/language/config_import_lib3c.dart
new file mode 100644
index 0000000..b984783
--- /dev/null
+++ b/tests/language/config_import_lib3c.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib3() => "c";
diff --git a/tests/language/config_import_lib4a.dart b/tests/language/config_import_lib4a.dart
new file mode 100644
index 0000000..1607f07
--- /dev/null
+++ b/tests/language/config_import_lib4a.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib4() => "a";
diff --git a/tests/language/config_import_lib4b.dart b/tests/language/config_import_lib4b.dart
new file mode 100644
index 0000000..9e2f08c
--- /dev/null
+++ b/tests/language/config_import_lib4b.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib4() => "b";
diff --git a/tests/language/config_import_lib4c.dart b/tests/language/config_import_lib4c.dart
new file mode 100644
index 0000000..f4a1972
--- /dev/null
+++ b/tests/language/config_import_lib4c.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+String lib4() => "c";
diff --git a/tests/language/config_import_test.dart b/tests/language/config_import_test.dart
new file mode 100644
index 0000000..5678e8e
--- /dev/null
+++ b/tests/language/config_import_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// DartOptions=-Did=true -Ddotted.id=some_string -Dlots.of.dots.In.id=false --conditional-directives
+
+import 'package:expect/expect.dart';
+
+import 'config_import_lib1a.dart'
+  if (id) 'config_import_lib1b.dart'
+  if (not.set.id) 'config_import_lib1c.dart';
+
+import 'config_import_lib2a.dart'
+  if (not.set.id) 'config_import_lib2b.dart'
+  if (not.set.either) 'config_import_lib2c.dart';
+
+import 'config_import_lib3a.dart'
+  if (dotted.id == "some_string") 'config_import_lib3b.dart'
+  if (id) 'config_import_lib3c.dart';
+
+import 'config_import_lib4a.dart'
+  if (lots.of.dots.In.id == "other") 'config_import_lib4b.dart'
+  if (lots.of.dots.In.id == "false") 'config_import_lib4c.dart';
+
+main() {
+  Expect.equals("b", lib1());
+  Expect.equals("a", lib2());
+  Expect.equals("b", lib3());
+  Expect.equals("c", lib4());
+}
diff --git a/tests/language/const_for_in_variable_test.dart b/tests/language/const_for_in_variable_test.dart
new file mode 100644
index 0000000..a12cd55
--- /dev/null
+++ b/tests/language/const_for_in_variable_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {
+  for(
+      const                           /// 01: compile-time error
+      final                           /// 02: ok
+      int x in const [1, 2, 3]) {
+    break;
+  }
+}
\ No newline at end of file
diff --git a/tests/language/const_getter_test.dart b/tests/language/const_getter_test.dart
new file mode 100644
index 0000000..97717e8
--- /dev/null
+++ b/tests/language/const_getter_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Check that const getters are not allowed.
+
+import 'package:expect/expect.dart';
+
+class C {
+  const C();
+
+  const /// 01: compile-time error
+  get x => 1;
+}
+
+const /// 02: compile-time error
+get y => 2;
+
+main() {
+  Expect.equals(1, const C().x);
+  Expect.equals(2, y);
+}
diff --git a/tests/language/const_map2_test.dart b/tests/language/const_map2_test.dart
index 6b599f7..d32ca5b 100644
--- a/tests/language/const_map2_test.dart
+++ b/tests/language/const_map2_test.dart
@@ -14,10 +14,8 @@
   operator ==(o) => true;  /// 00: compile-time error
 }
 
-confuse(x) {
-  if (new DateTime.now() == 42) return confuse(2);
-  return x;
-}
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
 main() {
   // It is a compile-time error if the key type overrides operator ==.
diff --git a/tests/language/const_map_test.dart b/tests/language/const_map_test.dart
index 96db1d6..9cc0d5b 100644
--- a/tests/language/const_map_test.dart
+++ b/tests/language/const_map_test.dart
@@ -7,11 +7,8 @@
 /// Returns its argument.
 ///
 /// Prevents static optimizations and inlining.
-confuse(x) {
-  // DateTime.now() cannot be predicted statically.
-  if (new DateTime.now() == 42) return confuse(2);
-  return x;
-}
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
 main() {
   // Make sure that const maps use the == operator and not identical. The
diff --git a/tests/language/language.status b/tests/language/language.status
index 8c5eb92..0d4a45c 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -31,6 +31,9 @@
 async_star_cancel_while_paused_test: RuntimeError
 async_star_await_pauses_test: Skip # Times out. Issue 23996
 
+# Unsupported configuration specific imports.
+config_import_test: Fail # Issue 24581
+
 [ $compiler == none && $runtime == vm ]
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 unicode_bom_test: Fail # Issue 16067
@@ -135,6 +138,5 @@
 tearoff_basic_test: RuntimeError, Crash # Conflicting flag.
 vm/type_cast_vm_test: RuntimeError # Line number mismatch.
 regress_23408_test: RuntimeError
-issue21159_test: Pass, Crash, Timeout # Issue 24659 - missing stack overflow check
 
 stack_trace_test: Fail  # Issue 24783 - inlined frames missing
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index a5f91bf..a6eb91c 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -63,7 +63,7 @@
 
 # TBF: we should check conflicts not only for methods, but for accessors too
 override_field_test/03: fail
-method_override7_test/03: Fail # Issue 11496
+method_override7_test/03: Fail # Issue 11497
 
 external_test/21: Fail
 external_test/24: Fail
@@ -85,6 +85,11 @@
 multiline_newline_test/05: MissingCompileTimeError # Issue 23888
 multiline_newline_test/06: MissingCompileTimeError # Issue 23888
 
+const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
+
+# Unsupported configuration specific imports.
+config_import_test: CompileTimeError # Issue 24579
+
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
 #
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 27be7e0..ac93e88 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -22,7 +22,7 @@
 
 # TBF: we should check conflicts not only for methods, but for accessors too
 override_field_test/03: fail
-method_override7_test/03: Fail # Issue 11496
+method_override7_test/03: Fail # Issue 11497
 
 external_test/21: Fail
 external_test/24: Fail
@@ -37,6 +37,11 @@
 multiline_newline_test/05: MissingCompileTimeError # Issue 23888
 multiline_newline_test/06: MissingCompileTimeError # Issue 23888
 
+const_for_in_variable_test/01: MissingCompileTimeError # Issue 25161
+
+# Unsupported configuration specific imports.
+config_import_test: CompileTimeError # Issue 24579
+
 # Please add new failing tests before this line.
 # Section below is for invalid tests.
 #
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 1767b22..e872f46 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,9 +3,6 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dart2js ]
-sync_generator2_test/07: MissingCompileTimeError # Issue 22324
-sync_generator2_test/08: MissingCompileTimeError # Issue 22324
-sync_generator2_test/10: MissingCompileTimeError # Issue 22324
 getter_setter_in_lib_test: Fail # Issue 23288
 
 async_star_cancel_while_paused_test: RuntimeError # Issue 22853
@@ -22,6 +19,9 @@
 await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
 async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
 
+[ $compiler == dart2js && $browser ]
+config_import_test: Fail # Test flag is not passed to the compiler.
+
 [ $compiler == dart2js ]
 invocation_mirror_empty_arguments_test: Fail # Issue 24331
 nan_identical_test: Fail # Issue 11551
@@ -131,10 +131,6 @@
 symbol_conflict_test: RuntimeError # Issue 23857
 
 [ $compiler == dart2js ]
-async_await_syntax_test/a05h: Fail # 23716
-async_await_syntax_test/c11a: Fail # 23716
-async_await_syntax_test/c11b: Fail # 23716
-
 malformed_test/none: Fail # Expect failure in lib/_internal/js_runtime/lib/preambles/d8.js
 
 type_variable_conflict2_test/01: RuntimeError # Issue 19725
@@ -148,9 +144,7 @@
 mint_arithmetic_test: RuntimeError # Issue 1533
 left_shift_test: RuntimeError # Issue 1533
 regress_24283_test: RuntimeError # Issue 1533
-bad_override_test/01: CompileTimeError # Issue 11496
-bad_override_test/02: CompileTimeError # Issue 11496
-constructor_named_arguments_test/01: CompileTimeError # Issue 5519
+constructor_named_arguments_test/01: CompileTimeError # Issue 25225
 not_enough_positional_arguments_test/01: CompileTimeError # Issue 12838
 not_enough_positional_arguments_test/02: CompileTimeError # Issue 12838
 not_enough_positional_arguments_test/05: CompileTimeError # Issue 12838
@@ -224,7 +218,7 @@
 generic_field_mixin5_test: Crash # Issue 18651
 many_method_calls_test: Crash # Stack overflow in HGraphVisitor.visitPostDominatorTree.visitBasicBlockAndSuccessors
 
-[ $compiler == dart2js ]
+[ $compiler == dart2js && $runtime != drt && $runtime != dartium ]
 issue23244_test: RuntimeError # 23244
 
 [ $compiler == dart2js && $cps_ir ]
@@ -280,7 +274,6 @@
 closure_in_constructor_test: RuntimeError # Please triage this failure.
 closures_initializer_test: RuntimeError # Please triage this failure.
 constructor12_test: RuntimeError # Please triage this failure.
-crash_6725_test/01: Crash # unsupported operation on erroneous element
 deferred_call_empty_before_load_test: Crash # (lib1.thefun()): deferred access is not implemented
 deferred_closurize_load_library_test: RuntimeError # D.loadLibrary is not a function
 deferred_constant_list_test: RuntimeError # K.loadLibrary is not a function
diff --git a/tests/language/null_test.dart b/tests/language/null_test.dart
index 83ffd7b..ecb2e00 100644
--- a/tests/language/null_test.dart
+++ b/tests/language/null_test.dart
@@ -36,13 +36,9 @@
 // Magic incantation to avoid the compiler recognizing the constant values
 // at compile time. If the result is computed at compile time, the dynamic code
 // will not be tested.
-confuse(x) {
-  try {
-    if (new DateTime.now().millisecondsSinceEpoch == 42) x = 42;
-    throw [x];
-  } on dynamic catch (e) { return e[0]; }
-  return 42;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x;
 
 void main() {
   for (int i = 0; i < 10; i++) {
diff --git a/tests/language/range_analysis3_test.dart b/tests/language/range_analysis3_test.dart
index 5628e46..8777212 100644
--- a/tests/language/range_analysis3_test.dart
+++ b/tests/language/range_analysis3_test.dart
@@ -4,14 +4,9 @@
 
 import "package:expect/expect.dart";
 
-confuse(x) {
-  if (new DateTime.now().millisecondsSinceEpoch == 0) {
-    return confuse(x + 1);
-  } else if (new DateTime.now().millisecondsSinceEpoch == 0) {
-    return confuse(x - 1);
-  }
-  return x;
-}
+@NoInline()
+@AssumeDynamic()
+confuse(x) => x is int ? x : 0;
 
 test1() {
   int x = 0;
@@ -207,4 +202,4 @@
   test3b();
   test4a();
   test4b();
-}
\ No newline at end of file
+}
diff --git a/tests/language/regress_25122_test.dart b/tests/language/regress_25122_test.dart
new file mode 100644
index 0000000..b7d4068
--- /dev/null
+++ b/tests/language/regress_25122_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main() {}
+
+class AbstractListMember<E, M extends AbstractListMember<E, M>> {}
+
+class RepoListMember<M extends RepoListMember<M>>
+    extends AbstractListMember<String, M> {}
diff --git a/tests/language/syncstar_less_than_test.dart b/tests/language/syncstar_less_than_test.dart
index b0551a8..db2f6f3 100644
--- a/tests/language/syncstar_less_than_test.dart
+++ b/tests/language/syncstar_less_than_test.dart
@@ -4,7 +4,8 @@
 
 import "package:expect/expect.dart";
 
-confuse(x) => [1, 'x', true, null, x].last;
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
 
 Iterable<int> foo() sync* {
  var a = confuse(1);
@@ -15,4 +16,4 @@
 
 main() {
   Expect.listEquals(foo().toList(), [2]);
-}
\ No newline at end of file
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 079fa14..12ceb29 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -64,12 +64,6 @@
 mirrors/load_library_test: RuntimeError # Issue 6335
 mirrors/local_function_is_static_test: RuntimeError # Issue 6335
 mirrors/lru_test: Skip # dart2js_native/lru_test is used instead
-mirrors/metadata_allowed_values_test/01: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/05: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/10: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/11: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/13: MissingCompileTimeError # Issue 14548
-mirrors/metadata_allowed_values_test/14: MissingCompileTimeError # Issue 14548
 mirrors/metadata_scope_test/none: CompileTimeError # Issue 10905
 mirrors/method_mirror_name_test: RuntimeError # Issue 6335
 mirrors/method_mirror_properties_test: RuntimeError # Issue 11861
diff --git a/tests/standalone/array_bounds_check_generalization_test.dart b/tests/standalone/array_bounds_check_generalization_test.dart
index bfd0cce..2b6099d 100644
--- a/tests/standalone/array_bounds_check_generalization_test.dart
+++ b/tests/standalone/array_bounds_check_generalization_test.dart
@@ -2,7 +2,9 @@
 // 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.
 //
-// VMOptions=--optimization_counter_threshold=10 --no-use-osr
+// We are using --complete-timeline below to ensure that we get timeline events
+// generated during all phases of compilation and deoptimization.
+// VMOptions=--optimization_counter_threshold=10 --no-use-osr --complete-timeline
 
 import "package:expect/expect.dart";
 
diff --git a/tests/try/poi/serialize_test.dart b/tests/try/poi/serialize_test.dart
index b77327e..c890b8b 100644
--- a/tests/try/poi/serialize_test.dart
+++ b/tests/try/poi/serialize_test.dart
@@ -519,15 +519,15 @@
     "kind": "class"
   },
   {
+    "name": "Match",
+    "kind": "class"
+  },
+  {
     "name": "print",
     "kind": "function",
     "type": "(Object) -> void"
   },
   {
-    "name": "Match",
-    "kind": "class"
-  },
-  {
     "name": "RegExp",
     "kind": "class"
   },
diff --git a/tests/try/try.status b/tests/try/try.status
index e256bca..d6d7ca7 100644
--- a/tests/try/try.status
+++ b/tests/try/try.status
@@ -39,9 +39,6 @@
 [ $compiler == dart2js ]
 poi/*: Skip # Issue 20031
 
-[ $compiler == dart2js && $runtime == none ]
-poi/serialize_test: RuntimeError # Issue 25125
-
 [ $compiler == dart2js ]
 # Compilation is slow, test fails at runtime due to time out, but
 # unpredictably.
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index 5b2f041..1f6c520 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -10,9 +10,6 @@
 recursive_import_test: Slow, Pass
 source_mirrors_test: Slow, Pass
 
-[ $compiler == none && $runtime == drt ]
-dummy_compiler_test: Skip # Issue 7233
-
 [ $compiler == dart2js && $browser ]
 *: Skip
 
diff --git a/tools/VERSION b/tools/VERSION
index 7d5050b..433c092 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 14
 PATCH 0
-PRERELEASE 3
+PRERELEASE 4
 PRERELEASE_PATCH 0
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
index da166aa..53bd1ca 100644
--- a/tools/bots/bot_utils.py
+++ b/tools/bots/bot_utils.py
@@ -71,7 +71,7 @@
 
   Under every base path, the following structure is used:
     - /VERSION
-    - /api-docs/{dart-api-docs.zip,dartdocs-gen-api.zip}
+    - /api-docs/dartdocs-gen-api.zip
     - /dartium/{chromedriver,content_shell,dartium}
          -{linux,macos,windows}-{ia32,x64}-release.zip
     - /sdk/dartsdk-{linux,macos,windows}-{ia32,x64}-release.zip
@@ -119,6 +119,10 @@
     return '/'.join([self.dartium_directory(revision),
       self.dartium_variant_zipfilename(name, system, arch, mode)])
 
+  def apidocs_zipfilepath(self, revision):
+    return '/'.join([self.apidocs_directory(revision),
+      self.dartdocs_zipfilename()])
+
   def dartium_android_apk_filepath(self, revision, name, arch, mode):
     return '/'.join([self.dartium_android_directory(revision),
       self.dartium_android_apk_filename(name, arch, mode)])
@@ -162,9 +166,6 @@
   def dartium_android_apk_filename(self, name, arch, mode):
     return '%s-%s-%s.apk' % (name, arch, mode)
 
-  def apidocs_zipfilename(self):
-    return 'dart-api-docs.zip'
-
   def dartdocs_zipfilename(self):
     return 'dartdocs-gen-api.zip'
 
diff --git a/tools/dom/dom.py b/tools/dom/dom.py
index e0bbfdd..c69d065 100755
--- a/tools/dom/dom.py
+++ b/tools/dom/dom.py
@@ -139,7 +139,7 @@
   return call(cmd)
 
 def test_server():
-  start_test_server(5400, os.path.join('out', 'ReleaseIA32'))
+  start_test_server(5400, os.path.join('out', 'ReleaseX64'))
 
 def test_server_dartium():
   start_test_server(5500, os.path.join('..', 'out', 'Release'))
diff --git a/tools/promote.py b/tools/promote.py
index d3013ab..81ab402 100644
--- a/tools/promote.py
+++ b/tools/promote.py
@@ -131,11 +131,10 @@
     remove_gs_directory(to_loc)
     Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])
 
-    # Copy api-docs directory.
-    from_loc = raw_namer.apidocs_directory(revision)
-    to_loc = release_namer.apidocs_directory(to_revision)
-    remove_gs_directory(to_loc)
-    Gsutil(['-m', 'cp', '-a', 'public-read', '-R', from_loc, to_loc])
+    # Copy api-docs zipfile.
+    from_loc = raw_namer.apidocs_zipfilepath(revision)
+    to_loc = release_namer.apidocs_zipfilepath(to_revision)
+    Gsutil(['-m', 'cp', '-a', 'public-read', from_loc, to_loc])
 
     # Copy dartium directory.
     from_loc = raw_namer.dartium_directory(revision)
diff --git a/tools/testing/dart/http_server.dart b/tools/testing/dart/http_server.dart
index 7f5fae7..843aaaf 100644
--- a/tools/testing/dart/http_server.dart
+++ b/tools/testing/dart/http_server.dart
@@ -260,7 +260,13 @@
       websocket.done.catchError((_) {});
       websocket.listen((data) {
         websocket.add(data);
-        websocket.close();
+        if (data == 'close-with-error') {
+          // Note: according to the web-sockets spec, a reason longer than 123
+          // bytes will produce a SyntaxError on the client.
+          websocket.close(WebSocketStatus.UNSUPPORTED_DATA, 'X' * 124);
+        } else {
+          websocket.close();
+        }
       }, onError: (e) {
         DebugLogger.warning('HttpServer: error while echoing to WebSocket', e);
       });
