Version 1.14.0-dev.4.0

Merge commit '1ffc230bf0952850497c913fb878df4333290abf' into dev
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);