Version 1.12.0-dev.5.0

Merge commit '2ca0bc6d5a844c7e107e5502ec37669eabb35841' into dev
diff --git a/.gitattributes b/.gitattributes
index d77d09b..9dfc906 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -16,6 +16,9 @@
 tests/compiler/dart2js_extra/literal_string_juxtaposition_test.dart -text
 tests/language/raw_string_test.dart -text
 tests/language/multiline_strings_test.dart -text
+tests/language/multiline_newline_cr.dart -text
+tests/language/multiline_newline_crlf.dart -text
+tests/language/multiline_newline_lf.dart -text
 tests/lib/convert/json_pretty_test.dart -text
 tests/lib/mirrors/method_mirror_source_line_ending_test.dart -text
 tests/lib/mirrors/method_mirror_source_line_ending_cr.dart -text
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8383615..feb8c48 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -68,6 +68,9 @@
     * A crashing bug involving transformers that only apply to non-public code
       has been fixed.
 
+    * A deadlock caused by declaring transformer followed by a lazy transformer
+      (such as the built-in `$dart2js` transformer) has been fixed.
+
     * A stack overflow caused by a transformer being run multiple times on the
       package that defines it has been fixed.
 
@@ -76,6 +79,29 @@
 
 [package spec proposal]: https://github.com/lrhn/dep-pkgspec
 
+* Formatter (`dartfmt`)
+
+  * Over 50 bugs fixed.
+
+  * Optimized line splitter is much faster and produces better output on
+    complex code.
+
+### VM Service Protocol Changes
+
+* **BREAKING** The service protocol now sends JSON-RPC 2.0-compatible
+  server-to-client events. To reflect this, the service protocol version is
+  now 2.0.
+
+* The service protocol now includes a `"jsonrpc"` property in its responses, as
+  opposed to `"json-rpc"`.
+
+* The service protocol now properly handles requests with non-string ids.
+  Numeric ids are no longer converted to strings, and null ids now don't produce
+  a response.
+
+* Some RPCs that didn't include a `"jsonrpc"` property in their responses now
+  include one.
+
 ## 1.11.2
 
 ### Core library changes
diff --git a/DEPS b/DEPS
index 50369e4..e6693ff 100644
--- a/DEPS
+++ b/DEPS
@@ -31,17 +31,17 @@
   "github_mirror":
       "https://chromium.googlesource.com/external/github.com/dart-lang/%s.git",
 
-  "gyp_rev": "@1752",
+  "gyp_rev": "@6ee91ad8659871916f9aa840d42e1513befdf638",
   "co19_rev": "@f95f109fea67127a220958794ef5200a63cb454c",
   "chromium_url": "http://src.chromium.org/svn",
   "chromium_git": "https://chromium.googlesource.com",
 
   # Revisions of /third_party/* dependencies.
   "7zip_rev" : "@19997",
-  "analyzer_cli_rev" : "@7436b45b160f99e806bef2aafd1e971e1aedfc4d",
+  "analyzer_cli_rev" : "@c4e628a8467f75ded563f029dfb2f1738856f471",
   "args_tag": "@0.13.0",
   "async_tag": "@1.2.0",
-  "barback_tag" : "@0.15.2+5",
+  "barback_tag" : "@0.15.2+6",
   "charcode_tag": "@1.1.0",
   "chrome_rev" : "@19997",
   "clang_rev" : "@28450",
@@ -51,8 +51,8 @@
   "csslib_tag" : "@0.12.0",
   "dartdoc_tag" : "@v0.1.0+5",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
-  "dart_style_tag": "@0.1.8+1",
-  "dev_compiler_rev": "@0.1.1",
+  "dart_style_tag": "@0.2.0",
+  "dev_compiler_rev": "@0.1.3",
   "fake_async_rev" : "@38614",
   "firefox_jsshell_rev" : "@45554",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
@@ -65,7 +65,7 @@
   "idl_parser_rev": "@6316d5982dc24b34d09dd8b10fbeaaff28d83a48",
   "intl_rev": "@32047558bd220a53c1f4d93a26d54b83533b1475",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
-  "json_rpc_2_rev": "@a38eefd116d910199de205f962af92fed87c164c",
+  "json_rpc_2_tag": "@1.1.1",
   "linter_tag": "@0.1.0",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@56b0fd6c018d6103862d07e8e27407b9ea3b963d",
@@ -100,7 +100,7 @@
   "stack_trace_tag": "@1.3.4",
   "string_scanner_rev": "@3e7617d6f74ba382e9b6130b1cc12091d89a9bc5",
   "sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
-  "test_tag": "@0.12.3+4",
+  "test_tag": "@0.12.3+8",
   "test_reflective_loader_tag": "@0.0.3",
   "utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
   "unittest_tag": "@0.11.6",
@@ -122,7 +122,7 @@
 deps = {
   # Stuff needed for GYP to run.
   Var("dart_root") + "/third_party/gyp":
-      (Var("googlecode_url") % "gyp") + "/trunk" + Var("gyp_rev"),
+      Var('chromium_git') + '/external/gyp.git' + Var("gyp_rev"),
 
   Var("dart_root") + "/tests/co19/src":
       (Var("github_mirror") % "co19") + Var("co19_rev"),
@@ -195,7 +195,7 @@
       (Var("github_mirror") % "csslib") + Var("csslib_tag"),
   Var("dart_root") + "/third_party/pkg_tested/dart_style":
       (Var("github_mirror") % "dart_style") + Var("dart_style_tag"),
-  Var("dart_root") + "/third_party/pkg/dartdoc":  
+  Var("dart_root") + "/third_party/pkg/dartdoc":
       "https://github.com/dart-lang/dartdoc.git" + Var("dartdoc_tag"),
   Var("dart_root") + "/third_party/pkg/dev_compiler":
       "https://github.com/dart-lang/dev_compiler.git" + Var("dev_compiler_rev"),
@@ -216,7 +216,7 @@
   Var("dart_root") + "/third_party/pkg/intl":
       (Var("github_mirror") % "intl") + Var("intl_rev"),
   Var("dart_root") + "/third_party/pkg/json_rpc_2":
-      (Var("github_mirror") % "json_rpc_2") + Var("json_rpc_2_rev"),
+      (Var("github_mirror") % "json_rpc_2") + Var("json_rpc_2_tag"),
   Var("dart_root") + "/third_party/pkg/linter":
       (Var("github_mirror") % "linter") + Var("linter_tag"),
   Var("dart_root") + "/third_party/pkg/logging":
@@ -230,16 +230,16 @@
       (Var("github_mirror") % "metatest") + Var("metatest_rev"),
   Var("dart_root") + "/third_party/pkg/mime":
       (Var("github_mirror") % "mime") + Var("mime_rev"),
-  Var("dart_root") + "/third_party/pkg/mustache4dart":  
-      Var("chromium_git")  
-      + "/external/github.com/valotas/mustache4dart.git"   
+  Var("dart_root") + "/third_party/pkg/mustache4dart":
+      Var("chromium_git")
+      + "/external/github.com/valotas/mustache4dart.git"
       + Var("mustache4dart_rev"),
   Var("dart_root") + "/third_party/pkg/oauth2":
       (Var("github_mirror") % "oauth2") + Var("oauth2_rev"),
   Var("dart_root") + "/third_party/pkg/observe":
       (Var("github_mirror") % "observe") + Var("observe_rev"),
   Var("dart_root") + "/third_party/observatory_pub_packages":
-     (Var("github_mirror") % "observatory_pub_packages") 
+     (Var("github_mirror") % "observatory_pub_packages")
       + Var("observatory_pub_packages_rev"),
   Var("dart_root") + "/third_party/pkg/package_config":
       (Var("github_mirror") % "package_config") +
@@ -254,11 +254,11 @@
       (Var("github_mirror") % "pub_semver") + Var("pub_semver_tag"),
   Var("dart_root") + "/third_party/pkg/pub":
       (Var("github_mirror") % "pub") + Var("pub_rev"),
-  Var("dart_root") + "/third_party/pkg/pub_cache":  
+  Var("dart_root") + "/third_party/pkg/pub_cache":
       (Var("github_mirror") % "pub_cache") + Var("pub_cache_tag"),
-  Var("dart_root") + "/third_party/pkg/quiver": 
-      Var("chromium_git")  
-      + "/external/github.com/google/quiver-dart.git"  
+  Var("dart_root") + "/third_party/pkg/quiver":
+      Var("chromium_git")
+      + "/external/github.com/google/quiver-dart.git"
       + Var("quiver_tag"),
   Var("dart_root") + "/third_party/pkg/scheduled_test":
       (Var("github_mirror") % "scheduled_test") +
@@ -266,7 +266,7 @@
   Var("dart_root") + "/third_party/pkg/shelf":
       (Var("github_mirror") % "shelf") + Var("shelf_rev"),
   Var("dart_root") + "/third_party/pkg/shelf_static":
-      "https://github.com/kevmoo/shelf_static.dart.git" +
+      "https://github.com/dart-lang/shelf_static.git" +
       Var("shelf_static_rev"),
   Var("dart_root") + "/third_party/pkg/shelf_web_socket":
       (Var("github_mirror") % "shelf_web_socket") +
diff --git a/pkg/analysis_server/benchmark/integration/README.md b/pkg/analysis_server/benchmark/integration/README.md
new file mode 100644
index 0000000..78431f9
--- /dev/null
+++ b/pkg/analysis_server/benchmark/integration/README.md
@@ -0,0 +1,72 @@
+# Running Benchmarks
+
+There are two entry points for running benchmarks:
+* **main.dart** - a general Dart application for running performance benchmarks
+* **local_runner.dart** - an example Dart application
+which sets up the local environment
+and then calls main.dart to run performance benchmarks
+
+## local_runner.dart
+
+This Dart application is one example for running performance benchmarks.
+When run, this application 1) extracts a branch from a git repository
+into a temporary directory, and 2) creates a symlink to the out or xcodebuild
+directory for proper package-root package resolution.
+Once setup is complete, this applications calls main.dart
+
+The required command line arguments are
+* **gitDir** = a path to the git repository containing the initial target source
+* **branch** = the branch containing the initial target source
+* **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,
+then you might need to specify -m<oldSrcPath>,<newSrcPath>
+to map the source paths for playback.
+When specifying additional arguments, any occurrences of @tmpSrcDir@
+will be replaced with the absolute path of the temporary directory
+into which the source was extracted.
+
+## main.dart
+
+This Dart application reads an instrumentation or local log file produced by
+analysis server, "replays" that interaction with the analysis server,
+compares the notifications and responses with what was recorded in the log,
+and produces a report. It assumes that the environment for playback has
+already been setup.
+The required command line arguments are
+*  **-i, --input             <filePath>**
+The input file specifying how this client should interact with the server.
+If the input file name is "stdin", then the instructions are read from stdin.
+*  **-m, --map               <oldSrcPath>,<newSrcPath>**
+This option defines a mapping from the original source directory <oldSrcPath>
+when the instrumentation or log file was generated
+to the target source directory <newSrcPath> used during performance testing.
+Multiple mappings can be specified.
+WARNING: The contents of the target directory will be modified
+*  **-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
+*  **--vv**                 Extra verbose logging
+*  **-h, --help**           Print this help information
+
+For each request recorded in the input file,
+the application sends a corresponding request to the analysis server
+and waits up to 60 seconds for a response to that request.
+If a response in not received in that time, then the application exits.
+Any responses that are received are compared with the recorded response.
+
+For each analysis-complete notification recorded in the input file,
+the application waits for the corresponding analysis-complete notification
+from the running analysis server.
+While it is waiting for an analysis-complete notification,
+the application monitors the stream of notifications.
+If there is a period of more than 60 seconds during which no communication
+is received from the server, the application assumes that the server is hung
+and exits.
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 19243ea..a3167810 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -7,7 +7,6 @@
 import 'dart:async';
 import 'dart:math' show max, sqrt;
 
-import 'package:analyzer/src/generated/engine.dart' as engine;
 import 'package:logging/logging.dart';
 
 import '../../test/integration/integration_test_methods.dart';
@@ -44,7 +43,14 @@
    */
   static const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 5);
 
-  final Logger logger;
+  final Logger logger = new Logger('Driver');
+
+  final bool newTaskModel;
+
+  /**
+   * The diagnostic port for Analysis Server or `null` if none.
+   */
+  final int diagnosticPort;
 
   /**
    * A flag indicating whether the server is running.
@@ -64,7 +70,7 @@
    */
   Completer<Results> _runCompleter = new Completer<Results>();
 
-  Driver(this.logger);
+  Driver({this.newTaskModel, this.diagnosticPort});
 
   /**
    * Return a [Future] that completes with the [Results] of running
@@ -97,7 +103,7 @@
    * Launch the analysis server.
    * Return a [Future] that completes when analysis server has started.
    */
-  Future startServer({int diagnosticPort}) async {
+  Future startServer() async {
     logger.log(Level.FINE, 'starting server');
     initializeInttestMixin();
     server = new Server();
@@ -108,7 +114,9 @@
     });
     running = true;
     return server
-        .start(diagnosticPort: diagnosticPort /*profileServer: true*/)
+        .start(
+            diagnosticPort: diagnosticPort,
+            newTaskModel: newTaskModel /*profileServer: true*/)
         .then((params) {
       server.listenToOutput(dispatchNotification);
       server.exitCode.then((_) {
@@ -193,7 +201,7 @@
     _printDuration(sb, new Duration(microseconds: meanTime));
     _printDuration(sb, time90th);
     _printDuration(sb, time99th);
-    _printColumn(sb, standardDeviation.toString(), 15, rightJustified: true);
+    _printDuration(sb, new Duration(microseconds: standardDeviation));
     _printDuration(sb, minTime);
     _printDuration(sb, maxTime);
     _printDuration(sb, new Duration(microseconds: totalTimeMicros));
@@ -212,9 +220,8 @@
   }
 
   void _printDuration(StringBuffer sb, Duration duration) {
-    sb.write('  ');
-    sb.write(duration);
-    sb.write(',');
+    _printColumn(sb, duration.inMilliseconds.toString(), 15,
+        rightJustified: true);
   }
 }
 
@@ -231,11 +238,6 @@
   void printResults() {
     print('');
     print('==================================================================');
-    if (engine.AnalysisEngine.instance.useTaskModel) {
-      print('New task model');
-    } else {
-      print('Old task model');
-    }
     print('');
     List<String> keys = measurements.keys.toList()..sort();
     int keyLen = keys.fold(0, (int len, String key) => max(len, key.length));
@@ -263,11 +265,11 @@
       }
     }
     /// TODO(danrubel) *** print warnings if driver caches are not empty ****
-    print('');
-    print(
-        '(1) uxr = UneXpected Results, or responses received from the server');
-    print(
-        '          that do not match the recorded response for that request.');
+    print('''
+
+(1) uxr = UneXpected Results or responses received from the server
+          that do not match the recorded response for that request.
+(2) all times in milliseconds''');
   }
 
   /**
@@ -294,7 +296,7 @@
     _printColumn(sb, 'error', 6, rightJustified: true);
     _printColumn(sb, 'uxr(1)', 6, rightJustified: true);
     sb.write('  ');
-    _printColumn(sb, 'mean', 15);
+    _printColumn(sb, 'mean(2)', 15);
     _printColumn(sb, '90th', 15);
     _printColumn(sb, '99th', 15);
     _printColumn(sb, 'std-dev', 15);
diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart
index ef90131..3d9fd5a 100644
--- a/pkg/analysis_server/benchmark/integration/input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/input_converter.dart
@@ -62,7 +62,7 @@
    * from location where instrumentation or log file was generated
    * to the target location of the source using during performance measurement.
    */
-  final Map<String, String> srcPathMap;
+  final PathMap srcPathMap;
 
   /**
    * The root directory for all source being modified
@@ -70,13 +70,7 @@
    */
   final String tmpSrcDirPath;
 
-  /**
-   * The diagnostic port for Analysis Server or `null` if none.
-   */
-  final int diagnosticPort;
-
-  CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap,
-      {this.diagnosticPort});
+  CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap);
 
   /**
    * Return an operation for the notification or `null` if none.
@@ -95,7 +89,7 @@
     }
     if (event == SERVER_CONNECTED) {
       // {"event":"server.connected","params":{"version":"1.7.0"}}
-      return new StartServerOperation(diagnosticPort: diagnosticPort);
+      return new StartServerOperation();
     }
     if (eventsSeen.add(event)) {
       logger.log(Level.INFO, 'Ignored notification: $event\n  $json');
@@ -182,6 +176,14 @@
         this, requestMap.remove(json['id']), translateSrcPaths(json));
   }
 
+  void logOverlayContent() {
+    logger.log(Level.WARNING, '${overlays.length} overlays');
+    List<String> allPaths = overlays.keys.toList()..sort();
+    for (String filePath in allPaths) {
+      logger.log(Level.WARNING, 'overlay $filePath\n${overlays[filePath]}');
+    }
+  }
+
   /**
    * Process an error response from the server by either
    * completing the associated completer in the [responseCompleters]
@@ -242,13 +244,7 @@
    */
   translateSrcPaths(json) {
     if (json is String) {
-      String result = json;
-      srcPathMap.forEach((String oldPrefix, String newPrefix) {
-        if (json.startsWith(oldPrefix)) {
-          result = '$newPrefix${json.substring(oldPrefix.length)}';
-        }
-      });
-      return result;
+      return srcPathMap.translate(json);
     }
     if (json is List) {
       List result = [];
@@ -281,7 +277,7 @@
    * from location where instrumentation or log file was generated
    * to the target location of the source using during performance measurement.
    */
-  final Map<String, String> srcPathMap;
+  final PathMap srcPathMap;
 
   /**
    * The root directory for all source being modified
@@ -290,11 +286,6 @@
   final String tmpSrcDirPath;
 
   /**
-   * The diagnostic port for Analysis Server or `null` if none.
-   */
-  final int diagnosticPort;
-
-  /**
    * The number of lines read before the underlying converter was determined
    * or the end of file was reached.
    */
@@ -312,7 +303,7 @@
    */
   bool active = true;
 
-  InputConverter(this.tmpSrcDirPath, this.srcPathMap, {this.diagnosticPort});
+  InputConverter(this.tmpSrcDirPath, this.srcPathMap);
 
   @override
   Operation convert(String line) {
@@ -331,11 +322,9 @@
       throw 'Failed to determine input file format';
     }
     if (InstrumentationInputConverter.isFormat(line)) {
-      converter = new InstrumentationInputConverter(tmpSrcDirPath, srcPathMap,
-          diagnosticPort: diagnosticPort);
+      converter = new InstrumentationInputConverter(tmpSrcDirPath, srcPathMap);
     } else if (LogFileInputConverter.isFormat(line)) {
-      converter = new LogFileInputConverter(tmpSrcDirPath, srcPathMap,
-          diagnosticPort: diagnosticPort);
+      converter = new LogFileInputConverter(tmpSrcDirPath, srcPathMap);
     }
     if (converter != null) {
       return converter.convert(line);
@@ -350,6 +339,43 @@
   }
 }
 
+/**
+ * A container of [PathMapEntry]s used to translate a source path in the log
+ * before it is sent to the analysis server.
+ */
+class PathMap {
+  final List<PathMapEntry> entries = [];
+
+  void add(String oldSrcPrefix, String newSrcPrefix) {
+    entries.add(new PathMapEntry(oldSrcPrefix, newSrcPrefix));
+  }
+
+  String translate(String original) {
+    String result = original;
+    for (PathMapEntry entry in entries) {
+      result = entry.translate(result);
+    }
+    return result;
+  }
+}
+
+/**
+ * An entry in [PathMap] used to translate a source path in the log
+ * before it is sent to the analysis server.
+ */
+class PathMapEntry {
+  final String oldSrcPrefix;
+  final String newSrcPrefix;
+
+  PathMapEntry(this.oldSrcPrefix, this.newSrcPrefix);
+
+  String translate(String original) {
+    return original.startsWith(oldSrcPrefix)
+        ? '$newSrcPrefix${original.substring(oldSrcPrefix.length)}'
+        : original;
+  }
+}
+
 class _InputSink extends ChunkedConversionSink<String> {
   final Converter<String, Operation> converter;
   final outSink;
diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
index 11e2f9a..790da05 100644
--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
@@ -30,9 +30,8 @@
   StringBuffer readBuffer = null;
 
   InstrumentationInputConverter(
-      String tmpSrcDirPath, Map<String, String> srcPathMap,
-      {int diagnosticPort})
-      : super(tmpSrcDirPath, srcPathMap, diagnosticPort: diagnosticPort);
+      String tmpSrcDirPath, PathMap srcPathMap)
+      : super(tmpSrcDirPath, srcPathMap);
 
   @override
   Operation convert(String line) {
diff --git a/pkg/analysis_server/benchmark/integration/local_runner.dart b/pkg/analysis_server/benchmark/integration/local_runner.dart
index 1d8d245..78d8c2a 100644
--- a/pkg/analysis_server/benchmark/integration/local_runner.dart
+++ b/pkg/analysis_server/benchmark/integration/local_runner.dart
@@ -12,7 +12,7 @@
   /*
    * Parse arguments
    */
-  if (args.length != 3) printHelp('Expected 3 arguments');
+  if (args.length < 3) printHelp('Expected 3 arguments');
   var gitDir = new Directory(args[0]);
   if (!gitDir.existsSync()) printHelp('${gitDir.path} does not exist');
   if (!new Directory(join(gitDir.path, '.git')).existsSync()) printHelp(
@@ -58,15 +58,17 @@
   ]);
   if (result.exitCode != 0) throw 'failed to link out or xcodebuild: $result';
   /*
+   * Collect arguments
+   */
+  var perfArgs = ['-i${inputFile.path}', '-t$tmpSrcDirPath',];
+  for (int index = 3; index < args.length; ++index) {
+    perfArgs.add(args[index].replaceAll('@tmpSrcDir@', tmpSrcDirPath));
+  }
+  perfArgs.add('-m${gitDir.path},$tmpSrcDirPath');
+  /*
    * Launch the performance analysis tool
    */
-  performance.main([
-    //'-vv', // very verbose
-    //'-d8081', // analysis server localhost diagnostic port
-    '-i${inputFile.path}',
-    '-t$tmpSrcDirPath',
-    '-m${gitDir.path},$tmpSrcDirPath',
-  ]);
+  performance.main(perfArgs);
 }
 
 /// Print help and exit
@@ -76,9 +78,12 @@
     print('Error: $errMsg');
     print('');
   }
-  print('Arguments: <gitDir> <branch> <inputFile>');
-  print('gitDir = git repository containing the initial target source');
-  print('branch = the branch containing the initial target source');
-  print('inputFile = the instrumentation or log file');
+  print('''Required arguments: <gitDir> <branch> <inputFile>
+gitDir = a path to the git repository containing the initial target source
+branch = the branch containing the initial target source
+inputFile = the instrumentation or log file
+
+Optional arguments:''');
+  print(performance.argParser.usage);
   exit(1);
 }
diff --git a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
index dd6c35c..0781bae 100644
--- a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
@@ -23,9 +23,8 @@
  * into a series of operations to be sent to the analysis server.
  */
 class LogFileInputConverter extends CommonInputConverter {
-  LogFileInputConverter(String tmpSrcDirPath, Map<String, String> srcPathMap,
-      {int diagnosticPort})
-      : super(tmpSrcDirPath, srcPathMap, diagnosticPort: diagnosticPort);
+  LogFileInputConverter(String tmpSrcDirPath, PathMap srcPathMap)
+      : super(tmpSrcDirPath, srcPathMap);
 
   @override
   Operation convert(String line) {
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index 793110d..7cfb299 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -26,7 +26,8 @@
   });
   PerfArgs args = parseArgs(rawArgs);
 
-  Driver driver = new Driver(logger);
+  Driver driver = new Driver(
+      diagnosticPort: args.diagnosticPort, newTaskModel: args.newTaskModel);
   Stream<Operation> stream = openInput(args);
   StreamSubscription<Operation> subscription;
   subscription = stream.listen((Operation op) {
@@ -56,6 +57,7 @@
 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
@@ -67,6 +69,43 @@
 const VERBOSE_CMDLINE_OPTION = 'verbose';
 const VERY_VERBOSE_CMDLINE_OPTION = 'vv';
 
+ArgParser _argParser;
+
+ArgParser get argParser {
+  _argParser = new ArgParser();
+
+  _argParser.addOption(INPUT_CMDLINE_OPTION, abbr: 'i', help: '<filePath>\n'
+      'The input file specifying how this client should interact with the server.\n'
+      'If the input file name is "stdin", then the instructions are read from standard input.');
+  _argParser.addOption(MAP_OPTION,
+      abbr: 'm',
+      allowMultiple: true,
+      splitCommas: false,
+      help: '<oldSrcPath>,<newSrcPath>\n'
+          'This option defines a mapping from the original source directory <oldSrcPath>\n'
+          'when the instrumentation or log file was generated\n'
+          'to the target source directory <newSrcPath> used during performance testing.\n'
+          'Multiple mappings can be specified.\n'
+          'WARNING: The contents of the target directory will be modified');
+  _argParser.addOption(TMP_SRC_DIR_OPTION, abbr: 't', 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');
+  _argParser.addFlag(VERBOSE_CMDLINE_OPTION,
+      abbr: 'v', help: 'Verbose logging', negatable: false);
+  _argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
+      help: 'Extra verbose logging', negatable: false);
+  _argParser.addFlag(HELP_CMDLINE_OPTION,
+      abbr: 'h', help: 'Print this help information', negatable: false);
+  return _argParser;
+}
+
 /**
  * Open and return the input stream specifying how this client
  * should interact with the analysis server.
@@ -79,57 +118,28 @@
   } else {
     inputRaw = new File(args.inputPath).openRead();
   }
-  args.srcPathMap.forEach((oldPath, newPath) {
-    logger.log(
-        Level.INFO, 'mapping source path\n  from $oldPath\n  to   $newPath');
-  });
+  for (PathMapEntry entry in args.srcPathMap.entries) {
+    logger.log(Level.INFO, 'mapping source path\n'
+        '  from ${entry.oldSrcPrefix}\n  to   ${entry.newSrcPrefix}');
+  }
   logger.log(Level.INFO, 'tmpSrcDir: ${args.tmpSrcDirPath}');
   return inputRaw
       .transform(SYSTEM_ENCODING.decoder)
       .transform(new LineSplitter())
-      .transform(new InputConverter(args.tmpSrcDirPath, args.srcPathMap,
-          diagnosticPort: args.diagnosticPort));
+      .transform(new InputConverter(args.tmpSrcDirPath, args.srcPathMap));
 }
 
 /**
  * Parse the command line arguments.
  */
 PerfArgs parseArgs(List<String> rawArgs) {
-  ArgParser parser = new ArgParser();
-
-  parser.addOption(INPUT_CMDLINE_OPTION, abbr: 'i', help: '<filePath>\n'
-      'The input file specifying how this client should interact with the server.\n'
-      'If the input file name is "stdin", then the instructions are read from standard input.');
-  parser.addOption(MAP_OPTION,
-      abbr: 'm',
-      allowMultiple: true,
-      splitCommas: false,
-      help: '<oldSrcPath>,<newSrcPath>\n'
-      'This option defines a mapping from the original source directory <oldSrcPath>\n'
-      'when the instrumentation or log file was generated\n'
-      'to the target source directory <newSrcPath> used during performance testing.\n'
-      'Multiple mappings can be specified.\n'
-      'WARNING: The contents of the target directory will be modified');
-  parser.addOption(TMP_SRC_DIR_OPTION, abbr: 't', help: '<dirPath>\n'
-      'The temporary directory containing source used during performance measurement.\n'
-      'WARNING: The contents of the target directory will be modified');
-  parser.addOption(DIAGNOSTIC_PORT_OPTION,
-      abbr: 'd',
-      help: 'localhost port on which server will provide diagnostic web pages');
-  parser.addFlag(VERBOSE_CMDLINE_OPTION,
-      abbr: 'v', help: 'Verbose logging', negatable: false);
-  parser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
-      help: 'Extra verbose logging', negatable: false);
-  parser.addFlag(HELP_CMDLINE_OPTION,
-      abbr: 'h', help: 'Print this help information', negatable: false);
-
   ArgResults args;
   PerfArgs perfArgs = new PerfArgs();
   try {
-    args = parser.parse(rawArgs);
+    args = argParser.parse(rawArgs);
   } on Exception catch (e) {
     print(e);
-    printHelp(parser);
+    printHelp();
     exit(1);
   }
 
@@ -143,15 +153,14 @@
     showHelp = true;
   }
 
-  perfArgs.srcPathMap = <String, String>{};
   for (String pair in args[MAP_OPTION]) {
     if (pair is String) {
       int index = pair.indexOf(',');
       if (index != -1 && pair.indexOf(',', index + 1) == -1) {
-        String oldSrcPath = _withTrailingSeparator(pair.substring(0, index));
-        String newSrcPath = _withTrailingSeparator(pair.substring(index + 1));
-        if (new Directory(newSrcPath).existsSync()) {
-          perfArgs.srcPathMap[oldSrcPath] = newSrcPath;
+        String oldSrcPrefix = _withTrailingSeparator(pair.substring(0, index));
+        String newSrcPrefix = _withTrailingSeparator(pair.substring(index + 1));
+        if (new Directory(newSrcPrefix).existsSync()) {
+          perfArgs.srcPathMap.add(oldSrcPrefix, newSrcPrefix);
           continue;
         }
       }
@@ -166,6 +175,8 @@
     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) {
@@ -183,18 +194,18 @@
   }
 
   if (showHelp) {
-    printHelp(parser);
+    printHelp();
     exit(1);
   }
 
   return perfArgs;
 }
 
-void printHelp(ArgParser parser) {
+void printHelp() {
   print('');
   print('Launch and interact with the AnalysisServer');
   print('');
-  print(parser.usage);
+  print(argParser.usage);
 }
 
 /**
@@ -226,7 +237,7 @@
    * when the instrumentation or log file was generated
    * to the target source directory used during performance testing.
    */
-  Map<String, String> srcPathMap;
+  final PathMap srcPathMap = new PathMap();
 
   /**
    * The temporary directory containing source used during performance measurement.
@@ -237,4 +248,9 @@
    * 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/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart
index f9ee62a..9e408d8 100644
--- a/pkg/analysis_server/benchmark/integration/operation.dart
+++ b/pkg/analysis_server/benchmark/integration/operation.dart
@@ -111,7 +111,7 @@
  * A [ResponseOperation] waits for a [JSON] response from the server.
  */
 class ResponseOperation extends Operation {
-  static final Duration responseTimeout = new Duration(seconds: 5);
+  static final Duration responseTimeout = new Duration(seconds: 60);
   final CommonInputConverter converter;
   final Map<String, dynamic> requestJson;
   final Map<String, dynamic> responseJson;
@@ -169,6 +169,7 @@
           'expected error:${format(expectedError)}\n'
           'but received:${format(actualResult)}';
       driver.results.recordUnexpectedResults(requestJson['method']);
+      converter.logOverlayContent();
       if (expectedError == null) {
         converter.logger.log(Level.SEVERE, message);
       } else {
@@ -179,13 +180,9 @@
 }
 
 class StartServerOperation extends Operation {
-  final int diagnosticPort;
-
-  StartServerOperation({this.diagnosticPort});
-
   @override
   Future perform(Driver driver) {
-    return driver.startServer(diagnosticPort: diagnosticPort);
+    return driver.startServer();
   }
 }
 
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 8d2995c..815a2d3 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -1575,6 +1575,7 @@
       
       
       
+      
     <h3>Requests</h3><dl><dt class="request"><a name="request_edit.format">edit.format</a> (<a href="#request_edit.format">#</a>)</dt><dd><div class="box"><pre>request: {
   "id": String
   "method": "edit.format"
@@ -1940,6 +1941,48 @@
               The file edit that is to be applied to the given file to effect
               the sorting.
             </p>
+          </dd></dl></dd><dt class="request"><a name="request_edit.organizeDirectives">edit.organizeDirectives</a> (<a href="#request_edit.organizeDirectives">#</a>)</dt><dd><div class="box"><pre>request: {
+  "id": String
+  "method": "edit.organizeDirectives"
+  "params": {
+    "<b>file</b>": <a href="#type_FilePath">FilePath</a>
+  }
+}</pre><br><pre>response: {
+  "id": String
+  "error": <span style="color:#999999">optional</span> <a href="#type_RequestError">RequestError</a>
+  "result": {
+    "<b>edit</b>": <a href="#type_SourceFileEdit">SourceFileEdit</a>
+  }
+}</pre></div>
+        <p>
+          Organizes all of the directives - removes unused imports and sorts
+          directives of the given Dart file according to the
+          <a href="https://www.dartlang.org/articles/style-guide/">Dart Style Guide</a>.
+        </p>
+        <p>
+          If a request is made for a file that does not exist, does not belong
+          to an analysis root or is not a Dart file,
+          <tt>FILE_NOT_ANALYZED</tt> will be generated.
+        </p>
+        <p>
+          If directives of the Dart file cannot be organized, for example
+          because it has scan or parse errors, or by other reasons,
+          <tt>ORGANIZE_DIRECTIVES_ERROR</tt> will be generated. The message
+          will provide datails about the reason.
+        </p>
+        
+        
+      <h4>Parameters</h4><dl><dt class="field"><b><i>file ( <a href="#type_FilePath">FilePath</a> )</i></b></dt><dd>
+            
+            <p>
+              The Dart file to organize directives in.
+            </p>
+          </dd></dl><h4>Returns</h4><dl><dt class="field"><b><i>edit ( <a href="#type_SourceFileEdit">SourceFileEdit</a> )</i></b></dt><dd>
+            
+            <p>
+              The file edit that is to be applied to the given file to effect
+              the organizing.
+            </p>
           </dd></dl></dd></dl>
     <h2 class="domain"><a name="domain_execution">Domain: execution</a></h2>
       <p>
@@ -2289,27 +2332,28 @@
         
       <dl><dt class="field"><b><i>enableAsync ( <span style="color:#999999">optional</span> bool )</i></b></dt><dd>
             
-            <p><b><i>Deprecated</i></b></p>
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed async feature.
             </p>
           </dd><dt class="field"><b><i>enableDeferredLoading ( <span style="color:#999999">optional</span> bool )</i></b></dt><dd>
             
-            <p><b><i>Deprecated</i></b></p>
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed deferred loading feature.
             </p>
           </dd><dt class="field"><b><i>enableEnums ( <span style="color:#999999">optional</span> bool )</i></b></dt><dd>
             
-            <p><b><i>Deprecated</i></b></p>
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed enum feature.
             </p>
           </dd><dt class="field"><b><i>enableNullAwareOperators ( <span style="color:#999999">optional</span> bool )</i></b></dt><dd>
             
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed "null aware operators" feature.
@@ -3359,6 +3403,13 @@
               not be satisfied because the content of the file changed before
               the requested results could be computed.
             </p>
+          </dd><dt class="value">FILE_NOT_ANALYZED</dt><dd>
+            
+            <p>
+              A request specified a FilePath which does not match a file in
+              an analysis root, or the requested operation is not available
+              for the file.
+            </p>
           </dd><dt class="value">FORMAT_INVALID_FILE</dt><dd>
             
             <p>
@@ -3381,7 +3432,7 @@
           </dd><dt class="value">GET_NAVIGATION_INVALID_FILE</dt><dd>
             
             <p>
-              An "analysis.getErrors" request specified a FilePath
+              An "analysis.getNavigation" request specified a FilePath
               which does not match a file currently subject to
               analysis.
             </p>
@@ -3421,6 +3472,12 @@
               The "--no-index" flag was passed when the analysis server created,
               but this API call requires an index to have been generated.
             </p>
+          </dd><dt class="value">ORGANIZE_DIRECTIVES_ERROR</dt><dd>
+            
+            <p>
+              An "edit.organizeDirectives" request specified a Dart file that
+              cannot be analyzed. The reason is described in the message.
+            </p>
           </dd><dt class="value">REFACTORING_REQUEST_CANCELLED</dt><dd>
             
             <p>
diff --git a/pkg/analysis_server/lib/edit/fix/fix_core.dart b/pkg/analysis_server/lib/edit/fix/fix_core.dart
index f546198..f38d59a 100644
--- a/pkg/analysis_server/lib/edit/fix/fix_core.dart
+++ b/pkg/analysis_server/lib/edit/fix/fix_core.dart
@@ -5,6 +5,7 @@
 library analysis_server.edit.fix.fix_core;
 
 import 'package:analysis_server/src/protocol.dart' show SourceChange;
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 
@@ -24,7 +25,8 @@
    * relevant fixes will be sorted before fixes with a lower relevance.
    */
   static final Comparator<Fix> SORT_BY_RELEVANCE = (Fix firstFix,
-      Fix secondFix) => firstFix.kind.relevance - secondFix.kind.relevance;
+          Fix secondFix) =>
+      firstFix.kind.relevance - secondFix.kind.relevance;
 
   /**
    * A description of the fix being proposed.
@@ -59,7 +61,8 @@
    * Return a list of fixes for the given [error]. The error was reported
    * after it's source was analyzed in the given [context].
    */
-  List<Fix> computeFixes(AnalysisContext context, AnalysisError error);
+  List<Fix> computeFixes(ResourceProvider resourceProvider,
+      AnalysisContext context, AnalysisError error);
 }
 
 /**
diff --git a/pkg/analysis_server/lib/edit/fix/fix_dart.dart b/pkg/analysis_server/lib/edit/fix/fix_dart.dart
index 0e559e4..c009e68 100644
--- a/pkg/analysis_server/lib/edit/fix/fix_dart.dart
+++ b/pkg/analysis_server/lib/edit/fix/fix_dart.dart
@@ -5,6 +5,7 @@
 library analysis_server.edit.fix.fix_dart;
 
 import 'package:analysis_server/edit/fix/fix_core.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -18,7 +19,8 @@
  */
 abstract class DartFixContributor extends FixContributor {
   @override
-  List<Fix> computeFixes(AnalysisContext context, AnalysisError error) {
+  List<Fix> computeFixes(ResourceProvider resourceProvider,
+      AnalysisContext context, AnalysisError error) {
     Source source = error.source;
     if (!AnalysisEngine.isDartFileName(source.fullName)) {
       return Fix.EMPTY_LIST;
@@ -32,12 +34,13 @@
     if (unit == null) {
       return Fix.EMPTY_LIST;
     }
-    return internalComputeFixes(unit, error);
+    return internalComputeFixes(resourceProvider, unit, error);
   }
 
   /**
    * Return a list of fixes for the given [error]. The error was reported
    * against the given compilation [unit].
    */
-  List<Fix> internalComputeFixes(CompilationUnit unit, AnalysisError error);
+  List<Fix> internalComputeFixes(ResourceProvider resourceProvider,
+      CompilationUnit unit, AnalysisError error);
 }
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 57fd203..21a0f7e 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -21,12 +21,10 @@
 import 'package:analysis_server/src/services/correction/namespace.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
 import 'package:analysis_server/uri/resolver_provider.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
-import 'package:analyzer/source/sdk_ext.dart';
+import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -35,7 +33,6 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:package_config/packages.dart';
 import 'package:plugin/plugin.dart';
 
 typedef void OptionUpdater(AnalysisOptionsImpl options);
@@ -117,7 +114,7 @@
    * The [ContextManager] that handles the mapping from analysis roots to
    * context directories.
    */
-  ServerContextManager contextManager;
+  ContextManager contextManager;
 
   /**
    * A flag indicating whether the server is running.  When false, contexts
@@ -272,6 +269,17 @@
   Set<String> prevAnalyzedFiles;
 
   /**
+   * The default options used to create new analysis contexts.
+   */
+  AnalysisOptionsImpl defaultContextOptions = new AnalysisOptionsImpl();
+
+  /**
+   * The controller for sending [ContextsChangedEvent]s.
+   */
+  StreamController<ContextsChangedEvent> _onContextsChangedController =
+      new StreamController<ContextsChangedEvent>.broadcast();
+
+  /**
    * Initialize a newly created server to receive requests from and send
    * responses to the given [channel].
    *
@@ -284,9 +292,9 @@
    * running a full analysis server.
    */
   AnalysisServer(this.channel, this.resourceProvider,
-      OptimizingPubPackageMapProvider packageMapProvider, Index _index,
-      this.serverPlugin, this.options, this.defaultSdk,
-      this.instrumentationService, {ContextManager contextManager: null,
+      PubPackageMapProvider packageMapProvider, Index _index, this.serverPlugin,
+      this.options, this.defaultSdk, this.instrumentationService,
+      {ContextManager contextManager: null,
       ResolverProvider packageResolverProvider: null,
       this.rethrowExceptions: true})
       : index = _index,
@@ -294,20 +302,18 @@
     _performance = performanceDuringStartup;
     operationQueue = new ServerOperationQueue();
     if (contextManager == null) {
-      contextManager = new ServerContextManager(this, resourceProvider,
+      contextManager = new ContextManagerImpl(resourceProvider,
           packageResolverProvider, packageMapProvider, instrumentationService);
-      AnalysisOptionsImpl analysisOptions =
-          (contextManager as ServerContextManager).defaultOptions;
-      analysisOptions.incremental = true;
-      analysisOptions.incrementalApi = options.enableIncrementalResolutionApi;
-      analysisOptions.incrementalValidation =
-          options.enableIncrementalResolutionValidation;
-      analysisOptions.generateImplicitErrors = false;
-    } else if (contextManager is! ServerContextManager) {
-      // TODO(brianwilkerson) Remove this when the interface is complete.
-      throw new StateError(
-          'The contextManager must be an instance of ServerContextManager');
     }
+    ServerContextManagerCallbacks contextManagerCallbacks =
+        new ServerContextManagerCallbacks(this, resourceProvider);
+    contextManager.callbacks = contextManagerCallbacks;
+    defaultContextOptions.incremental = true;
+    defaultContextOptions.incrementalApi =
+        options.enableIncrementalResolutionApi;
+    defaultContextOptions.incrementalValidation =
+        options.enableIncrementalResolutionValidation;
+    defaultContextOptions.generateImplicitErrors = false;
     this.contextManager = contextManager;
     _noErrorNotification = options.noErrorNotification;
     AnalysisEngine.instance.logger = new AnalysisLogger();
@@ -353,7 +359,7 @@
    * The stream that is notified when contexts are added or removed.
    */
   Stream<ContextsChangedEvent> get onContextsChanged =>
-      contextManager.onContextsChanged;
+      _onContextsChangedController.stream;
 
   /**
    * The stream that is notified when a single file has been analyzed.
@@ -497,15 +503,14 @@
     {
       AnalysisContext containingContext = getContainingContext(path);
       if (containingContext != null) {
-        Source source = AbstractContextManager.createSourceInContext(
-            containingContext, file);
+        Source source =
+            ContextManagerImpl.createSourceInContext(containingContext, file);
         return new ContextSourcePair(containingContext, source);
       }
     }
     // try to find a context that analysed the file
     for (AnalysisContext context in folderMap.values) {
-      Source source =
-          AbstractContextManager.createSourceInContext(context, file);
+      Source source = ContextManagerImpl.createSourceInContext(context, file);
       SourceKind kind = context.getKindOf(source);
       if (kind != SourceKind.UNKNOWN) {
         return new ContextSourcePair(context, source);
@@ -1025,8 +1030,8 @@
             Uri uri = context.sourceFactory.restoreUri(source);
             if (uri.scheme != 'file') {
               preferredContext = context;
-              source = AbstractContextManager.createSourceInContext(
-                  context, resource);
+              source =
+                  ContextManagerImpl.createSourceInContext(context, resource);
               break;
             }
           }
@@ -1226,15 +1231,14 @@
     //
     // Update the defaults used to create new contexts.
     //
-    AnalysisOptionsImpl options = contextManager.defaultOptions;
     optionUpdaters.forEach((OptionUpdater optionUpdater) {
-      optionUpdater(options);
+      optionUpdater(defaultContextOptions);
     });
   }
 
   /**
-   * Return a set of contexts containing all of the resources in the given list
-   * of [resources].
+   * Return a set of all contexts whose associated folder is contained within,
+   * or equal to, one of the resources in the given list of [resources].
    */
   Set<AnalysisContext> _getContexts(List<Resource> resources) {
     Set<AnalysisContext> contexts = new HashSet<AnalysisContext>();
@@ -1337,45 +1341,26 @@
   PriorityChangeEvent(this.firstSource);
 }
 
-class ServerContextManager extends AbstractContextManager {
+class ServerContextManagerCallbacks extends ContextManagerCallbacks {
   final AnalysisServer analysisServer;
 
   /**
-   * The default options used to create new analysis contexts.
+   * The [ResourceProvider] by which paths are converted into [Resource]s.
    */
-  AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
+  final ResourceProvider resourceProvider;
 
-  /**
-   * The controller for sending [ContextsChangedEvent]s.
-   */
-  StreamController<ContextsChangedEvent> _onContextsChangedController;
-
-  ServerContextManager(this.analysisServer, ResourceProvider resourceProvider,
-      ResolverProvider packageResolverProvider,
-      OptimizingPubPackageMapProvider packageMapProvider,
-      InstrumentationService service)
-      : super(resourceProvider, packageResolverProvider, packageMapProvider,
-          service) {
-    _onContextsChangedController =
-        new StreamController<ContextsChangedEvent>.broadcast();
-  }
-
-  /**
-   * The stream that is notified when contexts are added or removed.
-   */
-  Stream<ContextsChangedEvent> get onContextsChanged =>
-      _onContextsChangedController.stream;
+  ServerContextManagerCallbacks(this.analysisServer, this.resourceProvider);
 
   @override
-  AnalysisContext addContext(
-      Folder folder, UriResolver packageUriResolver, Packages packages) {
+  AnalysisContext addContext(Folder folder, FolderDisposition disposition) {
     InternalAnalysisContext context =
         AnalysisEngine.instance.createAnalysisContext();
     context.contentCache = analysisServer.overlayState;
     analysisServer.folderMap[folder] = context;
-    context.sourceFactory = _createSourceFactory(packageUriResolver, packages);
-    context.analysisOptions = new AnalysisOptionsImpl.from(defaultOptions);
-    _onContextsChangedController
+    context.sourceFactory = _createSourceFactory(disposition);
+    context.analysisOptions =
+        new AnalysisOptionsImpl.from(analysisServer.defaultContextOptions);
+    analysisServer._onContextsChangedController
         .add(new ContextsChangedEvent(added: [context]));
     analysisServer.schedulePerformAnalysisOperation(context);
     return context;
@@ -1406,20 +1391,15 @@
   }
 
   @override
-  void removeContext(Folder folder) {
+  void removeContext(Folder folder, List<String> flushedFiles) {
     AnalysisContext context = analysisServer.folderMap.remove(folder);
-
-    // See dartbug.com/22689, the AnalysisContext is computed in
-    // computeFlushedFiles instead of using the referenced context above, this
-    // is an attempt to be careful concerning the referenced issue.
-    List<String> flushedFiles = computeFlushedFiles(folder);
     sendAnalysisNotificationFlushResults(analysisServer, flushedFiles);
 
     if (analysisServer.index != null) {
       analysisServer.index.removeContext(context);
     }
     analysisServer.operationQueue.contextRemoved(context);
-    _onContextsChangedController
+    analysisServer._onContextsChangedController
         .add(new ContextsChangedEvent(removed: [context]));
     analysisServer.sendContextAnalysisDoneNotifications(
         context, AnalysisDoneReason.CONTEXT_REMOVED);
@@ -1446,10 +1426,10 @@
 
   @override
   void updateContextPackageUriResolver(
-      Folder contextFolder, UriResolver packageUriResolver, Packages packages) {
+      Folder contextFolder, FolderDisposition disposition) {
     AnalysisContext context = analysisServer.folderMap[contextFolder];
-    context.sourceFactory = _createSourceFactory(packageUriResolver, packages);
-    _onContextsChangedController
+    context.sourceFactory = _createSourceFactory(disposition);
+    analysisServer._onContextsChangedController
         .add(new ContextsChangedEvent(changed: [context]));
     analysisServer.schedulePerformAnalysisOperation(context);
   }
@@ -1463,25 +1443,17 @@
   }
 
   /**
-   * Set up a [SourceFactory] that resolves packages using the given
-   * [packageUriResolver] and [packages] resolution strategy.
+   * Set up a [SourceFactory] that resolves packages as appropriate for the
+   * given [disposition].
    */
-  SourceFactory _createSourceFactory(
-      UriResolver packageUriResolver, Packages packages) {
+  SourceFactory _createSourceFactory(FolderDisposition disposition) {
     UriResolver dartResolver = new DartUriResolver(analysisServer.defaultSdk);
     UriResolver resourceResolver = new ResourceUriResolver(resourceProvider);
     List<UriResolver> resolvers = [];
     resolvers.add(dartResolver);
-    if (packageUriResolver is PackageMapUriResolver) {
-      UriResolver sdkExtResolver =
-          new SdkExtUriResolver(packageUriResolver.packageMap);
-      resolvers.add(sdkExtResolver);
-    }
-    if (packageUriResolver != null) {
-      resolvers.add(packageUriResolver);
-    }
+    resolvers.addAll(disposition.createPackageUriResolvers(resourceProvider));
     resolvers.add(resourceResolver);
-    return new SourceFactory(resolvers, packages);
+    return new SourceFactory(resolvers, disposition.packages);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/constants.dart b/pkg/analysis_server/lib/src/constants.dart
index b4acd97..f37446b 100644
--- a/pkg/analysis_server/lib/src/constants.dart
+++ b/pkg/analysis_server/lib/src/constants.dart
@@ -79,6 +79,7 @@
 const String EDIT_GET_AVAILABLE_REFACTORINGS = 'edit.getAvailableRefactorings';
 const String EDIT_GET_FIXES = 'edit.getFixes';
 const String EDIT_GET_REFACTORING = 'edit.getRefactoring';
+const String EDIT_ORGANIZE_DIRECTIVES = 'edit.organizeDirectives';
 const String EDIT_SORT_MEMBERS = 'edit.sortMembers';
 
 //
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index fb1c3b4..41fb266 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -10,13 +10,15 @@
 import 'dart:core' hide Resource;
 
 import 'package:analysis_server/src/analysis_server.dart';
-import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
+import 'package:analysis_server/src/server_options.dart';
 import 'package:analysis_server/uri/resolver_provider.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/source/path_filter.dart';
+import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -29,15 +31,287 @@
 import 'package:yaml/yaml.dart';
 
 /**
+ * Information tracked by the [ContextManager] for each context.
+ */
+class ContextInfo {
+  /**
+   * The [ContextManager] which is tracking this information.
+   */
+  final ContextManagerImpl contextManager;
+
+  /**
+   * The [Folder] for which this information object is created.
+   */
+  final Folder folder;
+
+  /// The [PathFilter] used to filter sources from being analyzed.
+  final PathFilter pathFilter;
+
+  /**
+   * The enclosed pubspec-based contexts.
+   */
+  final List<ContextInfo> children = <ContextInfo>[];
+
+  /**
+   * The package root for this context, or null if there is no package root.
+   */
+  String packageRoot;
+
+  /**
+   * The [ContextInfo] that encloses this one, or `null` if this is the virtual
+   * [ContextInfo] object that acts as the ancestor of all other [ContextInfo]
+   * objects.
+   */
+  ContextInfo parent;
+
+  /**
+   * The package description file path for this context.
+   */
+  String packageDescriptionPath;
+
+  /**
+   * Paths to files which determine the folder disposition and package map.
+   *
+   * TODO(paulberry): if any of these files are outside of [folder], they won't
+   * be watched for changes.  I believe the use case for watching these files
+   * is no longer relevant.
+   */
+  Set<String> _dependencies = new Set<String>();
+
+  /**
+   * The analysis context that was created for the [folder].
+   */
+  AnalysisContext context;
+
+  /**
+   * Map from full path to the [Source] object, for each source that has been
+   * added to the context.
+   */
+  Map<String, Source> sources = new HashMap<String, Source>();
+
+  ContextInfo(ContextManagerImpl contextManager, this.parent, Folder folder,
+      File packagespecFile, this.packageRoot)
+      : contextManager = contextManager,
+        folder = folder,
+        pathFilter = new PathFilter(
+            contextManager.resourceProvider.pathContext, folder.path, null) {
+    packageDescriptionPath = packagespecFile.path;
+    parent.children.add(this);
+  }
+
+  /**
+   * Create the virtual [ContextInfo] which acts as an ancestor to all other
+   * [ContextInfo]s.
+   */
+  ContextInfo._root()
+      : contextManager = null,
+        folder = null,
+        pathFilter = null;
+
+  /**
+   * Iterate through all [children] and their children, recursively.
+   */
+  Iterable<ContextInfo> get descendants sync* {
+    for (ContextInfo child in children) {
+      yield child;
+      yield* child.descendants;
+    }
+  }
+
+  /**
+   * Returns `true` if this is a "top level" context, meaning that the folder
+   * associated with it is not contained within any other folders that have an
+   * associated context.
+   */
+  bool get isTopLevel => parent.parent == null;
+
+  /**
+   * Returns `true` if [path] is excluded, as it is in one of the children.
+   */
+  bool excludes(String path) {
+    return children.any((child) {
+      return child.folder.contains(path);
+    });
+  }
+
+  /**
+   * Returns `true` if [resource] is excluded, as it is in one of the children.
+   */
+  bool excludesResource(Resource resource) => excludes(resource.path);
+
+  /**
+   * Return the first [ContextInfo] in [children] whose associated folder is or
+   * contains [path].  If there is no such [ContextInfo], return `null`.
+   */
+  ContextInfo findChildInfoFor(String path) {
+    for (ContextInfo info in children) {
+      if (info.folder.isOrContains(path)) {
+        return info;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Determine if the given [path] is one of the dependencies most recently
+   * passed to [setDependencies].
+   */
+  bool hasDependency(String path) => _dependencies.contains(path);
+
+  /// Returns `true` if  [path] should be ignored.
+  bool ignored(String path) => pathFilter.ignored(path);
+
+  /**
+   * Returns `true` if [path] is the package description file for this context
+   * (pubspec.yaml or .packages).
+   */
+  bool isPathToPackageDescription(String path) =>
+      path == packageDescriptionPath;
+
+  /**
+   * Update the set of dependencies for this context.
+   */
+  void setDependencies(Iterable<String> newDependencies) {
+    _dependencies = newDependencies.toSet();
+  }
+}
+
+/**
  * Class that maintains a mapping from included/excluded paths to a set of
  * folders that should correspond to analysis contexts.
  */
-abstract class AbstractContextManager implements ContextManager {
+abstract class ContextManager {
+  // TODO(brianwilkerson) Support:
+  //   setting the default analysis options
+  //   setting the default content cache
+  //   setting the default SDK
+  //   maintaining AnalysisContext.folderMap (or remove it)
+  //   telling server when a context has been added or removed (see onContextsChanged)
+  //   telling server when a context needs to be re-analyzed
+  //   notifying the client when results should be flushed
+  //   using analyzeFileFunctions to determine which files to analyze
+  //
+  // TODO(brianwilkerson) Move this class to a public library.
 
   /**
+   * Get the callback interface used to create, destroy, and update contexts.
+   */
+  ContextManagerCallbacks get callbacks;
+
+  /**
+   * Set the callback interface used to create, destroy, and update contexts.
+   */
+  void set callbacks(ContextManagerCallbacks value);
+
+  /**
+   * Return the list of excluded paths (folders and files) most recently passed
+   * to [setRoots].
+   */
+  List<String> get excludedPaths;
+
+  /**
+   * Return the list of included paths (folders and files) most recently passed
+   * to [setRoots].
+   */
+  List<String> get includedPaths;
+
+  /**
+   * Return a list of all of the contexts reachable from the given
+   * [analysisRoot] (the context associated with [analysisRoot] and all of its
+   * descendants).
+   */
+  List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot);
+
+  /**
+   * Return `true` if the given absolute [path] is in one of the current
+   * root folders and is not excluded.
+   */
+  bool isInAnalysisRoot(String path);
+
+  /**
+   * Rebuild the set of contexts from scratch based on the data last sent to
+   * [setRoots]. Only contexts contained in the given list of analysis [roots]
+   * will be rebuilt, unless the list is `null`, in which case every context
+   * will be rebuilt.
+   */
+  void refresh(List<Resource> roots);
+
+  /**
+   * Change the set of paths which should be used as starting points to
+   * determine the context directories.
+   */
+  void setRoots(List<String> includedPaths, List<String> excludedPaths,
+      Map<String, String> packageRoots);
+}
+
+/**
+ * Callback interface used by [ContextManager] to (a) request that contexts be
+ * created, destroyed or updated, (b) inform the client when "pub list"
+ * operations are in progress, and (c) determine which files should be
+ * analyzed.
+ *
+ * TODO(paulberry): eliminate this interface, and instead have [ContextManager]
+ * operations return data structures describing how context state should be
+ * modified.
+ */
+abstract class ContextManagerCallbacks {
+  /**
+   * Create and return a new analysis context, allowing [disposition] to govern
+   * details of how the context is to be created.
+   */
+  AnalysisContext addContext(Folder folder, FolderDisposition disposition);
+
+  /**
+   * Called when the set of files associated with a context have changed (or
+   * some of those files have been modified).  [changeSet] is the set of
+   * changes that need to be applied to the context.
+   */
+  void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
+
+  /**
+   * Called when the ContextManager is about to start computing the package
+   * map.
+   */
+  void beginComputePackageMap() {
+    // By default, do nothing.
+  }
+
+  /**
+   * Called when the ContextManager has finished computing the package map.
+   */
+  void endComputePackageMap() {
+    // By default, do nothing.
+  }
+
+  /**
+   * Remove the context associated with the given [folder].  [flushedFiles] is
+   * a list of the files which will be "orphaned" by removing this context
+   * (they will no longer be analyzed by any context).
+   */
+  void removeContext(Folder folder, List<String> flushedFiles);
+
+  /**
+   * Return `true` if the given [file] should be analyzed.
+   */
+  bool shouldFileBeAnalyzed(File file);
+
+  /**
+   * Called when the disposition for a context has changed.
+   */
+  void updateContextPackageUriResolver(
+      Folder contextFolder, FolderDisposition disposition);
+}
+
+/**
+ * Class that maintains a mapping from included/excluded paths to a set of
+ * folders that should correspond to analysis contexts.
+ */
+class ContextManagerImpl implements ContextManager {
+  /**
    * Temporary flag to hide WIP .packages support (DEP 5).
    */
-  static bool ENABLE_PACKAGESPEC_SUPPORT = false;
+  static bool ENABLE_PACKAGESPEC_SUPPORT = serverOptions.isSet(
+      'ContextManagerImpl.ENABLE_PACKAGESPEC_SUPPORT', defaultValue: true);
 
   /**
    * The name of the `lib` directory.
@@ -60,12 +334,6 @@
   static const String PACKAGE_SPEC_NAME = '.packages';
 
   /**
-   * [_ContextInfo] object for each included directory in the most
-   * recent successful call to [setRoots].
-   */
-  Map<Folder, _ContextInfo> _contexts = new HashMap<Folder, _ContextInfo>();
-
-  /**
    * The [ResourceProvider] using which paths are converted into [Resource]s.
    */
   final ResourceProvider resourceProvider;
@@ -109,7 +377,7 @@
    * Provider which is used to determine the mapping from package name to
    * package folder.
    */
-  final OptimizingPubPackageMapProvider _packageMapProvider;
+  final PubPackageMapProvider _packageMapProvider;
 
   /// Provider of analysis options.
   AnalysisOptionsProvider analysisOptionsProvider =
@@ -120,70 +388,59 @@
    */
   final InstrumentationService _instrumentationService;
 
-  AbstractContextManager(this.resourceProvider, this.packageResolverProvider,
+  @override
+  ContextManagerCallbacks callbacks;
+
+  /**
+   * Virtual [ContextInfo] which acts as the ancestor of all other
+   * [ContextInfo]s.
+   */
+  final ContextInfo _rootInfo = new ContextInfo._root();
+
+  /**
+   * Stream subscription we are using to watch each analysis root directory for
+   * changes.
+   */
+  final Map<Folder, StreamSubscription<WatchEvent>> _changeSubscriptions =
+      <Folder, StreamSubscription<WatchEvent>>{};
+
+  ContextManagerImpl(this.resourceProvider, this.packageResolverProvider,
       this._packageMapProvider, this._instrumentationService) {
     pathContext = resourceProvider.pathContext;
   }
 
-  /**
-   * Create and return a new analysis context.
-   */
-  AnalysisContext addContext(
-      Folder folder, UriResolver packageUriResolver, Packages packages);
-
-  /**
-   * Called when the set of files associated with a context have changed (or
-   * some of those files have been modified).  [changeSet] is the set of
-   * changes that need to be applied to the context.
-   */
-  void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
-
-  /**
-   * We are about to start computing the package map.
-   */
-  void beginComputePackageMap() {
-    // Do nothing.
-  }
-
-  /**
-   * Compute the set of files that are being flushed, this is defined as
-   * the set of sources in the removed context (context.sources), that are
-   * orphaned by this context being removed (no other context includes this
-   * file.)
-   */
-  List<String> computeFlushedFiles(Folder folder) {
-    AnalysisContext context = _contexts[folder].context;
-    HashSet<String> flushedFiles = new HashSet<String>();
-    for (Source source in context.sources) {
-      flushedFiles.add(source.fullName);
-    }
-    for (_ContextInfo contextInfo in _contexts.values) {
-      AnalysisContext contextN = contextInfo.context;
-      if (context != contextN) {
-        for (Source source in contextN.sources) {
-          flushedFiles.remove(source.fullName);
-        }
-      }
-    }
-    return flushedFiles.toList(growable: false);
-  }
-
   @override
   List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot) {
     List<AnalysisContext> contexts = <AnalysisContext>[];
-    _contexts.forEach((Folder contextFolder, _ContextInfo info) {
-      if (analysisRoot.isOrContains(contextFolder.path)) {
-        contexts.add(info.context);
+    ContextInfo innermostContainingInfo =
+        _getInnermostContextInfoFor(analysisRoot.path);
+    void addContextAndDescendants(ContextInfo info) {
+      contexts.add(info.context);
+      info.children.forEach(addContextAndDescendants);
+    }
+    if (innermostContainingInfo != null) {
+      if (analysisRoot == innermostContainingInfo.folder) {
+        addContextAndDescendants(innermostContainingInfo);
+      } else {
+        for (ContextInfo info in innermostContainingInfo.children) {
+          if (analysisRoot.isOrContains(info.folder.path)) {
+            addContextAndDescendants(info);
+          }
+        }
       }
-    });
+    }
     return contexts;
   }
 
   /**
-   * We have finished computing the package map.
+   * For testing: get the [ContextInfo] object for the given [folder], if any.
    */
-  void endComputePackageMap() {
-    // Do nothing.
+  ContextInfo getContextInfoFor(Folder folder) {
+    ContextInfo info = _getInnermostContextInfoFor(folder.path);
+    if (folder == info.folder) {
+      return info;
+    }
+    return null;
   }
 
   @override
@@ -192,9 +449,9 @@
     if (_isExcluded(path)) {
       return false;
     }
-    // check if in of the roots
-    for (Folder root in _contexts.keys) {
-      if (root.contains(path)) {
+    // check if in one of the roots
+    for (ContextInfo info in _rootInfo.children) {
+      if (info.folder.contains(path)) {
         return true;
       }
     }
@@ -202,12 +459,11 @@
     return false;
   }
 
-  /// Process [options] for the context [folder].
-  void processOptionsForContext(Folder folder, Map<String, YamlNode> options) {
-    _ContextInfo info = _contexts[folder];
-    if (info == null) {
-      return;
-    }
+  /**
+   * Process [options] for the context having info [info].
+   */
+  void processOptionsForContext(
+      ContextInfo info, Map<String, YamlNode> options) {
     YamlMap analyzer = options['analyzer'];
     if (analyzer == null) {
       // No options for analyzer.
@@ -217,21 +473,22 @@
     // Set ignore patterns.
     YamlList exclude = analyzer['exclude'];
     if (exclude != null) {
-      setIgnorePatternsForContext(folder, exclude);
+      setIgnorePatternsForContext(info, exclude);
     }
   }
 
   @override
   void refresh(List<Resource> roots) {
     // Destroy old contexts
-    List<Folder> contextFolders = _contexts.keys.toList();
+    List<ContextInfo> contextInfos = _rootInfo.descendants.toList();
     if (roots == null) {
-      contextFolders.forEach(_destroyContext);
+      contextInfos.forEach(_destroyContext);
     } else {
       roots.forEach((Resource resource) {
-        contextFolders.forEach((Folder contextFolder) {
-          if (resource is Folder && resource.isOrContains(contextFolder.path)) {
-            _destroyContext(contextFolder);
+        contextInfos.forEach((ContextInfo contextInfo) {
+          if (resource is Folder &&
+              resource.isOrContains(contextInfo.folder.path)) {
+            _destroyContext(contextInfo);
           }
         });
       });
@@ -242,18 +499,11 @@
   }
 
   /**
-   * Remove the context associated with the given [folder].
+   * Sets the [ignorePatterns] for the context having info [info].
    */
-  void removeContext(Folder folder);
-
-  /// Sets the [ignorePatterns] for the context [folder].
-  void setIgnorePatternsForContext(Folder folder, List<String> ignorePatterns) {
-    _ContextInfo info = _contexts[folder];
-    if (info == null) {
-      return;
-    }
-    var pathFilter = info.pathFilter;
-    pathFilter.setIgnorePatterns(ignorePatterns);
+  void setIgnorePatternsForContext(
+      ContextInfo info, List<String> ignorePatterns) {
+    info.pathFilter.setIgnorePatterns(ignorePatterns);
   }
 
   @override
@@ -271,7 +521,7 @@
       }
     });
 
-    List<Folder> contextFolders = _contexts.keys.toList();
+    List<ContextInfo> contextInfos = _rootInfo.descendants.toList();
     // included
     Set<Folder> includedFolders = new HashSet<Folder>();
     for (int i = 0; i < includedPaths.length; i++) {
@@ -290,33 +540,35 @@
     List<String> oldExcludedPaths = this.excludedPaths;
     this.excludedPaths = excludedPaths;
     // destroy old contexts
-    for (Folder contextFolder in contextFolders) {
+    for (ContextInfo contextInfo in contextInfos) {
       bool isIncluded = includedFolders.any((folder) {
-        return folder.isOrContains(contextFolder.path);
+        return folder.isOrContains(contextInfo.folder.path);
       });
       if (!isIncluded) {
-        _destroyContext(contextFolder);
+        _destroyContext(contextInfo);
       }
     }
     // Update package roots for existing contexts
-    _contexts.forEach((Folder folder, _ContextInfo info) {
-      String newPackageRoot = normalizedPackageRoots[folder.path];
+    for (ContextInfo info in _rootInfo.descendants) {
+      String newPackageRoot = normalizedPackageRoots[info.folder.path];
       if (info.packageRoot != newPackageRoot) {
         info.packageRoot = newPackageRoot;
-        _recomputePackageUriResolver(info);
+        _recomputeFolderDisposition(info);
       }
-    });
+    }
     // create new contexts
     for (Folder includedFolder in includedFolders) {
-      bool wasIncluded = contextFolders.any((folder) {
-        return folder.isOrContains(includedFolder.path);
+      bool wasIncluded = contextInfos.any((info) {
+        return info.folder.isOrContains(includedFolder.path);
       });
       if (!wasIncluded) {
-        _createContexts(includedFolder, false);
+        _changeSubscriptions[includedFolder] =
+            includedFolder.changes.listen(_handleWatchEvent);
+        _createContexts(_rootInfo, includedFolder, false);
       }
     }
     // remove newly excluded sources
-    _contexts.forEach((folder, info) {
+    for (ContextInfo info in _rootInfo.descendants) {
       // prepare excluded sources
       Map<String, Source> excludedSources = new HashMap<String, Source>();
       info.sources.forEach((String path, Source source) {
@@ -331,31 +583,21 @@
         info.sources.remove(path);
         changeSet.removedSource(source);
       });
-      applyChangesToContext(folder, changeSet);
-    });
+      callbacks.applyChangesToContext(info.folder, changeSet);
+    }
     // add previously excluded sources
-    _contexts.forEach((folder, info) {
+    for (ContextInfo info in _rootInfo.descendants) {
       ChangeSet changeSet = new ChangeSet();
-      _addPreviouslyExcludedSources(info, changeSet, folder, oldExcludedPaths);
-      applyChangesToContext(folder, changeSet);
-    });
+      _addPreviouslyExcludedSources(
+          info, changeSet, info.folder, oldExcludedPaths);
+      callbacks.applyChangesToContext(info.folder, changeSet);
+    }
   }
 
   /**
-   * Return `true` if the given [file] should be analyzed.
-   */
-  bool shouldFileBeAnalyzed(File file);
-
-  /**
-   * Called when the package map for a context has changed.
-   */
-  void updateContextPackageUriResolver(
-      Folder contextFolder, UriResolver packageUriResolver, Packages packages);
-
-  /**
    * Resursively adds all Dart and HTML files to the [changeSet].
    */
-  void _addPreviouslyExcludedSources(_ContextInfo info, ChangeSet changeSet,
+  void _addPreviouslyExcludedSources(ContextInfo info, ChangeSet changeSet,
       Folder folder, List<String> oldExcludedPaths) {
     if (info.excludesResource(folder)) {
       return;
@@ -377,7 +619,7 @@
       // add files, recurse into folders
       if (child is File) {
         // ignore if should not be analyzed at all
-        if (!shouldFileBeAnalyzed(child)) {
+        if (!callbacks.shouldFileBeAnalyzed(child)) {
           continue;
         }
         // ignore if was not excluded
@@ -402,7 +644,7 @@
   /**
    * Resursively adds all Dart and HTML files to the [changeSet].
    */
-  void _addSourceFiles(ChangeSet changeSet, Folder folder, _ContextInfo info) {
+  void _addSourceFiles(ChangeSet changeSet, Folder folder, ContextInfo info) {
     if (info.excludesResource(folder) || folder.shortName.startsWith('.')) {
       return;
     }
@@ -422,7 +664,7 @@
       }
       // add files, recurse into folders
       if (child is File) {
-        if (shouldFileBeAnalyzed(child)) {
+        if (callbacks.shouldFileBeAnalyzed(child)) {
           Source source = createSourceInContext(info.context, child);
           changeSet.addedSource(source);
           info.sources[path] = source;
@@ -437,18 +679,8 @@
     }
   }
 
-  /**
-   * Cancel all dependency subscriptions for the given context.
-   */
-  void _cancelDependencySubscriptions(_ContextInfo info) {
-    for (StreamSubscription<WatchEvent> s in info.dependencySubscriptions) {
-      s.cancel();
-    }
-    info.dependencySubscriptions.clear();
-  }
-
   void _checkForPackagespecUpdate(
-      String path, _ContextInfo info, Folder folder) {
+      String path, ContextInfo info, Folder folder) {
     // Check to see if this is the .packages file for this context and if so,
     // update the context's source factory.
     if (pathContext.basename(path) == PACKAGE_SPEC_NAME &&
@@ -457,22 +689,52 @@
       if (packagespec.exists) {
         Packages packages = _readPackagespec(packagespec);
         if (packages != null) {
-          updateContextPackageUriResolver(folder, null, packages);
+          callbacks.updateContextPackageUriResolver(
+              folder, new PackagesFileDisposition(packages));
         }
       }
     }
   }
 
   /**
-   * Compute the appropriate package URI resolver for [folder], and store
-   * dependency information in [info]. Return `null` if no package map can
-   * be computed.
+   * Compute the set of files that are being flushed, this is defined as
+   * the set of sources in the removed context (context.sources), that are
+   * orphaned by this context being removed (no other context includes this
+   * file.)
    */
-  UriResolver _computePackageUriResolver(Folder folder, _ContextInfo info) {
-    _cancelDependencySubscriptions(info);
-    if (info.packageRoot != null) {
-      info.packageMapInfo = null;
-      JavaFile packagesDir = new JavaFile(info.packageRoot);
+  List<String> _computeFlushedFiles(ContextInfo info) {
+    AnalysisContext context = info.context;
+    HashSet<String> flushedFiles = new HashSet<String>();
+    for (Source source in context.sources) {
+      flushedFiles.add(source.fullName);
+    }
+    for (ContextInfo contextInfo in _rootInfo.descendants) {
+      AnalysisContext contextN = contextInfo.context;
+      if (context != contextN) {
+        for (Source source in contextN.sources) {
+          flushedFiles.remove(source.fullName);
+        }
+      }
+    }
+    return flushedFiles.toList(growable: false);
+  }
+
+  /**
+   * Compute the appropriate [FolderDisposition] for [folder].  Use
+   * [addDependency] to indicate which files needed to be consulted in order to
+   * figure out the [FolderDisposition]; these dependencies will be watched in
+   * order to determine when it is necessary to call this function again.
+   *
+   * TODO(paulberry): use [addDependency] for tracking all folder disposition
+   * dependencies (currently we only use it to track "pub list" dependencies).
+   */
+  FolderDisposition _computeFolderDisposition(
+      Folder folder, void addDependency(String path)) {
+    String packageRoot = normalizedPackageRoots[folder.path];
+    if (packageRoot != null) {
+      // TODO(paulberry): We shouldn't be using JavaFile here because it
+      // makes the code untestable (see dartbug.com/23909).
+      JavaFile packagesDir = new JavaFile(packageRoot);
       Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>();
       if (packagesDir.isDirectory()) {
         for (JavaFile file in packagesDir.listFiles()) {
@@ -491,89 +753,66 @@
             packageMap[file.getName()] = <Folder>[res];
           }
         }
-        return new PackageMapUriResolver(resourceProvider, packageMap);
+        return new PackageMapDisposition(packageMap, packageRoot: packageRoot);
       }
-      //TODO(danrubel) remove this if it will never be called
-      return new PackageUriResolver([packagesDir]);
+      // The package root does not exist (or is not a folder).  Since
+      // [setRoots] ignores any package roots that don't exist (or aren't
+      // folders), the only way we should be able to get here is due to a race
+      // condition.  In any case, the package root folder is gone, so we can't
+      // resolve packages.
+      return new NoPackageFolderDisposition(packageRoot: packageRoot);
     } else {
-      beginComputePackageMap();
+      callbacks.beginComputePackageMap();
       if (packageResolverProvider != null) {
         UriResolver resolver = packageResolverProvider(folder);
         if (resolver != null) {
-          return resolver;
+          return new CustomPackageResolverDisposition(resolver);
         }
       }
-      OptimizingPubPackageMapInfo packageMapInfo;
+      PackageMapInfo packageMapInfo;
       ServerPerformanceStatistics.pub.makeCurrentWhile(() {
-        packageMapInfo =
-            _packageMapProvider.computePackageMap(folder, info.packageMapInfo);
+        packageMapInfo = _packageMapProvider.computePackageMap(folder);
       });
-      endComputePackageMap();
+      callbacks.endComputePackageMap();
       for (String dependencyPath in packageMapInfo.dependencies) {
-        Resource resource = resourceProvider.getResource(dependencyPath);
-        if (resource is File) {
-          StreamSubscription<WatchEvent> subscription;
-          subscription = resource.changes.listen((WatchEvent event) {
-            if (info.packageMapInfo != null &&
-                info.packageMapInfo.isChangedDependency(
-                    dependencyPath, resourceProvider)) {
-              _recomputePackageUriResolver(info);
-            }
-          }, onError: (error, StackTrace stackTrace) {
-            // Gracefully degrade if file is or becomes unwatchable
-            _instrumentationService.logException(error, stackTrace);
-            subscription.cancel();
-            info.dependencySubscriptions.remove(subscription);
-          });
-          info.dependencySubscriptions.add(subscription);
-        }
+        addDependency(dependencyPath);
       }
-      info.packageMapInfo = packageMapInfo;
       if (packageMapInfo.packageMap == null) {
-        return null;
+        return new NoPackageFolderDisposition();
       }
-      return new PackageMapUriResolver(
-          resourceProvider, packageMapInfo.packageMap);
-      // TODO(paulberry): if any of the dependencies is outside of [folder],
-      // we'll need to watch their parent folders as well.
+      return new PackageMapDisposition(packageMapInfo.packageMap);
     }
   }
 
   /**
-   * Create a new empty context associated with [folder].
+   * Create a new empty context associated with [folder], having parent
+   * [parent] and using [packagespecFile] to resolve package URI's.
    */
-  _ContextInfo _createContext(
-      Folder folder, File packagespecFile, List<_ContextInfo> children) {
-    _ContextInfo info = new _ContextInfo(
-        folder, packagespecFile, children, normalizedPackageRoots[folder.path]);
-    _contexts[folder] = info;
-    var options = analysisOptionsProvider.getOptions(folder);
-    processOptionsForContext(folder, options);
-    info.changeSubscription = folder.changes.listen((WatchEvent event) {
-      _handleWatchEvent(folder, info, event);
-    });
-    try {
-      Packages packages;
-      UriResolver packageUriResolver;
+  ContextInfo _createContext(
+      ContextInfo parent, Folder folder, File packagespecFile) {
+    ContextInfo info = new ContextInfo(this, parent, folder, packagespecFile,
+        normalizedPackageRoots[folder.path]);
+    Map<String, YamlNode> options = analysisOptionsProvider.getOptions(folder);
+    processOptionsForContext(info, options);
+    FolderDisposition disposition;
+    List<String> dependencies = <String>[];
 
-      if (ENABLE_PACKAGESPEC_SUPPORT) {
-        // Try .packages first.
-        if (pathos.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
-          packages = _readPackagespec(packagespecFile);
-        }
+    if (ENABLE_PACKAGESPEC_SUPPORT) {
+      // Try .packages first.
+      if (pathos.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
+        Packages packages = _readPackagespec(packagespecFile);
+        disposition = new PackagesFileDisposition(packages);
       }
-
-      // Next resort to a package uri resolver.
-      if (packages == null) {
-        packageUriResolver = _computePackageUriResolver(folder, info);
-      }
-
-      info.context = addContext(folder, packageUriResolver, packages);
-      info.context.name = folder.path;
-    } catch (_) {
-      info.changeSubscription.cancel();
-      rethrow;
     }
+
+    // Next resort to a package uri resolver.
+    if (disposition == null) {
+      disposition = _computeFolderDisposition(folder, dependencies.add);
+    }
+
+    info.setDependencies(dependencies);
+    info.context = callbacks.addContext(folder, disposition);
+    info.context.name = folder.path;
     return info;
   }
 
@@ -587,22 +826,12 @@
    * If [withPackageSpecOnly] is `true`, a context will be created only if there
    * is a 'pubspec.yaml' or '.packages' file in the [folder].
    *
-   * Returns created contexts.
+   * [parent] should be the parent of any contexts that are created.
    */
-  List<_ContextInfo> _createContexts(Folder folder, bool withPackageSpecOnly) {
-    // Try to find subfolders with pubspecs or .packages files.
-    List<_ContextInfo> children = <_ContextInfo>[];
-    try {
-      for (Resource child in folder.getChildren()) {
-        if (child is Folder) {
-          children.addAll(_createContexts(child, true));
-        }
-      }
-    } on FileSystemException {
-      // The directory either doesn't exist or cannot be read. Either way, there
-      // are no subfolders that need to be added.
-    }
-
+  void _createContexts(
+      ContextInfo parent, Folder folder, bool withPackageSpecOnly) {
+    // Decide whether a context needs to be created for [folder] here, and if
+    // so, create it.
     File packageSpec;
 
     if (ENABLE_PACKAGESPEC_SUPPORT) {
@@ -615,53 +844,59 @@
       packageSpec = folder.getChild(PUBSPEC_NAME);
     }
 
-    if (packageSpec.exists) {
-      return <_ContextInfo>[
-        _createContextWithSources(folder, packageSpec, children)
-      ];
+    bool createContext = packageSpec.exists || !withPackageSpecOnly;
+    if (withPackageSpecOnly &&
+        packageSpec.exists &&
+        (parent != null) &&
+        parent.ignored(packageSpec.path)) {
+      // Don't create a context if the package spec is required and ignored.
+      createContext = false;
     }
-    // No packagespec? Done.
-    if (withPackageSpecOnly) {
-      return children;
+    if (createContext) {
+      parent = _createContext(parent, folder, packageSpec);
     }
-    // OK, create a context without a packagespec.
-    return <_ContextInfo>[
-      _createContextWithSources(folder, packageSpec, children)
-    ];
-  }
 
-  /**
-   * Create a new context associated with the given [folder]. The [pubspecFile]
-   * is the `pubspec.yaml` file contained in the folder. Add any sources that
-   * are not included in one of the [children] to the context.
-   */
-  _ContextInfo _createContextWithSources(
-      Folder folder, File pubspecFile, List<_ContextInfo> children) {
-    _ContextInfo info = _createContext(folder, pubspecFile, children);
-    ChangeSet changeSet = new ChangeSet();
-    _addSourceFiles(changeSet, folder, info);
-    applyChangesToContext(folder, changeSet);
-    return info;
+    // Try to find subfolders with pubspecs or .packages files.
+    try {
+      for (Resource child in folder.getChildren()) {
+        if (child is Folder) {
+          if (!parent.ignored(child.path)) {
+            _createContexts(parent, child, true);
+          }
+        }
+      }
+    } on FileSystemException {
+      // The directory either doesn't exist or cannot be read. Either way, there
+      // are no subfolders that need to be added.
+    }
+
+    if (createContext) {
+      // Now that the child contexts have been created, add the sources that
+      // don't belong to the children.
+      ChangeSet changeSet = new ChangeSet();
+      _addSourceFiles(changeSet, folder, parent);
+      callbacks.applyChangesToContext(folder, changeSet);
+    }
   }
 
   /**
    * Clean up and destroy the context associated with the given folder.
    */
-  void _destroyContext(Folder folder) {
-    _ContextInfo info = _contexts[folder];
-    info.changeSubscription.cancel();
-    _cancelDependencySubscriptions(info);
-    removeContext(folder);
-    _contexts.remove(folder);
+  void _destroyContext(ContextInfo info) {
+    if (_changeSubscriptions.containsKey(info.folder)) {
+      _changeSubscriptions[info.folder].cancel();
+    }
+    callbacks.removeContext(info.folder, _computeFlushedFiles(info));
+    bool wasRemoved = info.parent.children.remove(info);
+    assert(wasRemoved);
   }
 
   /**
    * Extract a new [packagespecFile]-based context from [oldInfo].
    */
-  void _extractContext(_ContextInfo oldInfo, File packagespecFile) {
+  void _extractContext(ContextInfo oldInfo, File packagespecFile) {
     Folder newFolder = packagespecFile.parent;
-    _ContextInfo newInfo = _createContext(newFolder, packagespecFile, []);
-    newInfo.parent = oldInfo;
+    ContextInfo newInfo = _createContext(oldInfo, newFolder, packagespecFile);
     // prepare sources to extract
     Map<String, Source> extractedSources = new HashMap<String, Source>();
     oldInfo.sources.forEach((path, source) {
@@ -676,7 +911,7 @@
         newInfo.sources[path] = source;
         changeSet.addedSource(source);
       });
-      applyChangesToContext(newFolder, changeSet);
+      callbacks.applyChangesToContext(newFolder, changeSet);
     }
     // update old context
     {
@@ -685,18 +920,58 @@
         oldInfo.sources.remove(path);
         changeSet.removedSource(source);
       });
-      applyChangesToContext(oldInfo.folder, changeSet);
+      callbacks.applyChangesToContext(oldInfo.folder, changeSet);
+    }
+    // TODO(paulberry): every context that was previously a child of oldInfo is
+    // is still a child of oldInfo.  This is wrong--some of them ought to be
+    // adopted by newInfo now.
+  }
+
+  /**
+   * Return the [ContextInfo] for the "innermost" context whose associated
+   * folder is or contains the given path.  ("innermost" refers to the nesting
+   * of contexts, so if there is a context for path /foo and a context for
+   * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
+   * the context for /foo/bar.)
+   *
+   * If no context contains the given path, `null` is returned.
+   */
+  ContextInfo _getInnermostContextInfoFor(String path) {
+    ContextInfo info = _rootInfo.findChildInfoFor(path);
+    if (info == null) {
+      return null;
+    }
+    while (true) {
+      ContextInfo childInfo = info.findChildInfoFor(path);
+      if (childInfo == null) {
+        return info;
+      }
+      info = childInfo;
     }
   }
 
-  void _handleWatchEvent(Folder folder, _ContextInfo info, WatchEvent event) {
+  void _handleWatchEvent(WatchEvent event) {
+    // Figure out which context this event applies to.
     // TODO(brianwilkerson) If a file is explicitly included in one context
     // but implicitly referenced in another context, we will only send a
     // changeSet to the context that explicitly includes the file (because
     // that's the only context that's watching the file).
+    ContextInfo info = _getInnermostContextInfoFor(event.path);
+    if (info == null) {
+      // This event doesn't apply to any context.  This could happen due to a
+      // race condition (e.g. a context was removed while one of its events was
+      // in the event loop).  The event is inapplicable now, so just ignore it.
+      return;
+    }
     _instrumentationService.logWatchEvent(
-        folder.path, event.path, event.type.toString());
+        info.folder.path, event.path, event.type.toString());
     String path = event.path;
+    // First handle changes that affect folderDisposition (since these need to
+    // be processed regardless of whether they are part of an excluded/ignored
+    // path).
+    if (info.hasDependency(path)) {
+      _recomputeFolderDisposition(info);
+    }
     // maybe excluded globally
     if (_isExcluded(path)) {
       return;
@@ -711,7 +986,7 @@
     // handle the change
     switch (event.type) {
       case ChangeType.ADD:
-        if (_isInPackagesDir(path, folder)) {
+        if (_isInPackagesDir(path, info.folder)) {
           return;
         }
 
@@ -721,7 +996,7 @@
           String directoryPath = pathContext.dirname(path);
 
           // Check to see if we need to create a new context.
-          if (info.isRoot) {
+          if (info.isTopLevel) {
 
             // Only create a new context if this is not the same directory
             // described by our info object.
@@ -747,7 +1022,7 @@
         } else {
           // pubspec was added in a sub-folder, extract a new context
           if (_isPubspec(path) &&
-              info.isRoot &&
+              info.isTopLevel &&
               !info.isPathToPackageDescription(path)) {
             _extractContext(info, resource);
             return;
@@ -759,11 +1034,11 @@
         // that case don't add it.
         if (resource is File) {
           File file = resource;
-          if (shouldFileBeAnalyzed(file)) {
+          if (callbacks.shouldFileBeAnalyzed(file)) {
             ChangeSet changeSet = new ChangeSet();
             Source source = createSourceInContext(info.context, file);
             changeSet.addedSource(source);
-            applyChangesToContext(folder, changeSet);
+            callbacks.applyChangesToContext(info.folder, changeSet);
             info.sources[path] = source;
           }
         }
@@ -773,7 +1048,7 @@
         // If package spec info is removed, check to see if we can merge contexts.
         // Note that it's important to verify that there is NEITHER a .packages nor a
         // lingering pubspec.yaml before merging.
-        if (!info.isRoot) {
+        if (!info.isTopLevel) {
           if (ENABLE_PACKAGESPEC_SUPPORT) {
             String directoryPath = pathContext.dirname(path);
 
@@ -810,7 +1085,7 @@
           sources.forEach((Source source) {
             changeSet.removedSource(source);
           });
-          applyChangesToContext(folder, changeSet);
+          callbacks.applyChangesToContext(info.folder, changeSet);
           info.sources.remove(path);
         }
         break;
@@ -821,18 +1096,13 @@
           sources.forEach((Source source) {
             changeSet.changedSource(source);
           });
-          applyChangesToContext(folder, changeSet);
+          callbacks.applyChangesToContext(info.folder, changeSet);
         }
         break;
     }
 
     //TODO(pquitslund): find the right place for this
-    _checkForPackagespecUpdate(path, info, folder);
-
-    if (info.packageMapInfo != null &&
-        info.packageMapInfo.isChangedDependency(path, resourceProvider)) {
-      _recomputePackageUriResolver(info);
-    }
+    _checkForPackagespecUpdate(path, info, info.folder);
   }
 
   /**
@@ -870,11 +1140,11 @@
   /**
    * Merges [info] context into its parent.
    */
-  void _mergeContext(_ContextInfo info) {
+  void _mergeContext(ContextInfo info) {
     // destroy the context
-    _destroyContext(info.folder);
+    _destroyContext(info);
     // add files to the parent context
-    _ContextInfo parentInfo = info.parent;
+    ContextInfo parentInfo = info.parent;
     if (parentInfo != null) {
       parentInfo.children.remove(info);
       ChangeSet changeSet = new ChangeSet();
@@ -882,7 +1152,7 @@
         parentInfo.sources[path] = source;
         changeSet.addedSource(source);
       });
-      applyChangesToContext(parentInfo.folder, changeSet);
+      callbacks.applyChangesToContext(parentInfo.folder, changeSet);
     }
   }
 
@@ -899,17 +1169,19 @@
   }
 
   /**
-   * Recompute the package URI resolver for the context described by [info],
+   * Recompute the [FolderDisposition] for the context described by [info],
    * and update the client appropriately.
    */
-  void _recomputePackageUriResolver(_ContextInfo info) {
+  void _recomputeFolderDisposition(ContextInfo info) {
     // TODO(paulberry): when computePackageMap is changed into an
     // asynchronous API call, we'll want to suspend analysis for this context
     // while we're rerunning "pub list", since any analysis we complete while
     // "pub list" is in progress is just going to get thrown away anyhow.
-    UriResolver packageUriResolver =
-        _computePackageUriResolver(info.folder, info);
-    updateContextPackageUriResolver(info.folder, packageUriResolver, null);
+    List<String> dependencies = <String>[];
+    FolderDisposition disposition =
+        _computeFolderDisposition(info.folder, dependencies.add);
+    info.setDependencies(dependencies);
+    callbacks.updateContextPackageUriResolver(info.folder, disposition);
   }
 
   /**
@@ -929,73 +1201,6 @@
 }
 
 /**
- * Class that maintains a mapping from included/excluded paths to a set of
- * folders that should correspond to analysis contexts.
- */
-abstract class ContextManager {
-  // TODO(brianwilkerson) Support:
-  //   setting the default analysis options
-  //   setting the default content cache
-  //   setting the default SDK
-  //   maintaining AnalysisContext.folderMap (or remove it)
-  //   telling server when a context has been added or removed (see onContextsChanged)
-  //   telling server when a context needs to be re-analyzed
-  //   notifying the client when results should be flushed
-  //   using analyzeFileFunctions to determine which files to analyze
-  //
-  // TODO(brianwilkerson) Move this class to a public library.
-
-//  /**
-//   * The default options used to create new analysis contexts.
-//   */
-//  AnalysisOptionsImpl get defaultOptions;
-
-  /**
-   * Return the list of excluded paths (folders and files) most recently passed
-   * to [setRoots].
-   */
-  List<String> get excludedPaths;
-
-  /**
-   * Return the list of included paths (folders and files) most recently passed
-   * to [setRoots].
-   */
-  List<String> get includedPaths;
-
-//  /**
-//   * A stream that is notified when contexts are added or removed.
-//   */
-//  Stream<ContextsChangedEvent> get onContextsChanged;
-
-  /**
-   * Return a list containing all of the contexts contained in the given
-   * [analysisRoot].
-   */
-  List<AnalysisContext> contextsInAnalysisRoot(Folder analysisRoot);
-
-  /**
-   * Return `true` if the given absolute [path] is in one of the current
-   * root folders and is not excluded.
-   */
-  bool isInAnalysisRoot(String path);
-
-  /**
-   * Rebuild the set of contexts from scratch based on the data last sent to
-   * [setRoots]. Only contexts contained in the given list of analysis [roots]
-   * will be rebuilt, unless the list is `null`, in which case every context
-   * will be rebuilt.
-   */
-  void refresh(List<Resource> roots);
-
-  /**
-   * Change the set of paths which should be used as starting points to
-   * determine the context directories.
-   */
-  void setRoots(List<String> includedPaths, List<String> excludedPaths,
-      Map<String, String> packageRoots);
-}
-
-/**
  * An indication that one or more contexts were added, changed, or removed.
  *
  * The lists of [added], [changed] and [removed] contexts will not contain
@@ -1028,104 +1233,121 @@
 }
 
 /**
- * Information tracked by the [ContextManager] for each context.
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should resolve package URIs using a custom URI resolver.
  */
-class _ContextInfo {
+class CustomPackageResolverDisposition extends FolderDisposition {
   /**
-   * The [Folder] for which this information object is created.
+   * The [UriResolver] that should be used to resolve package URIs.
    */
-  final Folder folder;
+  UriResolver resolver;
 
-  /// The [PathFilter] used to filter sources from being analyzed.
-  final PathFilter pathFilter;
+  CustomPackageResolverDisposition(this.resolver);
+
+  @override
+  String get packageRoot => null;
+
+  @override
+  Packages get packages => null;
+
+  @override
+  Iterable<UriResolver> createPackageUriResolvers(
+      ResourceProvider resourceProvider) => <UriResolver>[resolver];
+}
+
+/**
+ * An instance of the class [FolderDisposition] represents the information
+ * gathered by the [ContextManagerImpl] to determine how to create an
+ * [AnalysisContext] for a given folder.
+ *
+ * Note: [ContextManagerImpl] may use equality testing and hash codes to
+ * determine when two folders should share the same context, so derived classes
+ * may need to override operator== and hashCode() if object identity is
+ * insufficient.
+ *
+ * TODO(paulberry): consider adding a flag to indicate that it is not necessary
+ * to recurse into the given folder looking for additional contexts to create
+ * or files to analyze (this could help avoid unnecessarily weighing down the
+ * system with file watchers).
+ */
+abstract class FolderDisposition {
+  /**
+   * If this [FolderDisposition] was created based on a package root
+   * folder, the absolute path to that folder.  Otherwise `null`.
+   */
+  String get packageRoot;
 
   /**
-   * The enclosed pubspec-based contexts.
+   * If contexts governed by this [FolderDisposition] should resolve packages
+   * using the ".packages" file mechanism (DEP 5), retrieve the [Packages]
+   * object that resulted from parsing the ".packages" file.
    */
-  final List<_ContextInfo> children;
+  Packages get packages;
 
   /**
-   * The package root for this context, or null if there is no package root.
+   * Create all the [UriResolver]s which should be used to resolve packages in
+   * contexts governed by this [FolderDisposition].
+   *
+   * [resourceProvider] is provided since it is needed to construct most
+   * [UriResolver]s.
    */
-  String packageRoot;
+  Iterable<UriResolver> createPackageUriResolvers(
+      ResourceProvider resourceProvider);
+}
 
-  /**
-   * The [_ContextInfo] that encloses this one.
-   */
-  _ContextInfo parent;
+/**
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should not resolve "package:" URIs at all.
+ */
+class NoPackageFolderDisposition extends FolderDisposition {
+  @override
+  final String packageRoot;
 
-  /**
-   * The package description file path for this context.
-   */
-  String packageDescriptionPath;
+  NoPackageFolderDisposition({this.packageRoot});
 
-  /**
-   * Stream subscription we are using to watch the context's directory for
-   * changes.
-   */
-  StreamSubscription<WatchEvent> changeSubscription;
+  @override
+  Packages get packages => null;
 
-  /**
-   * Stream subscriptions we are using to watch the files
-   * used to determine the package map.
-   */
-  final List<StreamSubscription<WatchEvent>> dependencySubscriptions =
-      <StreamSubscription<WatchEvent>>[];
+  @override
+  Iterable<UriResolver> createPackageUriResolvers(
+      ResourceProvider resourceProvider) => const <UriResolver>[];
+}
 
-  /**
-   * The analysis context that was created for the [folder].
-   */
-  AnalysisContext context;
+/**
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should resolve packages using a package map.
+ */
+class PackageMapDisposition extends FolderDisposition {
+  final Map<String, List<Folder>> packageMap;
 
-  /**
-   * Map from full path to the [Source] object, for each source that has been
-   * added to the context.
-   */
-  Map<String, Source> sources = new HashMap<String, Source>();
+  @override
+  final String packageRoot;
 
-  /**
-   * Info returned by the last call to
-   * [OptimizingPubPackageMapProvider.computePackageMap], or `null` if the
-   * package map hasn't been computed for this context yet.
-   */
-  OptimizingPubPackageMapInfo packageMapInfo;
+  PackageMapDisposition(this.packageMap, {this.packageRoot});
 
-  _ContextInfo(
-      Folder folder, File packagespecFile, this.children, this.packageRoot)
-      : folder = folder,
-        pathFilter = new PathFilter(folder.path, null) {
-    packageDescriptionPath = packagespecFile.path;
-    for (_ContextInfo child in children) {
-      child.parent = this;
-    }
-  }
+  @override
+  Packages get packages => null;
 
-  /**
-   * Returns `true` if this context is root folder based.
-   */
-  bool get isRoot => parent == null;
+  @override
+  Iterable<UriResolver> createPackageUriResolvers(
+          ResourceProvider resourceProvider) =>
+      <UriResolver>[new PackageMapUriResolver(resourceProvider, packageMap)];
+}
 
-  /**
-   * Returns `true` if [path] is excluded, as it is in one of the children.
-   */
-  bool excludes(String path) {
-    return children.any((child) {
-      return child.folder.contains(path);
-    });
-  }
+/**
+ * Concrete [FolderDisposition] object indicating that the context for a given
+ * folder should resolve packages using a ".packages" file.
+ */
+class PackagesFileDisposition extends FolderDisposition {
+  @override
+  final Packages packages;
 
-  /**
-   * Returns `true` if [resource] is excluded, as it is in one of the children.
-   */
-  bool excludesResource(Resource resource) => excludes(resource.path);
+  PackagesFileDisposition(this.packages) {}
 
-  /// Returns `true` if  [path] should be ignored.
-  bool ignored(String path) => pathFilter.ignored(path);
+  @override
+  String get packageRoot => null;
 
-  /**
-   * Returns `true` if [path] is the package description file for this context 
-   * (pubspec.yaml or .packages).
-   */
-  bool isPathToPackageDescription(String path) =>
-      path == packageDescriptionPath;
+  @override
+  Iterable<UriResolver> createPackageUriResolvers(
+      ResourceProvider resourceProvider) => const <UriResolver>[];
 }
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index 42afae3..483f532 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -112,13 +112,12 @@
   Response getNavigation(Request request) {
     var params = new AnalysisGetNavigationParams.fromRequest(request);
     String file = params.file;
-    int offset = params.offset;
-    Future<AnalysisDoneReason> completionFuture =
+    Future<AnalysisDoneReason> analysisFuture =
         server.onFileAnalysisComplete(file);
-    if (completionFuture == null) {
+    if (analysisFuture == null) {
       return new Response.getNavigationInvalidFile(request);
     }
-    completionFuture.then((AnalysisDoneReason reason) {
+    analysisFuture.then((AnalysisDoneReason reason) {
       switch (reason) {
         case AnalysisDoneReason.COMPLETE:
           List<CompilationUnit> units =
@@ -128,11 +127,10 @@
           } else {
             DartUnitNavigationComputer computer =
                 new DartUnitNavigationComputer();
+            _GetNavigationAstVisitor visitor = new _GetNavigationAstVisitor(
+                params.offset, params.offset + params.length, computer);
             for (CompilationUnit unit in units) {
-              AstNode node = new NodeLocator(offset).searchWithin(unit);
-              if (node != null) {
-                computer.compute(node);
-              }
+              unit.accept(visitor);
             }
             server.sendResponse(new AnalysisGetNavigationResult(
                     computer.files, computer.targets, computer.regions)
@@ -268,11 +266,6 @@
     var params = new AnalysisUpdateOptionsParams.fromRequest(request);
     AnalysisOptions newOptions = params.options;
     List<OptionUpdater> updaters = new List<OptionUpdater>();
-    if (newOptions.enableNullAwareOperators != null) {
-      updaters.add((engine.AnalysisOptionsImpl options) {
-        options.enableNullAwareOperators = newOptions.enableNullAwareOperators;
-      });
-    }
     if (newOptions.generateDart2jsHints != null) {
       updaters.add((engine.AnalysisOptionsImpl options) {
         options.dart2jsHint = newOptions.generateDart2jsHints;
@@ -292,3 +285,36 @@
     return new AnalysisUpdateOptionsResult().toResponse(request.id);
   }
 }
+
+/**
+ * An AST visitor that computer navigation regions in the givne region.
+ */
+class _GetNavigationAstVisitor extends UnifyingAstVisitor {
+  final int rangeStart;
+  final int rangeEnd;
+  final DartUnitNavigationComputer computer;
+
+  _GetNavigationAstVisitor(this.rangeStart, this.rangeEnd, this.computer);
+
+  bool isInRange(int offset) {
+    return rangeStart <= offset && offset <= rangeEnd;
+  }
+
+  @override
+  visitNode(AstNode node) {
+    // The node ends before the range starts.
+    if (node.end < rangeStart) {
+      return;
+    }
+    // The node starts after the range ends.
+    if (node.offset > rangeEnd) {
+      return;
+    }
+    // The node starts or ends in the range.
+    if (isInRange(node.offset) || isInRange(node.end)) {
+      computer.compute(node);
+      return;
+    }
+    super.visitNode(node);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index ee26dd8..3213537 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -14,6 +14,7 @@
 import 'package:analysis_server/src/protocol_server.dart' hide Element;
 import 'package:analysis_server/src/services/correction/assist.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/organize_directives.dart';
 import 'package:analysis_server/src/services/correction/sort_members.dart';
 import 'package:analysis_server/src/services/correction/status.dart';
 import 'package:analysis_server/src/services/refactoring/refactoring.dart';
@@ -156,8 +157,8 @@
         for (engine.AnalysisError error in errorInfo.errors) {
           int errorLine = lineInfo.getLocation(error.offset).lineNumber;
           if (errorLine == requestLine) {
-            List<Fix> fixes =
-                computeFixes(server.serverPlugin, unit.element.context, error);
+            List<Fix> fixes = computeFixes(server.serverPlugin,
+                server.resourceProvider, unit.element.context, error);
             if (fixes.isNotEmpty) {
               AnalysisError serverError =
                   newAnalysisError_fromEngine(lineInfo, error);
@@ -190,6 +191,8 @@
         return getFixes(request);
       } else if (requestName == EDIT_GET_REFACTORING) {
         return _getRefactoring(request);
+      } else if (requestName == EDIT_ORGANIZE_DIRECTIVES) {
+        return organizeDirectives(request);
       } else if (requestName == EDIT_SORT_MEMBERS) {
         return sortMembers(request);
       }
@@ -199,6 +202,38 @@
     return null;
   }
 
+  Response organizeDirectives(Request request) {
+    var params = new EditOrganizeDirectivesParams.fromRequest(request);
+    // prepare file
+    String file = params.file;
+    if (!engine.AnalysisEngine.isDartFileName(file)) {
+      return new Response.fileNotAnalyzed(request, file);
+    }
+    // prepare resolved units
+    List<CompilationUnit> units = server.getResolvedCompilationUnits(file);
+    if (units.isEmpty) {
+      return new Response.fileNotAnalyzed(request, file);
+    }
+    // prepare context
+    CompilationUnit unit = units.first;
+    engine.AnalysisContext context = unit.element.context;
+    Source source = unit.element.source;
+    List<engine.AnalysisError> errors = context.computeErrors(source);
+    // check if there are scan/parse errors in the file
+    int numScanParseErrors = _getNumberOfScanParseErrors(errors);
+    if (numScanParseErrors != 0) {
+      return new Response.organizeDirectivesError(
+          request, 'File has $numScanParseErrors scan/parse errors.');
+    }
+    // do organize
+    int fileStamp = context.getModificationStamp(source);
+    String code = context.getContents(source).data;
+    DirectiveOrganizer sorter = new DirectiveOrganizer(code, unit, errors);
+    List<SourceEdit> edits = sorter.organize();
+    SourceFileEdit fileEdit = new SourceFileEdit(file, fileStamp, edits: edits);
+    return new EditOrganizeDirectivesResult(fileEdit).toResponse(request.id);
+  }
+
   Response sortMembers(Request request) {
     var params = new EditSortMembersParams.fromRequest(request);
     // prepare file
@@ -215,15 +250,9 @@
     CompilationUnit unit = units.first;
     engine.AnalysisContext context = unit.element.context;
     Source source = unit.element.source;
-    // check if there are no scan/parse errors in the file
+    // check if there are scan/parse errors in the file
     engine.AnalysisErrorInfo errors = context.getErrors(source);
-    int numScanParseErrors = 0;
-    errors.errors.forEach((engine.AnalysisError error) {
-      if (error.errorCode is engine.ScannerErrorCode ||
-          error.errorCode is engine.ParserErrorCode) {
-        numScanParseErrors++;
-      }
-    });
+    int numScanParseErrors = _getNumberOfScanParseErrors(errors.errors);
     if (numScanParseErrors != 0) {
       return new Response.sortMembersParseErrors(request, numScanParseErrors);
     }
@@ -304,6 +333,17 @@
   void _newRefactoringManager() {
     refactoringManager = new _RefactoringManager(server, searchEngine);
   }
+
+  static int _getNumberOfScanParseErrors(List<engine.AnalysisError> errors) {
+    int numScanParseErrors = 0;
+    for (engine.AnalysisError error in errors) {
+      if (error.errorCode is engine.ScannerErrorCode ||
+          error.errorCode is engine.ParserErrorCode) {
+        numScanParseErrors++;
+      }
+    }
+    return numScanParseErrors;
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/generated_protocol.dart b/pkg/analysis_server/lib/src/generated_protocol.dart
index 5ecfe20..f92288f 100644
--- a/pkg/analysis_server/lib/src/generated_protocol.dart
+++ b/pkg/analysis_server/lib/src/generated_protocol.dart
@@ -6166,6 +6166,164 @@
 }
 
 /**
+ * edit.organizeDirectives params
+ *
+ * {
+ *   "file": FilePath
+ * }
+ */
+class EditOrganizeDirectivesParams implements HasToJson {
+  String _file;
+
+  /**
+   * The Dart file to organize directives in.
+   */
+  String get file => _file;
+
+  /**
+   * The Dart file to organize directives in.
+   */
+  void set file(String value) {
+    assert(value != null);
+    this._file = value;
+  }
+
+  EditOrganizeDirectivesParams(String file) {
+    this.file = file;
+  }
+
+  factory EditOrganizeDirectivesParams.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      String file;
+      if (json.containsKey("file")) {
+        file = jsonDecoder._decodeString(jsonPath + ".file", json["file"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "file");
+      }
+      return new EditOrganizeDirectivesParams(file);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "edit.organizeDirectives params", json);
+    }
+  }
+
+  factory EditOrganizeDirectivesParams.fromRequest(Request request) {
+    return new EditOrganizeDirectivesParams.fromJson(
+        new RequestDecoder(request), "params", request._params);
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["file"] = file;
+    return result;
+  }
+
+  Request toRequest(String id) {
+    return new Request(id, "edit.organizeDirectives", toJson());
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is EditOrganizeDirectivesParams) {
+      return file == other.file;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = _JenkinsSmiHash.combine(hash, file.hashCode);
+    return _JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
+ * edit.organizeDirectives result
+ *
+ * {
+ *   "edit": SourceFileEdit
+ * }
+ */
+class EditOrganizeDirectivesResult implements HasToJson {
+  SourceFileEdit _edit;
+
+  /**
+   * The file edit that is to be applied to the given file to effect the
+   * organizing.
+   */
+  SourceFileEdit get edit => _edit;
+
+  /**
+   * The file edit that is to be applied to the given file to effect the
+   * organizing.
+   */
+  void set edit(SourceFileEdit value) {
+    assert(value != null);
+    this._edit = value;
+  }
+
+  EditOrganizeDirectivesResult(SourceFileEdit edit) {
+    this.edit = edit;
+  }
+
+  factory EditOrganizeDirectivesResult.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      SourceFileEdit edit;
+      if (json.containsKey("edit")) {
+        edit = new SourceFileEdit.fromJson(jsonDecoder, jsonPath + ".edit", json["edit"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "edit");
+      }
+      return new EditOrganizeDirectivesResult(edit);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "edit.organizeDirectives result", json);
+    }
+  }
+
+  factory EditOrganizeDirectivesResult.fromResponse(Response response) {
+    return new EditOrganizeDirectivesResult.fromJson(
+        new ResponseDecoder(REQUEST_ID_REFACTORING_KINDS.remove(response.id)), "result", response._result);
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["edit"] = edit.toJson();
+    return result;
+  }
+
+  Response toResponse(String id) {
+    return new Response(id, result: toJson());
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is EditOrganizeDirectivesResult) {
+      return edit == other.edit;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = _JenkinsSmiHash.combine(hash, edit.hashCode);
+    return _JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * execution.createContext params
  *
  * {
@@ -7403,14 +7561,14 @@
   bool _generateLints;
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed async feature.
    */
   bool get enableAsync => _enableAsync;
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed async feature.
    */
@@ -7419,7 +7577,7 @@
   }
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed deferred
    * loading feature.
@@ -7427,7 +7585,7 @@
   bool get enableDeferredLoading => _enableDeferredLoading;
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed deferred
    * loading feature.
@@ -7437,14 +7595,14 @@
   }
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed enum feature.
    */
   bool get enableEnums => _enableEnums;
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed enum feature.
    */
@@ -7453,12 +7611,16 @@
   }
 
   /**
+   * Deprecated: this feature is always enabled.
+   *
    * True if the client wants to enable support for the proposed "null aware
    * operators" feature.
    */
   bool get enableNullAwareOperators => _enableNullAwareOperators;
 
   /**
+   * Deprecated: this feature is always enabled.
+   *
    * True if the client wants to enable support for the proposed "null aware
    * operators" feature.
    */
@@ -12665,6 +12827,7 @@
  *
  * enum {
  *   CONTENT_MODIFIED
+ *   FILE_NOT_ANALYZED
  *   FORMAT_INVALID_FILE
  *   FORMAT_WITH_ERRORS
  *   GET_ERRORS_INVALID_FILE
@@ -12675,6 +12838,7 @@
  *   INVALID_PARAMETER
  *   INVALID_REQUEST
  *   NO_INDEX_GENERATED
+ *   ORGANIZE_DIRECTIVES_ERROR
  *   REFACTORING_REQUEST_CANCELLED
  *   SERVER_ALREADY_STARTED
  *   SERVER_ERROR
@@ -12695,6 +12859,12 @@
   static const CONTENT_MODIFIED = const RequestErrorCode._("CONTENT_MODIFIED");
 
   /**
+   * A request specified a FilePath which does not match a file in an analysis
+   * root, or the requested operation is not available for the file.
+   */
+  static const FILE_NOT_ANALYZED = const RequestErrorCode._("FILE_NOT_ANALYZED");
+
+  /**
    * An "edit.format" request specified a FilePath which does not match a Dart
    * file in an analysis root.
    */
@@ -12712,8 +12882,8 @@
   static const GET_ERRORS_INVALID_FILE = const RequestErrorCode._("GET_ERRORS_INVALID_FILE");
 
   /**
-   * An "analysis.getErrors" request specified a FilePath which does not match
-   * a file currently subject to analysis.
+   * An "analysis.getNavigation" request specified a FilePath which does not
+   * match a file currently subject to analysis.
    */
   static const GET_NAVIGATION_INVALID_FILE = const RequestErrorCode._("GET_NAVIGATION_INVALID_FILE");
 
@@ -12752,6 +12922,12 @@
   static const NO_INDEX_GENERATED = const RequestErrorCode._("NO_INDEX_GENERATED");
 
   /**
+   * An "edit.organizeDirectives" request specified a Dart file that cannot be
+   * analyzed. The reason is described in the message.
+   */
+  static const ORGANIZE_DIRECTIVES_ERROR = const RequestErrorCode._("ORGANIZE_DIRECTIVES_ERROR");
+
+  /**
    * Another refactoring request was received during processing of this one.
    */
   static const REFACTORING_REQUEST_CANCELLED = const RequestErrorCode._("REFACTORING_REQUEST_CANCELLED");
@@ -12817,7 +12993,7 @@
   /**
    * A list containing all of the enum values that are defined.
    */
-  static const List<RequestErrorCode> VALUES = const <RequestErrorCode>[CONTENT_MODIFIED, FORMAT_INVALID_FILE, FORMAT_WITH_ERRORS, GET_ERRORS_INVALID_FILE, GET_NAVIGATION_INVALID_FILE, INVALID_ANALYSIS_ROOT, INVALID_EXECUTION_CONTEXT, INVALID_OVERLAY_CHANGE, INVALID_PARAMETER, INVALID_REQUEST, NO_INDEX_GENERATED, 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, 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];
 
   final String name;
 
@@ -12827,6 +13003,8 @@
     switch (name) {
       case "CONTENT_MODIFIED":
         return CONTENT_MODIFIED;
+      case "FILE_NOT_ANALYZED":
+        return FILE_NOT_ANALYZED;
       case "FORMAT_INVALID_FILE":
         return FORMAT_INVALID_FILE;
       case "FORMAT_WITH_ERRORS":
@@ -12847,6 +13025,8 @@
         return INVALID_REQUEST;
       case "NO_INDEX_GENERATED":
         return NO_INDEX_GENERATED;
+      case "ORGANIZE_DIRECTIVES_ERROR":
+        return ORGANIZE_DIRECTIVES_ERROR;
       case "REFACTORING_REQUEST_CANCELLED":
         return REFACTORING_REQUEST_CANCELLED;
       case "SERVER_ALREADY_STARTED":
diff --git a/pkg/analysis_server/lib/src/get_handler.dart b/pkg/analysis_server/lib/src/get_handler.dart
index 7068b9d..360b5da 100644
--- a/pkg/analysis_server/lib/src/get_handler.dart
+++ b/pkg/analysis_server/lib/src/get_handler.dart
@@ -1010,7 +1010,7 @@
     List<Folder> folders = folderMap.keys.toList();
     folders.sort((Folder first, Folder second) =>
         first.shortName.compareTo(second.shortName));
-    AnalysisOptionsImpl options = analysisServer.contextManager.defaultOptions;
+    AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
     ServerOperationQueue operationQueue = analysisServer.operationQueue;
 
     buffer.write('<h3>Analysis Domain</h3>');
@@ -1052,8 +1052,6 @@
       _writeOption(
           buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
       _writeOption(buffer, 'Cache size', options.cacheSize);
-      _writeOption(buffer, 'Enable null-aware operators',
-          options.enableNullAwareOperators);
       _writeOption(
           buffer, 'Enable strict call checks', options.enableStrictCallChecks);
       _writeOption(buffer, 'Generate hints', options.hint);
diff --git a/pkg/analysis_server/lib/src/protocol.dart b/pkg/analysis_server/lib/src/protocol.dart
index aec8d71..ef960f0 100644
--- a/pkg/analysis_server/lib/src/protocol.dart
+++ b/pkg/analysis_server/lib/src/protocol.dart
@@ -392,7 +392,8 @@
       var disambiguatorPath = '$jsonPath[${JSON.encode(field)}]';
       String disambiguator = _decodeString(disambiguatorPath, json[field]);
       if (!decoders.containsKey(disambiguator)) {
-        throw mismatch(disambiguatorPath, 'One of: ${decoders.keys.toList()}', json);
+        throw mismatch(
+            disambiguatorPath, 'One of: ${decoders.keys.toList()}', json);
       }
       return decoders[disambiguator](jsonPath, json);
     } else {
@@ -625,8 +626,8 @@
       buffer.write(JSON.encode(actual));
       buffer.write('"');
     }
-    return new RequestFailure(new Response.invalidParameter(
-        _request, jsonPath, buffer.toString()));
+    return new RequestFailure(
+        new Response.invalidParameter(_request, jsonPath, buffer.toString()));
   }
 
   @override
@@ -721,20 +722,31 @@
       : _result = result;
 
   /**
+   * Initialize a newly created instance to represent the
+   * FILE_NOT_ANALYZED error condition.
+   */
+  Response.fileNotAnalyzed(Request request, String file)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.FILE_NOT_ANALYZED,
+                'File is not analyzed: $file.'));
+
+  /**
    * Initialize a newly created instance to represent the FORMAT_INVALID_FILE
    * error condition.
    */
-  Response.formatInvalidFile(Request request) : this(request.id,
-          error: new RequestError(RequestErrorCode.FORMAT_INVALID_FILE,
-              'Error during `edit.format`: invalid file.'));
+  Response.formatInvalidFile(Request request)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.FORMAT_INVALID_FILE,
+                'Error during `edit.format`: invalid file.'));
 
   /**
    * Initialize a newly created instance to represent the FORMAT_WITH_ERROR
    * error condition.
    */
-  Response.formatWithErrors(Request request) : this(request.id,
-          error: new RequestError(RequestErrorCode.FORMAT_WITH_ERRORS,
-              'Error during `edit.format`: source contains syntax errors.'));
+  Response.formatWithErrors(Request request)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.FORMAT_WITH_ERRORS,
+                'Error during `edit.format`: source contains syntax errors.'));
 
   /**
    * Initialize a newly created instance based upon the given JSON data
@@ -766,37 +778,40 @@
    * Initialize a newly created instance to represent the
    * GET_ERRORS_INVALID_FILE error condition.
    */
-  Response.getErrorsInvalidFile(Request request) : this(request.id,
-          error: new RequestError(RequestErrorCode.GET_ERRORS_INVALID_FILE,
-              'Error during `analysis.getErrors`: invalid file.'));
+  Response.getErrorsInvalidFile(Request request)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.GET_ERRORS_INVALID_FILE,
+                'Error during `analysis.getErrors`: invalid file.'));
 
   /**
    * Initialize a newly created instance to represent the
    * GET_NAVIGATION_INVALID_FILE error condition.
    */
-  Response.getNavigationInvalidFile(Request request) : this(request.id,
-          error: new RequestError(RequestErrorCode.GET_NAVIGATION_INVALID_FILE,
-              'Error during `analysis.getNavigation`: invalid file.'));
+  Response.getNavigationInvalidFile(Request request)
+      : this(request.id,
+            error: new RequestError(
+                RequestErrorCode.GET_NAVIGATION_INVALID_FILE,
+                'Error during `analysis.getNavigation`: invalid file.'));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
    * by an analysis.reanalyze [request] that specifies an analysis root that is
    * not in the current list of analysis roots.
    */
-  Response.invalidAnalysisRoot(Request request, String rootPath) : this(
-          request.id,
-          error: new RequestError(RequestErrorCode.INVALID_ANALYSIS_ROOT,
-              "Invalid analysis root: $rootPath"));
+  Response.invalidAnalysisRoot(Request request, String rootPath)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.INVALID_ANALYSIS_ROOT,
+                "Invalid analysis root: $rootPath"));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
    * by a [request] that specifies an execution context whose context root does
    * not exist.
    */
-  Response.invalidExecutionContext(Request request, String contextId) : this(
-          request.id,
-          error: new RequestError(RequestErrorCode.INVALID_EXECUTION_CONTEXT,
-              "Invalid execution context: $contextId"));
+  Response.invalidExecutionContext(Request request, String contextId)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.INVALID_EXECUTION_CONTEXT,
+                "Invalid execution context: $contextId"));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
@@ -807,33 +822,45 @@
    */
   Response.invalidParameter(Request request, String path, String expectation)
       : this(request.id,
-          error: new RequestError(RequestErrorCode.INVALID_PARAMETER,
-              "Invalid parameter '$path'. $expectation."));
+            error: new RequestError(RequestErrorCode.INVALID_PARAMETER,
+                "Invalid parameter '$path'. $expectation."));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
    * by a malformed request.
    */
-  Response.invalidRequestFormat() : this('',
-          error: new RequestError(
-              RequestErrorCode.INVALID_REQUEST, 'Invalid request'));
+  Response.invalidRequestFormat()
+      : this('',
+            error: new RequestError(
+                RequestErrorCode.INVALID_REQUEST, 'Invalid request'));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
    * by a request that requires an index, but indexing is disabled.
    */
-  Response.noIndexGenerated(Request request) : this(request.id,
-          error: new RequestError(
-              RequestErrorCode.NO_INDEX_GENERATED, 'Indexing is disabled'));
+  Response.noIndexGenerated(Request request)
+      : this(request.id,
+            error: new RequestError(
+                RequestErrorCode.NO_INDEX_GENERATED, 'Indexing is disabled'));
+
+  /**
+   * Initialize a newly created instance to represent the
+   * ORGANIZE_DIRECTIVES_ERROR error condition.
+   */
+  Response.organizeDirectivesError(Request request, String message)
+      : this(request.id,
+            error: new RequestError(
+                RequestErrorCode.ORGANIZE_DIRECTIVES_ERROR, message));
 
   /**
    * Initialize a newly created instance to represent the
    * REFACTORING_REQUEST_CANCELLED error condition.
    */
-  Response.refactoringRequestCancelled(Request request) : this(request.id,
-          error: new RequestError(
-              RequestErrorCode.REFACTORING_REQUEST_CANCELLED,
-              'The `edit.getRefactoring` request was cancelled.'));
+  Response.refactoringRequestCancelled(Request request)
+      : this(request.id,
+            error: new RequestError(
+                RequestErrorCode.REFACTORING_REQUEST_CANCELLED,
+                'The `edit.getRefactoring` request was cancelled.'));
 
   /**
    * Initialize a newly created instance to represent the SERVER_ERROR error
@@ -852,49 +879,52 @@
    * Initialize a newly created instance to represent the
    * SORT_MEMBERS_INVALID_FILE error condition.
    */
-  Response.sortMembersInvalidFile(Request request) : this(request.id,
-          error: new RequestError(RequestErrorCode.SORT_MEMBERS_INVALID_FILE,
-              'Error during `edit.sortMembers`: invalid file.'));
+  Response.sortMembersInvalidFile(Request request)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.SORT_MEMBERS_INVALID_FILE,
+                'Error during `edit.sortMembers`: invalid file.'));
 
   /**
    * Initialize a newly created instance to represent the
    * SORT_MEMBERS_PARSE_ERRORS error condition.
    */
-  Response.sortMembersParseErrors(Request request, int numErrors) : this(
-          request.id,
-          error: new RequestError(RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS,
-              'Error during `edit.sortMembers`: file has $numErrors scan/parse errors.'));
+  Response.sortMembersParseErrors(Request request, int numErrors)
+      : this(request.id,
+            error: new RequestError(RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS,
+                'Error during `edit.sortMembers`: file has $numErrors scan/parse errors.'));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
    * by a `analysis.setPriorityFiles` [request] that includes one or more files
    * that are not being analyzed.
    */
-  Response.unanalyzedPriorityFiles(String requestId, String fileNames) : this(
-          requestId,
-          error: new RequestError(RequestErrorCode.UNANALYZED_PRIORITY_FILES,
-              "Unanalyzed files cannot be a priority: '$fileNames'"));
+  Response.unanalyzedPriorityFiles(String requestId, String fileNames)
+      : this(requestId,
+            error: new RequestError(RequestErrorCode.UNANALYZED_PRIORITY_FILES,
+                "Unanalyzed files cannot be a priority: '$fileNames'"));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
    * by a [request] that cannot be handled by any known handlers.
    */
-  Response.unknownRequest(Request request) : this(request.id,
-          error: new RequestError(
-              RequestErrorCode.UNKNOWN_REQUEST, 'Unknown request'));
+  Response.unknownRequest(Request request)
+      : this(request.id,
+            error: new RequestError(
+                RequestErrorCode.UNKNOWN_REQUEST, 'Unknown request'));
 
   /**
    * Initialize a newly created instance to represent an error condition caused
    * by a [request] referencing a source that does not exist.
    */
-  Response.unknownSource(Request request) : this(request.id,
-          error: new RequestError(
-              RequestErrorCode.UNKNOWN_SOURCE, 'Unknown source'));
+  Response.unknownSource(Request request)
+      : this(request.id,
+            error: new RequestError(
+                RequestErrorCode.UNKNOWN_SOURCE, 'Unknown source'));
 
-  Response.unsupportedFeature(String requestId, String message) : this(
-          requestId,
-          error: new RequestError(
-              RequestErrorCode.UNSUPPORTED_FEATURE, message));
+  Response.unsupportedFeature(String requestId, String message)
+      : this(requestId,
+            error: new RequestError(
+                RequestErrorCode.UNSUPPORTED_FEATURE, message));
 
   /**
    * Return a table representing the structure of the Json object that will be
diff --git a/pkg/analysis_server/lib/src/protocol_server.dart b/pkg/analysis_server/lib/src/protocol_server.dart
index f9e48c5..4f0b490 100644
--- a/pkg/analysis_server/lib/src/protocol_server.dart
+++ b/pkg/analysis_server/lib/src/protocol_server.dart
@@ -47,6 +47,23 @@
   change.addEdit(file, fileStamp, edit);
 }
 
+String getReturnTypeString(engine.Element element) {
+  if (element is engine.ExecutableElement) {
+    if (element.kind == engine.ElementKind.SETTER) {
+      return null;
+    } else {
+      return element.returnType.toString();
+    }
+  } else if (element is engine.VariableElement) {
+    engine.DartType type = element.type;
+    return type != null ? type.displayName : 'dynamic';
+  } else if (element is engine.FunctionTypeAliasElement) {
+    return element.returnType.toString();
+  } else {
+    return null;
+  }
+}
+
 /**
  * Construct based on error information from the analyzer engine.
  */
@@ -86,7 +103,7 @@
   String name = element.displayName;
   String elementTypeParameters = _getTypeParametersString(element);
   String elementParameters = _getParametersString(element);
-  String elementReturnType = _getReturnTypeString(element);
+  String elementReturnType = getReturnTypeString(element);
   ElementKind kind = newElementKind_fromEngineElement(element);
   return new Element(kind, name, Element.makeFlags(
           isPrivate: element.isPrivate,
@@ -103,7 +120,7 @@
 
 /**
  * Construct based on a value from the analyzer engine.
- * This does not take into account that 
+ * This does not take into account that
  * instances of ClassElement can be an enum and
  * instances of FieldElement can be an enum constant.
  * Use [newElementKind_fromEngineElement] where possible.
@@ -351,23 +368,6 @@
   return '(' + sb.toString() + ')';
 }
 
-String _getReturnTypeString(engine.Element element) {
-  if (element is engine.ExecutableElement) {
-    if (element.kind == engine.ElementKind.SETTER) {
-      return null;
-    } else {
-      return element.returnType.toString();
-    }
-  } else if (element is engine.VariableElement) {
-    engine.DartType type = element.type;
-    return type != null ? type.displayName : 'dynamic';
-  } else if (element is engine.FunctionTypeAliasElement) {
-    return element.returnType.toString();
-  } else {
-    return null;
-  }
-}
-
 String _getTypeParametersString(engine.Element element) {
   List<engine.TypeParameterElement> typeParameters;
   if (element is engine.ClassElement) {
diff --git a/pkg/analysis_server/lib/src/server_options.dart b/pkg/analysis_server/lib/src/server_options.dart
new file mode 100644
index 0000000..2eff6d9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/server_options.dart
@@ -0,0 +1,118 @@
+// 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.server_options;
+
+import 'dart:collection';
+import 'dart:io';
+
+import 'package:path/path.dart' as path;
+import 'package:yaml/yaml.dart';
+
+//TODO: consider renaming (https://github.com/dart-lang/sdk/issues/23927)
+const _optionsFileName = '.dart_analysis_server.yaml';
+
+/// The shared options instance.
+ServerOptions _serverOptions;
+
+/// Server options.
+ServerOptions get serverOptions {
+  if (_serverOptions == null) {
+    _serverOptions = _loadOptions();
+  }
+  return _serverOptions;
+}
+
+/// Find the options file relative to the user's home directory.
+/// Returns `null` if there is none or the user's homedir cannot
+/// be derived from the platform's environment (e.g., `HOME` and
+/// `UserProfile` for mac/Linux and Windows respectively).
+File _findOptionsFile() {
+  String home;
+  Map<String, String> envVars = Platform.environment;
+  if (Platform.isMacOS || Platform.isLinux) {
+    home = envVars['HOME'];
+  } else if (Platform.isWindows) {
+    home = envVars['UserProfile'];
+  }
+
+  if (home == null) {
+    return null;
+  }
+
+  return new File(path.context.join(home, _optionsFileName));
+}
+
+ServerOptions _loadOptions() {
+  File optionsFile = _findOptionsFile();
+  try {
+    if (optionsFile != null && optionsFile.existsSync()) {
+      return new ServerOptions.fromFile(optionsFile);
+    }
+  } catch (e) {
+    // Fall through.
+  }
+  return new ServerOptions._empty();
+}
+
+/// Describes options captured in an external options file.
+/// `ServerOptions` are described in a file `dart_analysis_server.options`
+/// located in the user's home directory. Options are defined in YAML and
+/// read once and cached. In order for changes to be picked up, server needs
+/// to be restarted.
+class ServerOptions {
+  final Map<String, dynamic> _options = new HashMap<String, dynamic>();
+
+  /// Load options from the given [contents].
+  ServerOptions.fromContents(String contents) {
+    _readOptions(contents);
+  }
+
+  /// Load options from the given [options] file.
+  factory ServerOptions.fromFile(File options) =>
+      new ServerOptions.fromContents(options.readAsStringSync());
+
+  /// Create an empty options object.
+  ServerOptions._empty();
+
+  /// Get the value for `key` from the options file.
+  dynamic operator [](String key) => _options[key];
+
+  /// Get a String value for this `key` or [defaultValue] if undefined
+  /// or not a String.
+  String getStringValue(String key, {String defaultValue: null}) {
+    var value = _options[key];
+    if (value is String) {
+      return value;
+    }
+    return defaultValue;
+  }
+
+  /// Test whether the given [booleanPropertyKey] is set to the value `true`,
+  /// falling back to [defaultValue] if undefined.
+  /// For example:
+  ///     myDebugOption1:true
+  ///     myDebugOption2:TRUE # Also true (case and trailing whitespace are ignored).
+  ///     myDebugOption3:false
+  ///     myDebugOption4:off  # Treated as `false`.
+  ///     myDebugOption5:on   # Also read as `false`.
+  bool isSet(String booleanPropertyKey, {bool defaultValue: false}) {
+    var value = _options[booleanPropertyKey];
+    if (value == null) {
+      return defaultValue;
+    }
+    return value == true;
+  }
+
+  void _readOptions(String contents) {
+    var doc = loadYaml(contents);
+    if (doc is YamlMap) {
+      doc.forEach((k, v) {
+        if (k is String) {
+          _options[k] = v;
+        }
+      });
+    }
+  }
+}
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 9fb70ba..b3a78e6 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
@@ -127,6 +127,9 @@
    */
   List<DartCompletionContributor> computeFast(
       DartCompletionRequest request, CompletionPerformance performance) {
+    bool isKeywordOrIdentifier(Token token) =>
+        token.type == TokenType.KEYWORD || token.type == TokenType.IDENTIFIER;
+
     return performance.logElapseTime('computeFast', () {
       CompilationUnit unit = context.parseCompilationUnit(source);
       request.unit = unit;
@@ -140,12 +143,22 @@
 
       var entity = request.target.entity;
       Token token = entity is AstNode ? entity.beginToken : entity;
-      if (token != null &&
-          token.offset <= request.offset &&
-          (token.type == TokenType.KEYWORD ||
-              token.type == TokenType.IDENTIFIER)) {
-        request.replacementOffset = token.offset;
-        request.replacementLength = token.length;
+      if (token != null && request.offset < token.offset) {
+        token = token.previous;
+      }
+      if (token != null) {
+        if (request.offset == token.offset && !isKeywordOrIdentifier(token)) {
+          // If the insertion point is at the beginning of the current token
+          // and the current token is not an identifier
+          // then check the previous token to see if it should be replaced
+          token = token.previous;
+        }
+        if (token != null && isKeywordOrIdentifier(token)) {
+          if (token.offset <= request.offset && request.offset <= token.end) {
+            request.replacementOffset = token.offset;
+            request.replacementLength = token.length;
+          }
+        }
       }
 
       List<DartCompletionContributor> todo = new List.from(contributors);
diff --git a/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart
index 7eca2b5..9cfbb0d 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/local_reference_contributor.dart
@@ -14,6 +14,7 @@
 import 'package:analysis_server/src/services/completion/local_suggestion_builder.dart';
 import 'package:analysis_server/src/services/completion/optype.dart';
 import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
@@ -182,7 +183,7 @@
     }
     paramBuf.write(')');
     protocol.Element element = createElement(
-        protocol.ElementKind.CONSTRUCTOR, elemId,
+        request.source, protocol.ElementKind.CONSTRUCTOR, elemId,
         parameters: paramBuf.toString());
     element.returnType = classDecl.name.name;
     CompletionSuggestion suggestion = new CompletionSuggestion(
@@ -277,8 +278,9 @@
     if (isCaseLabel ? includeCaseLabels : includeStatementLabels) {
       CompletionSuggestion suggestion = _addSuggestion(label.label);
       if (suggestion != null) {
-        suggestion.element =
-            _createElement(protocol.ElementKind.LABEL, label.label);
+        suggestion.element = createElement(
+            request.source, protocol.ElementKind.LABEL, label.label,
+            returnType: NO_RETURN_TYPE);
       }
     }
   }
@@ -331,17 +333,6 @@
     }
     return null;
   }
-
-  /**
-   * Create a new protocol Element for inclusion in a completion suggestion.
-   */
-  protocol.Element _createElement(
-      protocol.ElementKind kind, SimpleIdentifier id) {
-    String name = id.name;
-    int flags =
-        protocol.Element.makeFlags(isPrivate: Identifier.isPrivateName(name));
-    return new protocol.Element(kind, name, flags);
-  }
 }
 
 /**
@@ -386,7 +377,7 @@
   void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
     if (optype.includeReturnValueSuggestions) {
       CompletionSuggestion suggestion =
-          createFieldSuggestion(fieldDecl, varDecl);
+          createFieldSuggestion(request.source, fieldDecl, varDecl);
       if (suggestion != null) {
         request.addSuggestion(suggestion);
       }
@@ -547,7 +538,7 @@
         id, isDeprecated, relevance, typeName, classDecl: classDecl);
     if (suggestion != null) {
       request.addSuggestion(suggestion);
-      suggestion.element = createElement(elemKind, id,
+      suggestion.element = createElement(request.source, elemKind, id,
           isAbstract: isAbstract,
           isDeprecated: isDeprecated,
           parameters: param != null ? param.toSource() : null,
diff --git a/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart
index 8014dd4..324e1a7 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/local_suggestion_builder.dart
@@ -10,6 +10,7 @@
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/source.dart';
 
 const DYNAMIC = 'dynamic';
 
@@ -19,16 +20,28 @@
 /**
  * Create a new protocol Element for inclusion in a completion suggestion.
  */
-protocol.Element createElement(protocol.ElementKind kind, SimpleIdentifier id,
+protocol.Element createElement(
+    Source source, protocol.ElementKind kind, SimpleIdentifier id,
     {String parameters, TypeName returnType, bool isAbstract: false,
     bool isDeprecated: false}) {
-  String name = id != null ? id.name : '';
+  String name;
+  Location location;
+  if (id != null) {
+    name = id.name;
+    // TODO(danrubel) use lineInfo to determine startLine and startColumn
+    location = new Location(source.fullName, id.offset, id.length, 0, 0);
+  } else {
+    name = '';
+    location = new Location(source.fullName, -1, 0, 1, 0);
+  }
   int flags = protocol.Element.makeFlags(
       isAbstract: isAbstract,
       isDeprecated: isDeprecated,
       isPrivate: Identifier.isPrivateName(name));
   return new protocol.Element(kind, name, flags,
-      parameters: parameters, returnType: nameForType(returnType));
+      location: location,
+      parameters: parameters,
+      returnType: nameForType(returnType));
 }
 
 /**
@@ -36,13 +49,13 @@
  * Return the new suggestion or `null` if it could not be created.
  */
 CompletionSuggestion createFieldSuggestion(
-    FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
+    Source source, FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
   bool deprecated = isDeprecated(fieldDecl) || isDeprecated(varDecl);
   TypeName type = fieldDecl.fields.type;
   return createSuggestion(
       varDecl.name, deprecated, DART_RELEVANCE_LOCAL_FIELD, type,
       classDecl: fieldDecl.parent,
-      element: createElement(protocol.ElementKind.FIELD, varDecl.name,
+      element: createElement(source, protocol.ElementKind.FIELD, varDecl.name,
           returnType: type, isDeprecated: deprecated));
 }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/optype.dart b/pkg/analysis_server/lib/src/services/completion/optype.dart
index c9d88bcd..7ab13f9 100644
--- a/pkg/analysis_server/lib/src/services/completion/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/optype.dart
@@ -543,7 +543,6 @@
     if (identical(entity, node.expression)) {
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
-      optype.includeVoidReturnSuggestions = true;
     }
   }
 
@@ -553,6 +552,21 @@
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     }
+    if (identical(entity, node.rightBracket)) {
+      if (node.members.isNotEmpty) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+        optype.includeVoidReturnSuggestions = true;
+      }
+    }
+    if (entity is SwitchMember && entity != node.members.first) {
+      SwitchMember member = entity as SwitchMember;
+      if (offset <= member.offset) {
+          optype.includeReturnValueSuggestions = true;
+          optype.includeTypeNameSuggestions = true;
+          optype.includeVoidReturnSuggestions = true;
+      }
+    }
   }
 
   @override
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
index 5abb208..f3a9db4 100644
--- a/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/prefixed_element_contributor.dart
@@ -8,9 +8,12 @@
 
 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';
+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';
 
@@ -134,7 +137,7 @@
                 if (fieldName != null && fieldName.length > 0) {
                   if (!referencedFields.contains(fieldName)) {
                     CompletionSuggestion suggestion =
-                        createFieldSuggestion(member, varDecl);
+                        createFieldSuggestion(request.source, member, varDecl);
                     if (suggestion != null) {
                       request.addSuggestion(suggestion);
                     }
@@ -405,20 +408,8 @@
                 request.target.containingNode.parent is TypeName);
             modified = true;
             if (directive.deferredKeyword != null) {
-              String completion = 'loadLibrary';
-              CompletionSuggestion suggestion = new CompletionSuggestion(
-                  CompletionSuggestionKind.INVOCATION, DART_RELEVANCE_DEFAULT,
-                  completion, completion.length, 0, false, false,
-                  parameterNames: [],
-                  parameterTypes: [],
-                  requiredParameterCount: 0,
-                  hasNamedParameters: false,
-                  returnType: 'void');
-              suggestion.element = new protocol.Element(
-                  protocol.ElementKind.FUNCTION, completion,
-                  protocol.Element.makeFlags(),
-                  parameters: '()', returnType: 'void');
-              request.addSuggestion(suggestion);
+              FunctionElement loadLibFunct = library.loadLibraryFunction;
+              request.addSuggestion(createSuggestion(loadLibFunct));
             }
           }
         }
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 157a9e0..c6e376a 100644
--- a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
@@ -28,35 +28,10 @@
 CompletionSuggestion createSuggestion(Element element,
     {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
     int relevance: DART_RELEVANCE_DEFAULT, Source importForSource}) {
-  String nameForType(DartType type) {
-    if (type == null) {
-      return DYNAMIC;
-    }
-    String name = type.displayName;
-    if (name == null || name.length <= 0) {
-      return DYNAMIC;
-    }
-    //TODO (danrubel) include type arguments ??
-    return name;
+  if (element is ExecutableElement && element.isOperator) {
+    // Do not include operators in suggestions
+    return null;
   }
-
-  String returnType = null;
-  if (element is ExecutableElement) {
-    if (element.isOperator) {
-      // Do not include operators in suggestions
-      return null;
-    }
-    if (element is PropertyAccessorElement && element.isSetter) {
-      // no return type
-    } else {
-      returnType = nameForType(element.returnType);
-    }
-  } else if (element is VariableElement) {
-    returnType = nameForType(element.type);
-  } else if (element is FunctionTypeAliasElement) {
-    returnType = nameForType(element.returnType);
-  }
-
   String completion = element.displayName;
   bool isDeprecated = element.isDeprecated;
   CompletionSuggestion suggestion = new CompletionSuggestion(kind,
@@ -67,7 +42,7 @@
   if (enclosingElement is ClassElement) {
     suggestion.declaringType = enclosingElement.displayName;
   }
-  suggestion.returnType = returnType;
+  suggestion.returnType = getReturnTypeString(element);
   if (element is ExecutableElement && element is! PropertyAccessorElement) {
     suggestion.parameterNames = element.parameters
         .map((ParameterElement parameter) => parameter.name)
@@ -476,6 +451,12 @@
   @override
   visitCompilationUnitElement(CompilationUnitElement element) {
     element.visitChildren(this);
+    LibraryElement containingLibrary = element.library;
+    if (containingLibrary != null) {
+      for (var lib in containingLibrary.exportedLibraries) {
+        lib.visitChildren(this);
+      }
+    }
   }
 
   @override
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 9c5e9ba..cf87d27 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -399,13 +399,19 @@
       return;
     }
     Expression returnValue = (body as ExpressionFunctionBody).expression;
+    DartType returnValueType = returnValue.staticType;
+    String returnValueCode = _getNodeText(returnValue);
     // prepare prefix
     String prefix = utils.getNodePrefix(body.parent);
-    // add change
     String indent = utils.getIndent(1);
-    String returnSource = 'return ' + _getNodeText(returnValue);
-    String newBodySource = '{$eol$prefix$indent$returnSource;$eol$prefix}';
-    _addReplaceEdit(rangeNode(body), newBodySource);
+    // add change
+    String statementCode =
+        (returnValueType.isVoid ? '' : 'return ') + returnValueCode;
+    SourceBuilder sb = new SourceBuilder(file, body.offset);
+    sb.append('{$eol$prefix$indent$statementCode;');
+    sb.setExitOffset();
+    sb.append('$eol$prefix}');
+    _insertBuilder(sb, body.length);
     // add proposal
     _addAssist(DartAssistKind.CONVERT_INTO_BLOCK_BODY, []);
   }
@@ -423,13 +429,14 @@
       _coverageMarker();
       return;
     }
-    if (statements[0] is! ReturnStatement) {
-      _coverageMarker();
-      return;
-    }
-    ReturnStatement returnStatement = statements[0] as ReturnStatement;
+    Statement onlyStatement = statements.first;
     // prepare returned expression
-    Expression returnExpression = returnStatement.expression;
+    Expression returnExpression;
+    if (onlyStatement is ReturnStatement) {
+      returnExpression = onlyStatement.expression;
+    } else if (onlyStatement is ExpressionStatement) {
+      returnExpression = onlyStatement.expression;
+    }
     if (returnExpression == null) {
       _coverageMarker();
       return;
@@ -484,8 +491,8 @@
       // check number of references
       {
         int numOfReferences = 0;
-        AstVisitor visitor = new _SimpleIdentifierRecursiveAstVisitor(
-            (SimpleIdentifier node) {
+        AstVisitor visitor =
+            new _SimpleIdentifierRecursiveAstVisitor((SimpleIdentifier node) {
           if (node.staticElement == parameterElement) {
             numOfReferences++;
           }
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index 46ae81f..dde87a0 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -6,6 +6,7 @@
 
 import 'package:analysis_server/edit/fix/fix_core.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -15,13 +16,14 @@
  * reported after it's source was analyzed in the given [context]. The [plugin]
  * is used to get the list of fix contributors.
  */
-List<Fix> computeFixes(
-    ServerPlugin plugin, AnalysisContext context, AnalysisError error) {
+List<Fix> computeFixes(ServerPlugin plugin, ResourceProvider resourceProvider,
+    AnalysisContext context, AnalysisError error) {
   List<Fix> fixes = <Fix>[];
   List<FixContributor> contributors = plugin.fixContributors;
   for (FixContributor contributor in contributors) {
     try {
-      List<Fix> contributedFixes = contributor.computeFixes(context, error);
+      List<Fix> contributedFixes =
+          contributor.computeFixes(resourceProvider, context, error);
       if (contributedFixes != null) {
         fixes.addAll(contributedFixes);
       }
@@ -44,7 +46,8 @@
   static const ADD_FIELD_FORMAL_PARAMETERS = const FixKind(
       'ADD_FIELD_FORMAL_PARAMETERS', 30, "Add final field formal parameters");
   static const ADD_MISSING_PARAMETER_POSITIONAL = const FixKind(
-      'ADD_MISSING_PARAMETER_POSITIONAL', 31,
+      'ADD_MISSING_PARAMETER_POSITIONAL',
+      31,
       "Add optional positional parameter");
   static const ADD_MISSING_PARAMETER_REQUIRED = const FixKind(
       'ADD_MISSING_PARAMETER_REQUIRED', 30, "Add required parameter");
@@ -53,7 +56,8 @@
   static const ADD_PART_OF =
       const FixKind('ADD_PART_OF', 50, "Add 'part of' directive");
   static const ADD_SUPER_CONSTRUCTOR_INVOCATION = const FixKind(
-      'ADD_SUPER_CONSTRUCTOR_INVOCATION', 50,
+      'ADD_SUPER_CONSTRUCTOR_INVOCATION',
+      50,
       "Add super constructor {0} invocation");
   static const CHANGE_TO = const FixKind('CHANGE_TO', 49, "Change to '{0}'");
   static const CHANGE_TO_STATIC_ACCESS = const FixKind(
@@ -63,7 +67,8 @@
   static const CREATE_CONSTRUCTOR =
       const FixKind('CREATE_CONSTRUCTOR', 50, "Create constructor '{0}'");
   static const CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS = const FixKind(
-      'CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS', 50,
+      'CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS',
+      50,
       "Create constructor for final fields");
   static const CREATE_CONSTRUCTOR_SUPER = const FixKind(
       'CREATE_CONSTRUCTOR_SUPER', 50, "Create constructor to call {0}");
@@ -98,10 +103,12 @@
   static const REMOVE_DEAD_CODE =
       const FixKind('REMOVE_DEAD_CODE', 50, "Remove dead code");
   static const REMOVE_PARAMETERS_IN_GETTER_DECLARATION = const FixKind(
-      'REMOVE_PARAMETERS_IN_GETTER_DECLARATION', 50,
+      'REMOVE_PARAMETERS_IN_GETTER_DECLARATION',
+      50,
       "Remove parameters in getter declaration");
   static const REMOVE_PARENTHESIS_IN_GETTER_INVOCATION = const FixKind(
-      'REMOVE_PARENTHESIS_IN_GETTER_INVOCATION', 50,
+      'REMOVE_PARENTHESIS_IN_GETTER_INVOCATION',
+      50,
       "Remove parentheses in getter invocation");
   static const REMOVE_UNNECASSARY_CAST =
       const FixKind('REMOVE_UNNECASSARY_CAST', 50, "Remove unnecessary cast");
@@ -118,11 +125,13 @@
   static const REPLACE_VAR_WITH_DYNAMIC = const FixKind(
       'REPLACE_VAR_WITH_DYNAMIC', 50, "Replace 'var' with 'dynamic'");
   static const REPLACE_RETURN_TYPE_FUTURE = const FixKind(
-      'REPLACE_RETURN_TYPE_FUTURE', 50,
+      'REPLACE_RETURN_TYPE_FUTURE',
+      50,
       "Return 'Future' from 'async' function");
   static const USE_CONST = const FixKind('USE_CONST', 50, "Change to constant");
   static const USE_EFFECTIVE_INTEGER_DIVISION = const FixKind(
-      'USE_EFFECTIVE_INTEGER_DIVISION', 50,
+      'USE_EFFECTIVE_INTEGER_DIVISION',
+      50,
       "Use effective integer division ~/");
   static const USE_EQ_EQ_NULL =
       const FixKind('USE_EQ_EQ_NULL', 50, "Use == null instead of 'is Null'");
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 cb695b8..3c8f1a7 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -5,6 +5,7 @@
 library analysis_server.src.services.correction.fix_internal;
 
 import 'dart:collection';
+import 'dart:core' hide Resource;
 
 import 'package:analysis_server/edit/fix/fix_core.dart';
 import 'package:analysis_server/edit/fix/fix_dart.dart';
@@ -22,6 +23,7 @@
 import 'package:analysis_server/src/services/correction/strings.dart';
 import 'package:analysis_server/src/services/correction/util.dart';
 import 'package:analysis_server/src/services/search/hierarchy.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';
@@ -33,6 +35,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:path/path.dart';
+import 'package:path/path.dart' as ppp;
 
 /**
  * A predicate is a one-argument function that returns a boolean value.
@@ -44,8 +47,9 @@
  */
 class DefaultFixContributor extends DartFixContributor {
   @override
-  List<Fix> internalComputeFixes(CompilationUnit unit, AnalysisError error) {
-    FixProcessor processor = new FixProcessor(unit, error);
+  List<Fix> internalComputeFixes(ResourceProvider resourceProvider,
+      CompilationUnit unit, AnalysisError error) {
+    FixProcessor processor = new FixProcessor(resourceProvider, unit, error);
     return processor.compute();
   }
 }
@@ -56,6 +60,7 @@
 class FixProcessor {
   static const int MAX_LEVENSHTEIN_DISTANCE = 3;
 
+  final ResourceProvider resourceProvider;
   final CompilationUnit unit;
   final AnalysisError error;
   AnalysisContext context;
@@ -83,7 +88,7 @@
   AstNode node;
   AstNode coveredNode;
 
-  FixProcessor(this.unit, this.error) {
+  FixProcessor(this.resourceProvider, this.unit, this.error) {
     unitElement = unit.element;
     context = unitElement.context;
     unitSource = unitElement.source;
@@ -207,8 +212,7 @@
     if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) {
       _addFix_createConstructor_named();
     }
-    if (errorCode ==
-            StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
+    if (errorCode == StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE ||
         errorCode ==
             StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO ||
         errorCode ==
@@ -249,6 +253,7 @@
       bool isAsync = _addFix_addAsync();
       if (!isAsync) {
         _addFix_undefinedClassAccessor_useSimilar();
+        _addFix_createClass();
         _addFix_createField();
         _addFix_createGetter();
         _addFix_createFunction_forFunctionType();
@@ -423,7 +428,8 @@
         CorrectionUtils partUtils = new CorrectionUtils(partUnit);
         CorrectionUtils_InsertDesc desc = partUtils.getInsertDescTop();
         String libraryName = unitLibraryElement.name;
-        _addInsertEdit(desc.offset,
+        _addInsertEdit(
+            desc.offset,
             '${desc.prefix}part of $libraryName;$eol${desc.suffix}',
             partUnit.element);
         _addFix(DartFixKind.ADD_PART_OF, []);
@@ -440,17 +446,20 @@
   void _addFix_createClass() {
     Element prefixElement = null;
     String name = null;
+    SimpleIdentifier nameNode;
     if (node is SimpleIdentifier) {
       AstNode parent = node.parent;
       if (parent is PrefixedIdentifier) {
         PrefixedIdentifier prefixedIdentifier = parent;
         prefixElement = prefixedIdentifier.prefix.staticElement;
         parent = prefixedIdentifier.parent;
+        nameNode = prefixedIdentifier.identifier;
         name = prefixedIdentifier.identifier.name;
       } else {
-        name = (node as SimpleIdentifier).name;
+        nameNode = node;
+        name = nameNode.name;
       }
-      if (parent is! TypeName) {
+      if (!_mayBeTypeIdentifier(nameNode)) {
         return;
       }
     } else {
@@ -1050,8 +1059,7 @@
       if (source != null) {
         String file = source.fullName;
         if (isAbsolute(file)) {
-          String libName = removeEnd(source.shortName, '.dart');
-          libName = libName.replaceAll('_', '.');
+          String libName = _computeLibraryName(file);
           SourceEdit edit = new SourceEdit(0, 0, 'library $libName;$eol$eol');
           doSourceChange_addSourceEdit(change, context, source, edit);
           _addFix(DartFixKind.CREATE_FILE, [source.shortName]);
@@ -1344,10 +1352,8 @@
       if (prefix != null) {
         SourceRange range = rf.rangeStartLength(node, 0);
         _addReplaceEdit(range, '${prefix.displayName}.');
-        _addFix(DartFixKind.IMPORT_LIBRARY_PREFIX, [
-          libraryElement.displayName,
-          prefix.displayName
-        ]);
+        _addFix(DartFixKind.IMPORT_LIBRARY_PREFIX,
+            [libraryElement.displayName, prefix.displayName]);
         continue;
       }
       // may be update "show" directive
@@ -1657,7 +1663,8 @@
   void _addFix_undefinedClass_useSimilar() {
     if (_mayBeTypeIdentifier(node)) {
       String name = (node as SimpleIdentifier).name;
-      _ClosestElementFinder finder = new _ClosestElementFinder(name,
+      _ClosestElementFinder finder = new _ClosestElementFinder(
+          name,
           (Element element) => element is ClassElement,
           MAX_LEVENSHTEIN_DISTANCE);
       // find closest element
@@ -1790,7 +1797,8 @@
   void _addFix_undefinedFunction_useSimilar() {
     if (node is SimpleIdentifier) {
       String name = (node as SimpleIdentifier).name;
-      _ClosestElementFinder finder = new _ClosestElementFinder(name,
+      _ClosestElementFinder finder = new _ClosestElementFinder(
+          name,
           (Element element) => element is FunctionElement,
           MAX_LEVENSHTEIN_DISTANCE);
       // this library
@@ -2052,9 +2060,16 @@
    * Prepares proposal for creating function corresponding to the given
    * [FunctionType].
    */
-  void _addProposal_createFunction(FunctionType functionType, String name,
-      Source targetSource, int insertOffset, bool isStatic, String prefix,
-      String sourcePrefix, String sourceSuffix, Element target) {
+  void _addProposal_createFunction(
+      FunctionType functionType,
+      String name,
+      Source targetSource,
+      int insertOffset,
+      bool isStatic,
+      String prefix,
+      String sourcePrefix,
+      String sourceSuffix,
+      Element target) {
     // build method source
     String targetFile = targetSource.fullName;
     SourceBuilder sb = new SourceBuilder(targetFile, insertOffset);
@@ -2154,8 +2169,15 @@
       sourcePrefix = eol;
     }
     String sourceSuffix = eol;
-    _addProposal_createFunction(functionType, name, targetSource, insertOffset,
-        _inStaticContext(), prefix, sourcePrefix, sourceSuffix,
+    _addProposal_createFunction(
+        functionType,
+        name,
+        targetSource,
+        insertOffset,
+        _inStaticContext(),
+        prefix,
+        sourcePrefix,
+        sourceSuffix,
         targetClassElement);
     // add proposal
     _addFix(DartFixKind.CREATE_METHOD, [name]);
@@ -2274,6 +2296,51 @@
   }
 
   /**
+   * Computes the name of the library at the given [path].
+   * See https://www.dartlang.org/articles/style-guide/#names for conventions.
+   */
+  String _computeLibraryName(String path) {
+    Context pathContext = resourceProvider.pathContext;
+    String packageFolder = _computePackageFolder(path);
+    if (packageFolder == null) {
+      return pathContext.basenameWithoutExtension(path);
+    }
+    String packageName = pathContext.basename(packageFolder);
+    String relPath = pathContext.relative(path, from: packageFolder);
+    List<String> relPathParts = pathContext.split(relPath);
+    if (relPathParts.isNotEmpty) {
+      if (relPathParts[0].toLowerCase() == 'lib') {
+        relPathParts.removeAt(0);
+      }
+      {
+        String nameWithoutExt = pathContext.withoutExtension(relPathParts.last);
+        relPathParts[relPathParts.length - 1] = nameWithoutExt;
+      }
+    }
+    return packageName + '.' + relPathParts.join('.');
+  }
+
+  /**
+   * Returns the path of the folder which contains the given [path].
+   */
+  String _computePackageFolder(String path) {
+    Context pathContext = resourceProvider.pathContext;
+    String pubspecFolder = dirname(path);
+    while (true) {
+      if (resourceProvider
+          .getResource(pathContext.join(pubspecFolder, 'pubspec.yaml'))
+          .exists) {
+        return pubspecFolder;
+      }
+      String pubspecFolderNew = pathContext.dirname(pubspecFolder);
+      if (pubspecFolderNew == pubspecFolder) {
+        return null;
+      }
+      pubspecFolder = pubspecFolderNew;
+    }
+  }
+
+  /**
    * @return the string to display as the name of the given constructor in a proposal name.
    */
   String _getConstructorProposalName(ConstructorElement constructor) {
@@ -2611,24 +2678,27 @@
     return <String>['arg$index'];
   }
 
+  static bool _isNameOfType(String name) {
+    if (name.isEmpty) {
+      return false;
+    }
+    String firstLetter = name.substring(0, 1);
+    if (firstLetter.toUpperCase() != firstLetter) {
+      return false;
+    }
+    return true;
+  }
+
   /**
    * Returns `true` if [node] is a type name.
    */
   static bool _mayBeTypeIdentifier(AstNode node) {
     if (node is SimpleIdentifier) {
       AstNode parent = node.parent;
-      if (parent is Annotation) {
-        return true;
-      }
       if (parent is TypeName) {
         return true;
       }
-      if (parent is MethodInvocation) {
-        return parent.realTarget == node;
-      }
-      if (parent is PrefixedIdentifier) {
-        return parent.prefix == node;
-      }
+      return _isNameOfType(node.name);
     }
     return false;
   }
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
new file mode 100644
index 0000000..b12ecb1
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
@@ -0,0 +1,248 @@
+// 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.src.refactoring.organize_directives;
+
+import 'package:analysis_server/src/protocol.dart' hide AnalysisError, Element;
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'dart:math';
+
+/**
+ * Organizer of directives in the [unit].
+ */
+class DirectiveOrganizer {
+  final String initialCode;
+  final CompilationUnit unit;
+  final List<AnalysisError> errors;
+  final bool removeUnresolved;
+  final bool removeUnused;
+  String code;
+  String endOfLine;
+
+  DirectiveOrganizer(this.initialCode, this.unit, this.errors,
+      {this.removeUnresolved: true, this.removeUnused: true}) {
+    this.code = initialCode;
+    this.endOfLine = getEOL(code);
+  }
+
+  /**
+   * Return the [SourceEdit]s that organize directives in the [unit].
+   */
+  List<SourceEdit> organize() {
+    _organizeDirectives();
+    // prepare edits
+    List<SourceEdit> edits = <SourceEdit>[];
+    if (code != initialCode) {
+      int suffixLength = findCommonSuffix(initialCode, code);
+      SourceEdit edit = new SourceEdit(0, initialCode.length - suffixLength,
+          code.substring(0, code.length - suffixLength));
+      edits.add(edit);
+    }
+    return edits;
+  }
+
+  bool _isUnresolvedUri(UriBasedDirective directive) {
+    for (AnalysisError error in errors) {
+      if (error.errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST &&
+          directive.uri.offset == error.offset) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  bool _isUnusedImport(UriBasedDirective directive) {
+    for (AnalysisError error in errors) {
+      if (error.errorCode == HintCode.UNUSED_IMPORT &&
+          directive.uri.offset == error.offset) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * Oraganize all [Directive]s.
+   */
+  void _organizeDirectives() {
+    List<_DirectiveInfo> directives = [];
+    for (Directive directive in unit.directives) {
+      if (directive is UriBasedDirective) {
+        _DirectivePriority priority = getDirectivePriority(directive);
+        if (priority != null) {
+          int offset = directive.offset;
+          int length = directive.length;
+          String text = code.substring(offset, offset + length);
+          String uriContent = directive.uri.stringValue;
+          directives
+              .add(new _DirectiveInfo(directive, priority, uriContent, text));
+        }
+      }
+    }
+    // nothing to do
+    if (directives.isEmpty) {
+      return;
+    }
+    int firstDirectiveOffset = directives.first.directive.offset;
+    int lastDirectiveEnd = directives.last.directive.end;
+    // sort
+    directives.sort();
+    // append directives with grouping
+    String directivesCode;
+    {
+      StringBuffer sb = new StringBuffer();
+      _DirectivePriority currentPriority = null;
+      for (_DirectiveInfo directiveInfo in directives) {
+        if (removeUnresolved && _isUnresolvedUri(directiveInfo.directive)) {
+          continue;
+        }
+        if (removeUnused && _isUnusedImport(directiveInfo.directive)) {
+          continue;
+        }
+        if (currentPriority != directiveInfo.priority) {
+          if (sb.length != 0) {
+            sb.write(endOfLine);
+          }
+          currentPriority = directiveInfo.priority;
+        }
+        sb.write(directiveInfo.text);
+        sb.write(endOfLine);
+      }
+      directivesCode = sb.toString();
+      directivesCode = directivesCode.trimRight();
+    }
+    // append comment tokens which otherwise would be removed completely
+    {
+      bool firstCommentToken = true;
+      Token token = unit.beginToken;
+      while (token != null &&
+          token.type != TokenType.EOF &&
+          token.end < lastDirectiveEnd) {
+        Token commentToken = token.precedingComments;
+        while (commentToken != null) {
+          int offset = commentToken.offset;
+          int end = commentToken.end;
+          if (offset > firstDirectiveOffset && offset < lastDirectiveEnd) {
+            if (firstCommentToken) {
+              directivesCode += endOfLine;
+              firstCommentToken = false;
+            }
+            directivesCode += code.substring(offset, end) + endOfLine;
+          }
+          commentToken = commentToken.next;
+        }
+        token = token.next;
+      }
+    }
+    // prepare code
+    String beforeDirectives = code.substring(0, firstDirectiveOffset);
+    String afterDirectives = code.substring(lastDirectiveEnd);
+    code = beforeDirectives + directivesCode + afterDirectives;
+  }
+
+  static _DirectivePriority getDirectivePriority(UriBasedDirective directive) {
+    String uriContent = directive.uri.stringValue;
+    if (directive is ImportDirective) {
+      if (uriContent.startsWith("dart:")) {
+        return _DirectivePriority.IMPORT_SDK;
+      } else if (uriContent.startsWith("package:")) {
+        return _DirectivePriority.IMPORT_PKG;
+      } else if (uriContent.contains('://')) {
+        return _DirectivePriority.IMPORT_OTHER;
+      } else {
+        return _DirectivePriority.IMPORT_REL;
+      }
+    }
+    if (directive is ExportDirective) {
+      if (uriContent.startsWith("dart:")) {
+        return _DirectivePriority.EXPORT_SDK;
+      } else if (uriContent.startsWith("package:")) {
+        return _DirectivePriority.EXPORT_PKG;
+      } else if (uriContent.contains('://')) {
+        return _DirectivePriority.EXPORT_OTHER;
+      } else {
+        return _DirectivePriority.EXPORT_REL;
+      }
+    }
+    if (directive is PartDirective) {
+      return _DirectivePriority.PART;
+    }
+    return null;
+  }
+
+  /**
+   * Return the EOL to use for [code].
+   */
+  static String getEOL(String code) {
+    if (code.contains('\r\n')) {
+      return '\r\n';
+    } else {
+      return '\n';
+    }
+  }
+}
+
+class _DirectiveInfo implements Comparable<_DirectiveInfo> {
+  final UriBasedDirective directive;
+  final _DirectivePriority priority;
+  final String uri;
+  final String text;
+
+  _DirectiveInfo(this.directive, this.priority, this.uri, this.text);
+
+  @override
+  int compareTo(_DirectiveInfo other) {
+    if (priority == other.priority) {
+      return _compareUri(uri, other.uri);
+    }
+    return priority.ordinal - other.priority.ordinal;
+  }
+
+  @override
+  String toString() => '(priority=$priority; text=$text)';
+
+  static int _compareUri(String a, String b) {
+    List<String> aList = _splitUri(a);
+    List<String> bList = _splitUri(b);
+    int result;
+    if ((result = aList[0].compareTo(bList[0])) != 0) return result;
+    if ((result = aList[1].compareTo(bList[1])) != 0) return result;
+    return 0;
+  }
+
+  /**
+   * Split the given [uri] like `package:some.name/and/path.dart` into a list
+   * like `[package:some.name, and/path.dart]`.
+   */
+  static List<String> _splitUri(String uri) {
+    int index = uri.indexOf('/');
+    if (index == -1) {
+      return <String>[uri, ''];
+    }
+    return <String>[uri.substring(0, index), uri.substring(index + 1)];
+  }
+}
+
+class _DirectivePriority {
+  static const IMPORT_SDK = const _DirectivePriority('IMPORT_SDK', 0);
+  static const IMPORT_PKG = const _DirectivePriority('IMPORT_PKG', 1);
+  static const IMPORT_OTHER = const _DirectivePriority('IMPORT_OTHER', 2);
+  static const IMPORT_REL = const _DirectivePriority('IMPORT_REL', 3);
+  static const EXPORT_SDK = const _DirectivePriority('EXPORT_SDK', 4);
+  static const EXPORT_PKG = const _DirectivePriority('EXPORT_PKG', 5);
+  static const EXPORT_OTHER = const _DirectivePriority('EXPORT_OTHER', 6);
+  static const EXPORT_REL = const _DirectivePriority('EXPORT_REL', 7);
+  static const PART = const _DirectivePriority('PART', 8);
+
+  final String name;
+  final int ordinal;
+
+  const _DirectivePriority(this.name, this.ordinal);
+
+  @override
+  String toString() => name;
+}
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 1968766..d5abd12 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -11,10 +11,10 @@
 import 'package:analysis_server/src/protocol.dart';
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/local_file_index.dart';
-import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
 import 'package:analysis_server/uri/resolver_provider.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:plugin/plugin.dart';
 
@@ -81,9 +81,8 @@
     }
 
     analysisServer = new AnalysisServer(serverChannel, resourceProvider,
-        new OptimizingPubPackageMapProvider(resourceProvider, defaultSdk),
-        index, serverPlugin, analysisServerOptions, defaultSdk,
-        instrumentationService,
+        new PubPackageMapProvider(resourceProvider, defaultSdk), index,
+        serverPlugin, analysisServerOptions, defaultSdk, instrumentationService,
         contextManager: contextManager,
         packageResolverProvider: packageResolverProvider,
         rethrowExceptions: false);
diff --git a/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart b/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
deleted file mode 100644
index deeee77..0000000
--- a/pkg/analysis_server/lib/src/source/optimizing_pub_package_map_provider.dart
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library source.optimizing_pub_package_map_provider;
-
-import 'dart:core' hide Resource;
-
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/source/package_map_provider.dart';
-import 'package:analyzer/source/pub_package_map_provider.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
-
-/**
- * Extension of [PackageMapInfo] that tracks the modification timestamps of
- * pub dependencies.  This allows the analysis server to avoid making redundant
- * calls to "pub list" when nothing has changed.
- */
-class OptimizingPubPackageMapInfo extends PackageMapInfo {
-  /**
-   * Map from file path to the file's modification timestamp prior to running
-   * "pub list".  Since the set of dependencies is not always known prior to
-   * running "pub list", some or all of the dependencies may be missing from
-   * this map.
-   */
-  final Map<String, int> modificationTimes;
-
-  OptimizingPubPackageMapInfo(Map<String, List<Folder>> packageMap,
-      Set<String> dependencies, this.modificationTimes)
-      : super(packageMap, dependencies);
-
-  /**
-   * Return `true` if the given [path] is listed as a dependency, and we cannot
-   * prove using modification timestamps that it is unchanged.
-   * [resourceProvider] is used (if necessary) to read the [path]'s
-   * modification time.
-   */
-  bool isChangedDependency(String path, ResourceProvider resourceProvider) {
-    if (!dependencies.contains(path)) {
-      // Path is not a dependency.
-      return false;
-    }
-    int lastModificationTime = modificationTimes[path];
-    if (lastModificationTime != null) {
-      Resource resource = resourceProvider.getResource(path);
-      if (resource is File) {
-        try {
-          if (resource.modificationStamp == lastModificationTime) {
-            // Path is a dependency, but it hasn't changed since the last run
-            // of "pub list".
-            return false;
-          }
-        } on FileSystemException {
-          // Path is a dependency, but we can't read its timestamp.  Assume
-          // it's changed to be safe.
-        }
-      }
-    }
-    // Path is a dependency, and we couldn't prove that it hadn't changed.
-    // Assume it's changed to be safe.
-    return true;
-  }
-}
-
-/**
- * Extension of [PubPackageMapProvider] that outputs additional information to
- * allow the analysis server to avoid making redundant calls to "pub list" when
- * nothing has changed.
- */
-class OptimizingPubPackageMapProvider extends PubPackageMapProvider {
-  OptimizingPubPackageMapProvider(
-      ResourceProvider resourceProvider, DirectoryBasedDartSdk sdk, [RunPubList runPubList])
-      : super(resourceProvider, sdk, runPubList);
-
-  /**
-   * Compute a package map for the given folder by executing "pub list".  If
-   * [previousInfo] is provided, it is used as a guess of which files the
-   * package map is likely to depend on; the modification times of those files
-   * are captured prior to executing "pub list" so that they can be used to
-   * avoid making redundant calls to "pub list" in the future.
-   *
-   * Also, in the case where dependencies can't be determined because of an
-   * error, the dependencies from [previousInfo] will be preserved.
-   */
-  OptimizingPubPackageMapInfo computePackageMap(Folder folder,
-      [OptimizingPubPackageMapInfo previousInfo]) {
-    // Prior to running "pub list", read the modification timestamps of all of
-    // the old dependencies (if known).
-    Map<String, int> modificationTimes = <String, int>{};
-    if (previousInfo != null) {
-      for (String path in previousInfo.dependencies) {
-        Resource resource = resourceProvider.getResource(path);
-        if (resource is File) {
-          try {
-            modificationTimes[path] = resource.modificationStamp;
-          } on FileSystemException {
-            // File no longer exists.  Don't record a timestamp for it; this
-            // will ensure that if the file reappears, we will re-run "pub
-            // list" regardless of the timestamp it reappears with.
-          }
-        }
-      }
-    }
-
-    // Try running "pub list".
-    PackageMapInfo info = super.computePackageMap(folder);
-    if (info == null) {
-      // Computing the package map resulted in an error.  Merge the old
-      // dependencies with the new ones, if possible.
-      info = super.computePackageMapError(folder);
-      if (previousInfo != null) {
-        info.dependencies.addAll(previousInfo.dependencies);
-      }
-    }
-
-    // Discard any elements of modificationTimes that are no longer
-    // dependencies.
-    if (previousInfo != null) {
-      for (String dependency
-          in previousInfo.dependencies.difference(info.dependencies)) {
-        modificationTimes.remove(dependency);
-      }
-    }
-
-    // Bundle the modificationTimes with the other info.
-    return new OptimizingPubPackageMapInfo(
-        info.packageMap, info.dependencies, modificationTimes);
-  }
-
-  @override
-  PackageMapInfo computePackageMapError(Folder folder) {
-    // Return null to indicate to our override of computePackageMap that there
-    // was an error, so it can compute dependencies correctly.
-    return null;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 0a053bd..5b5236c 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -1042,7 +1042,7 @@
     List<Folder> folders = folderMap.keys.toList();
     folders.sort((Folder first, Folder second) =>
         first.shortName.compareTo(second.shortName));
-    AnalysisOptionsImpl options = analysisServer.contextManager.defaultOptions;
+    AnalysisOptionsImpl options = analysisServer.defaultContextOptions;
     ServerOperationQueue operationQueue = analysisServer.operationQueue;
 
     buffer.write('<h3>Analysis Domain</h3>');
@@ -1084,8 +1084,6 @@
       _writeOption(
           buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
       _writeOption(buffer, 'Cache size', options.cacheSize);
-      _writeOption(buffer, 'Enable null-aware operators',
-          options.enableNullAwareOperators);
       _writeOption(
           buffer, 'Enable strict call checks', options.enableStrictCallChecks);
       _writeOption(buffer, 'Generate hints', options.hint);
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index a9cb19b..2b14dd6 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,7 +6,7 @@
 environment:
   sdk: '>=1.9.0 <2.0.0'
 dependencies:
-  analyzer: '>=0.25.3-alpha.0 <0.26.0'
+  analyzer: '>=0.26.0-alpha.0 <0.27.0'
   args: '>=0.13.0 <0.14.0'
   dart_style: '>=0.1.7 <0.2.0'
   logging: any
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 14203c9..4cc0a2f 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -99,7 +99,7 @@
     // remove context, causes sending an "invalid file" error
     {
       Folder projectFolder = resourceProvider.getResource(projectPath);
-      server.contextManager.removeContext(projectFolder);
+      server.contextManager.callbacks.removeContext(projectFolder, <String>[]);
     }
     // wait for an error response
     return serverChannel.waitForResponse(request).then((Response response) {
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index 1de99e4..752ee27 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -28,19 +28,6 @@
     createProject();
   }
 
-  test_afterAnalysisComplete() async {
-    addTestFile('''
-main() {
-  var test = 0;
-  print(test);
-}
-''');
-    await waitForTasksFinished();
-    await _getNavigation(testFile, testCode.indexOf('test);'), 0);
-    assertHasRegion('test);');
-    assertHasTarget('test = 0');
-  }
-
   test_beforeAnalysisComplete() async {
     addTestFile('''
 main() {
@@ -68,6 +55,36 @@
     return _checkInvalid(file, -1, -1);
   }
 
+  test_multipleRegions() async {
+    addTestFile('''
+main() {
+  var aaa = 1;
+  var bbb = 2;
+  var ccc = 3;
+  var ddd = 4;
+  print(aaa + bbb + ccc + ddd);
+}
+''');
+    await waitForTasksFinished();
+    // request navigation
+    String navCode = ' + bbb + ';
+    await _getNavigation(testFile, testCode.indexOf(navCode), navCode.length);
+    // verify
+    {
+      assertHasRegion('aaa +');
+      assertHasTarget('aaa = 1');
+    }
+    {
+      assertHasRegion('bbb +');
+      assertHasTarget('bbb = 2');
+    }
+    {
+      assertHasRegion('ccc +');
+      assertHasTarget('ccc = 3');
+    }
+    assertNoRegionAt('ddd)');
+  }
+
   test_removeContextAfterRequest() async {
     addTestFile('''
 main() {
@@ -82,7 +99,7 @@
     // remove context, causes sending an "invalid file" error
     {
       Folder projectFolder = resourceProvider.getResource(projectPath);
-      server.contextManager.removeContext(projectFolder);
+      server.contextManager.callbacks.removeContext(projectFolder, <String>[]);
     }
     // wait for an error response
     Response response = await serverChannel.waitForResponse(request);
@@ -90,6 +107,32 @@
     expect(response.error.code, RequestErrorCode.GET_NAVIGATION_INVALID_FILE);
   }
 
+  test_zeroLength_end() async {
+    addTestFile('''
+main() {
+  var test = 0;
+  print(test);
+}
+''');
+    await waitForTasksFinished();
+    await _getNavigation(testFile, testCode.indexOf(');'), 0);
+    assertHasRegion('test);');
+    assertHasTarget('test = 0');
+  }
+
+  test_zeroLength_start() async {
+    addTestFile('''
+main() {
+  var test = 0;
+  print(test);
+}
+''');
+    await waitForTasksFinished();
+    await _getNavigation(testFile, testCode.indexOf('test);'), 0);
+    assertHasRegion('test);');
+    assertHasTarget('test = 0');
+  }
+
   _checkInvalid(String file, int offset, int length) async {
     Request request = _createGetNavigationRequest(file, offset, length);
     Response response = await serverChannel.sendRequest(request);
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index 6c440471ca..09de3e8 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -18,6 +18,155 @@
   defineReflectiveTests(AnalysisNotificationNavigationTest);
 }
 
+class AbstractNavigationTest extends AbstractAnalysisTest {
+  List<NavigationRegion> regions;
+  List<NavigationTarget> targets;
+  List<String> targetFiles;
+
+  NavigationRegion testRegion;
+  List<int> testTargetIndexes;
+  NavigationTarget testTarget;
+
+  /**
+   * Validates that there is a target in [testTargetIndexes] with [file],
+   * at [offset] and with the given [length].
+   */
+  void assertHasFileTarget(String file, int offset, int length) {
+    List<NavigationTarget> testTargets =
+        testTargetIndexes.map((int index) => targets[index]).toList();
+    for (NavigationTarget target in testTargets) {
+      if (targetFiles[target.fileIndex] == file &&
+          target.offset == offset &&
+          target.length == length) {
+        testTarget = target;
+        return;
+      }
+    }
+    fail(
+        'Expected to find target (file=$file; offset=$offset; length=$length) in\n'
+        '${testRegion} in\n' '${testTargets.join('\n')}');
+  }
+
+  void assertHasOperatorRegion(String regionSearch, int regionLength,
+      String targetSearch, int targetLength) {
+    assertHasRegion(regionSearch, regionLength);
+    assertHasTarget(targetSearch, targetLength);
+  }
+
+  /**
+   * Validates that there is a region at the offset of [search] in [testFile].
+   * If [length] is not specified explicitly, then length of an identifier
+   * from [search] is used.
+   */
+  void assertHasRegion(String search, [int length = -1]) {
+    int offset = findOffset(search);
+    if (length == -1) {
+      length = findIdentifierLength(search);
+    }
+    findRegion(offset, length, true);
+  }
+
+  /**
+   * Validates that there is a region at the offset of [search] in [testFile]
+   * with the given [length] or the length of [search].
+   */
+  void assertHasRegionString(String search, [int length = -1]) {
+    int offset = findOffset(search);
+    if (length == -1) {
+      length = search.length;
+    }
+    findRegion(offset, length, true);
+  }
+
+  /**
+   * Validates that there is an identifier region at [regionSearch] with target
+   * at [targetSearch].
+   */
+  void assertHasRegionTarget(String regionSearch, String targetSearch) {
+    assertHasRegion(regionSearch);
+    assertHasTarget(targetSearch);
+  }
+
+  /**
+   * Validates that there is a target in [testTargets]  with [testFile], at the
+   * offset of [search] in [testFile], and with the given [length] or the length
+   * of an leading identifier in [search].
+   */
+  void assertHasTarget(String search, [int length = -1]) {
+    int offset = findOffset(search);
+    if (length == -1) {
+      length = findIdentifierLength(search);
+    }
+    assertHasFileTarget(testFile, offset, length);
+  }
+
+  /**
+   * Validates that there is no a region at [search] and with the given
+   * [length].
+   */
+  void assertNoRegion(String search, int length) {
+    int offset = findOffset(search);
+    findRegion(offset, length, false);
+  }
+
+  /**
+   * Validates that there is no a region at [search] with any length.
+   */
+  void assertNoRegionAt(String search) {
+    int offset = findOffset(search);
+    findRegion(offset, -1, false);
+  }
+
+  /**
+   * Validates that there is no a region for [search] string.
+   */
+  void assertNoRegionString(String search) {
+    int offset = findOffset(search);
+    int length = search.length;
+    findRegion(offset, length, false);
+  }
+
+  void assertRegionsSorted() {
+    int lastEnd = -1;
+    for (NavigationRegion region in regions) {
+      int offset = region.offset;
+      if (offset < lastEnd) {
+        fail('$lastEnd was expected to be > $offset in\n' + regions.join('\n'));
+      }
+      lastEnd = offset + region.length;
+    }
+  }
+
+  /**
+   * Finds the navigation region with the given [offset] and [length].
+   * If [length] is `-1`, then it is ignored.
+   *
+   * If [exists] is `true`, then fails if such region does not exist.
+   * Otherwise remembers this it into [testRegion].
+   * Also fills [testTargets] with its targets.
+   *
+   * If [exists] is `false`, then fails if such region exists.
+   */
+  void findRegion(int offset, int length, bool exists) {
+    for (NavigationRegion region in regions) {
+      if (region.offset == offset &&
+          (length == -1 || region.length == length)) {
+        if (exists == false) {
+          fail('Not expected to find (offset=$offset; length=$length) in\n'
+              '${regions.join('\n')}');
+        }
+        testRegion = region;
+        testTargetIndexes = region.targets;
+        return;
+      }
+    }
+    if (exists == true) {
+      fail('Expected to find (offset=$offset; length=$length) in\n'
+          '${regions.join('\n')}');
+    }
+  }
+}
+
 @reflectiveTest
 class AnalysisNotificationNavigationTest extends AbstractNavigationTest {
   Future prepareNavigation() {
@@ -295,6 +444,23 @@
     });
   }
 
+  test_inComment() async {
+    addTestFile('''
+class FirstClass {}
+class SecondClass {
+  /**
+   * Return a [FirstClass] object equivalent to this object in every other way.
+   */
+  convert() {
+    return new FirstClass();
+  }
+}
+''');
+    await prepareNavigation();
+    assertHasRegionTarget('FirstClass]', 'FirstClass {');
+    assertHasRegionTarget('FirstClass(', 'FirstClass {');
+  }
+
   test_instanceCreation_implicit() {
     addTestFile('''
 class A {
@@ -638,152 +804,3 @@
     });
   }
 }
-
-class AbstractNavigationTest extends AbstractAnalysisTest {
-  List<NavigationRegion> regions;
-  List<NavigationTarget> targets;
-  List<String> targetFiles;
-
-  NavigationRegion testRegion;
-  List<int> testTargetIndexes;
-  NavigationTarget testTarget;
-
-  /**
-   * Validates that there is a target in [testTargetIndexes] with [file],
-   * at [offset] and with the given [length].
-   */
-  void assertHasFileTarget(String file, int offset, int length) {
-    List<NavigationTarget> testTargets =
-        testTargetIndexes.map((int index) => targets[index]).toList();
-    for (NavigationTarget target in testTargets) {
-      if (targetFiles[target.fileIndex] == file &&
-          target.offset == offset &&
-          target.length == length) {
-        testTarget = target;
-        return;
-      }
-    }
-    fail(
-        'Expected to find target (file=$file; offset=$offset; length=$length) in\n'
-        '${testRegion} in\n' '${testTargets.join('\n')}');
-  }
-
-  void assertHasOperatorRegion(String regionSearch, int regionLength,
-      String targetSearch, int targetLength) {
-    assertHasRegion(regionSearch, regionLength);
-    assertHasTarget(targetSearch, targetLength);
-  }
-
-  /**
-   * Validates that there is a region at the offset of [search] in [testFile].
-   * If [length] is not specified explicitly, then length of an identifier
-   * from [search] is used.
-   */
-  void assertHasRegion(String search, [int length = -1]) {
-    int offset = findOffset(search);
-    if (length == -1) {
-      length = findIdentifierLength(search);
-    }
-    findRegion(offset, length, true);
-  }
-
-  /**
-   * Validates that there is a region at the offset of [search] in [testFile]
-   * with the given [length] or the length of [search].
-   */
-  void assertHasRegionString(String search, [int length = -1]) {
-    int offset = findOffset(search);
-    if (length == -1) {
-      length = search.length;
-    }
-    findRegion(offset, length, true);
-  }
-
-  /**
-   * Validates that there is an identifier region at [regionSearch] with target
-   * at [targetSearch].
-   */
-  void assertHasRegionTarget(String regionSearch, String targetSearch) {
-    assertHasRegion(regionSearch);
-    assertHasTarget(targetSearch);
-  }
-
-  /**
-   * Validates that there is a target in [testTargets]  with [testFile], at the
-   * offset of [search] in [testFile], and with the given [length] or the length
-   * of an leading identifier in [search].
-   */
-  void assertHasTarget(String search, [int length = -1]) {
-    int offset = findOffset(search);
-    if (length == -1) {
-      length = findIdentifierLength(search);
-    }
-    assertHasFileTarget(testFile, offset, length);
-  }
-
-  /**
-   * Validates that there is no a region at [search] and with the given
-   * [length].
-   */
-  void assertNoRegion(String search, int length) {
-    int offset = findOffset(search);
-    findRegion(offset, length, false);
-  }
-
-  /**
-   * Validates that there is no a region at [search] with any length.
-   */
-  void assertNoRegionAt(String search) {
-    int offset = findOffset(search);
-    findRegion(offset, -1, false);
-  }
-
-  /**
-   * Validates that there is no a region for [search] string.
-   */
-  void assertNoRegionString(String search) {
-    int offset = findOffset(search);
-    int length = search.length;
-    findRegion(offset, length, false);
-  }
-
-  void assertRegionsSorted() {
-    int lastEnd = -1;
-    for (NavigationRegion region in regions) {
-      int offset = region.offset;
-      if (offset < lastEnd) {
-        fail('$lastEnd was expected to be > $offset in\n' + regions.join('\n'));
-      }
-      lastEnd = offset + region.length;
-    }
-  }
-
-  /**
-   * Finds the navigation region with the given [offset] and [length].
-   * If [length] is `-1`, then it is ignored.
-   *
-   * If [exists] is `true`, then fails if such region does not exist.
-   * Otherwise remembers this it into [testRegion].
-   * Also fills [testTargets] with its targets.
-   *
-   * If [exists] is `false`, then fails if such region exists.
-   */
-  void findRegion(int offset, int length, bool exists) {
-    for (NavigationRegion region in regions) {
-      if (region.offset == offset &&
-          (length == -1 || region.length == length)) {
-        if (exists == false) {
-          fail('Not expected to find (offset=$offset; length=$length) in\n'
-              '${regions.join('\n')}');
-        }
-        testRegion = region;
-        testTargetIndexes = region.targets;
-        return;
-      }
-    }
-    if (exists == true) {
-      fail('Expected to find (offset=$offset; length=$length) in\n'
-          '${regions.join('\n')}');
-    }
-  }
-}
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index af43b51..d81f338 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -7,12 +7,9 @@
 import 'dart:collection';
 
 import 'package:analysis_server/src/context_manager.dart';
-import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
-import 'package:analysis_server/uri/resolver_provider.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -55,7 +52,9 @@
    */
   static const String TEST_NAME = 'test';
 
-  TestContextManager manager;
+  ContextManagerImpl manager;
+
+  TestContextManagerCallbacks callbacks;
 
   MemoryResourceProvider resourceProvider;
 
@@ -84,14 +83,40 @@
   void setUp() {
     resourceProvider = new MemoryResourceProvider();
     packageMapProvider = new MockPackageMapProvider();
-    manager = new TestContextManager(
-        resourceProvider, providePackageResolver, packageMapProvider);
+    manager = new ContextManagerImpl(resourceProvider, providePackageResolver,
+        packageMapProvider, InstrumentationService.NULL_SERVICE);
+    callbacks = new TestContextManagerCallbacks(resourceProvider);
+    manager.callbacks = callbacks;
     resourceProvider.newFolder(projPath);
-    AbstractContextManager.ENABLE_PACKAGESPEC_SUPPORT = true;
+    ContextManagerImpl.ENABLE_PACKAGESPEC_SUPPORT = true;
   }
 
   void tearDown() {
-    AbstractContextManager.ENABLE_PACKAGESPEC_SUPPORT = false;
+    ContextManagerImpl.ENABLE_PACKAGESPEC_SUPPORT = false;
+  }
+
+  void test_contextsInAnalysisRoot_nestedContext() {
+    String subProjPath = join(projPath, 'subproj');
+    Folder subProjFolder = resourceProvider.newFolder(subProjPath);
+    resourceProvider.newFile(join(subProjPath, 'pubspec.yaml'), 'contents');
+    String subProjFilePath = join(subProjPath, 'file.dart');
+    resourceProvider.newFile(subProjFilePath, 'contents');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    // Make sure that there really are contexts for both the main project and
+    // the subproject.
+    Folder projFolder = resourceProvider.getFolder(projPath);
+    ContextInfo projContextInfo = manager.getContextInfoFor(projFolder);
+    expect(projContextInfo, isNotNull);
+    expect(projContextInfo.folder, projFolder);
+    ContextInfo subProjContextInfo = manager.getContextInfoFor(subProjFolder);
+    expect(subProjContextInfo, isNotNull);
+    expect(subProjContextInfo.folder, subProjFolder);
+    expect(projContextInfo.context != subProjContextInfo.context, isTrue);
+    // Check that contextsInAnalysisRoot() works.
+    List<AnalysisContext> contexts = manager.contextsInAnalysisRoot(projFolder);
+    expect(contexts, hasLength(2));
+    expect(contexts, contains(projContextInfo.context));
+    expect(contexts, contains(subProjContextInfo.context));
   }
 
   test_ignoreFilesInPackagesFolder() {
@@ -103,12 +128,12 @@
     resourceProvider.newFile(filePath1, 'contents');
     // "packages" files are ignored initially
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    expect(manager.currentContextFilePaths[projPath], isEmpty);
+    expect(callbacks.currentContextFilePaths[projPath], isEmpty);
     // "packages" files are ignored during watch
     String filePath2 = posix.join(projPath, 'packages', 'file2.dart');
     resourceProvider.newFile(filePath2, 'contents');
     return pumpEventQueue().then((_) {
-      expect(manager.currentContextFilePaths[projPath], isEmpty);
+      expect(callbacks.currentContextFilePaths[projPath], isEmpty);
     });
   }
 
@@ -125,6 +150,21 @@
     expect(manager.isInAnalysisRoot('$excludedFolder/test.dart'), isFalse);
   }
 
+  void test_isInAnalysisRoot_inNestedContext() {
+    String subProjPath = join(projPath, 'subproj');
+    Folder subProjFolder = resourceProvider.newFolder(subProjPath);
+    resourceProvider.newFile(join(subProjPath, 'pubspec.yaml'), 'contents');
+    String subProjFilePath = join(subProjPath, 'file.dart');
+    resourceProvider.newFile(subProjFilePath, 'contents');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    // Make sure that there really is a context for the subproject.
+    ContextInfo subProjContextInfo = manager.getContextInfoFor(subProjFolder);
+    expect(subProjContextInfo, isNotNull);
+    expect(subProjContextInfo.folder, subProjFolder);
+    // Check that isInAnalysisRoot() works.
+    expect(manager.isInAnalysisRoot(subProjFilePath), isTrue);
+  }
+
   void test_isInAnalysisRoot_inRoot() {
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     expect(manager.isInAnalysisRoot('$projPath/test.dart'), isTrue);
@@ -135,98 +175,17 @@
     expect(manager.isInAnalysisRoot('/test.dart'), isFalse);
   }
 
-  test_refresh_folder_with_packagespec() {
-    // create a context with a .packages file
-    String packagespecFile = posix.join(projPath, '.packages');
-    resourceProvider.newFile(packagespecFile, '');
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    return pumpEventQueue().then((_) {
-      expect(manager.currentContextPaths.toList(), [projPath]);
-      manager.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(manager.currentContextPaths.toList(), [projPath]);
-        expect(manager.currentContextTimestamps[projPath], manager.now);
-      });
-    });
-  }
-
-  test_refresh_folder_with_packagespec_subfolders() {
-    // Create a folder with no .packages file, containing two subfolders with
-    // .packages files.
-    String subdir1Path = posix.join(projPath, 'subdir1');
-    String subdir2Path = posix.join(projPath, 'subdir2');
-    String packagespec1Path = posix.join(subdir1Path, '.packages');
-    String packagespec2Path = posix.join(subdir2Path, '.packages');
-    resourceProvider.newFile(packagespec1Path, '');
-    resourceProvider.newFile(packagespec2Path, '');
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    return pumpEventQueue().then((_) {
-      expect(manager.currentContextPaths.toSet(),
-          [subdir1Path, subdir2Path, projPath].toSet());
-      manager.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(manager.currentContextPaths.toSet(),
-            [subdir1Path, subdir2Path, projPath].toSet());
-        expect(manager.currentContextTimestamps[projPath], manager.now);
-        expect(manager.currentContextTimestamps[subdir1Path], manager.now);
-        expect(manager.currentContextTimestamps[subdir2Path], manager.now);
-      });
-    });
-  }
-
-  test_refresh_folder_with_pubspec() {
-    // create a context with a pubspec.yaml file
-    String pubspecPath = posix.join(projPath, 'pubspec.yaml');
-    resourceProvider.newFile(pubspecPath, 'pubspec');
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    return pumpEventQueue().then((_) {
-      expect(manager.currentContextPaths.toList(), [projPath]);
-      manager.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(manager.currentContextPaths.toList(), [projPath]);
-        expect(manager.currentContextTimestamps[projPath], manager.now);
-      });
-    });
-  }
-
-  test_refresh_folder_with_pubspec_subfolders() {
-    // Create a folder with no pubspec.yaml, containing two subfolders with
-    // pubspec.yaml files.
-    String subdir1Path = posix.join(projPath, 'subdir1');
-    String subdir2Path = posix.join(projPath, 'subdir2');
-    String pubspec1Path = posix.join(subdir1Path, 'pubspec.yaml');
-    String pubspec2Path = posix.join(subdir2Path, 'pubspec.yaml');
-    resourceProvider.newFile(pubspec1Path, 'pubspec');
-    resourceProvider.newFile(pubspec2Path, 'pubspec');
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    return pumpEventQueue().then((_) {
-      expect(manager.currentContextPaths.toSet(),
-          [subdir1Path, subdir2Path, projPath].toSet());
-      manager.now++;
-      manager.refresh(null);
-      return pumpEventQueue().then((_) {
-        expect(manager.currentContextPaths.toSet(),
-            [subdir1Path, subdir2Path, projPath].toSet());
-        expect(manager.currentContextTimestamps[projPath], manager.now);
-        expect(manager.currentContextTimestamps[subdir1Path], manager.now);
-        expect(manager.currentContextTimestamps[subdir2Path], manager.now);
-      });
-    });
-  }
-
   test_path_filter() async {
     // Setup context.
     Folder root = resourceProvider.newFolder(projPath);
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    expect(manager.currentContextFilePaths[projPath], isEmpty);
+    expect(callbacks.currentContextFilePaths[projPath], isEmpty);
     // Set ignore patterns for context.
+    ContextInfo rootInfo = manager.getContextInfoFor(root);
     manager.setIgnorePatternsForContext(
-        root, ['sdk_ext/**', 'lib/ignoreme.dart']);
+        rootInfo, ['sdk_ext/**', 'lib/ignoreme.dart']);
     // Start creating files.
-    newFile([projPath, AbstractContextManager.PUBSPEC_NAME]);
+    newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
     String libPath = newFolder([projPath, LIB_NAME]);
     newFile([libPath, 'main.dart']);
     newFile([libPath, 'ignoreme.dart']);
@@ -237,7 +196,8 @@
     // Pump event loop so new files are discovered and added to context.
     await pumpEventQueue();
     // Verify that ignored files were ignored.
-    Map<String, int> fileTimestamps = manager.currentContextFilePaths[projPath];
+    Map<String, int> fileTimestamps =
+        callbacks.currentContextFilePaths[projPath];
     expect(fileTimestamps, isNotEmpty);
     List<String> files = fileTimestamps.keys.toList();
     expect(files.length, equals(1));
@@ -263,13 +223,186 @@
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // Verify that analysis options was parsed and the ignore patterns applied.
-    Map<String, int> fileTimestamps = manager.currentContextFilePaths[projPath];
+    Map<String, int> fileTimestamps =
+        callbacks.currentContextFilePaths[projPath];
     expect(fileTimestamps, isNotEmpty);
     List<String> files = fileTimestamps.keys.toList();
     expect(files.length, equals(1));
     expect(files[0], equals('/my/proj/lib/main.dart'));
   }
 
+  test_path_filter_child_contexts_option() async {
+    // Create files.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    newFile([libPath, 'main.dart']);
+    newFile([libPath, 'pubspec.yaml'], r'''
+name: foobar
+''');
+    String otherLibPath = newFolder([projPath, 'other_lib']);
+    newFile([otherLibPath, 'entry.dart']);
+    newFile([otherLibPath, 'pubspec.yaml'], r'''
+name: other_lib
+''');
+    // Setup analysis options file with ignore list that ignores the 'other_lib'
+    // directory by name.
+    newFile([projPath, '.analysis_options'], r'''
+analyzer:
+  exclude:
+    - 'other_lib'
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    // Verify that the context in other_lib wasn't created and that the
+    // context in lib was created.
+    var contexts = manager.contextsInAnalysisRoot(
+        resourceProvider.newFolder(projPath));
+    expect(contexts.length, 2);
+    expect(contexts[0].name, equals('/my/proj'));
+    expect(contexts[1].name, equals('/my/proj/lib'));
+  }
+
+  test_path_filter_wildcard_child_contexts_option() async {
+    // Create files.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    newFile([libPath, 'main.dart']);
+    newFile([libPath, 'pubspec.yaml'], r'''
+name: foobar
+''');
+    String otherLibPath = newFolder([projPath, 'other_lib']);
+    newFile([otherLibPath, 'entry.dart']);
+    newFile([otherLibPath, 'pubspec.yaml'], r'''
+name: other_lib
+''');
+    // Setup analysis options file with ignore list that ignores 'other_lib'
+    // and all immediate children.
+    newFile([projPath, '.analysis_options'], r'''
+analyzer:
+  exclude:
+    - 'other_lib/*'
+''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    // Verify that the context in other_lib wasn't created and that the
+    // context in lib was created.
+    var contexts = manager.contextsInAnalysisRoot(
+        resourceProvider.newFolder(projPath));
+    expect(contexts.length, 2);
+    expect(contexts[0].name, equals('/my/proj'));
+    expect(contexts[1].name, equals('/my/proj/lib'));
+  }
+
+  test_path_filter_recursive_wildcard_child_contexts_option() async {
+    // Create files.
+    String libPath = newFolder([projPath, LIB_NAME]);
+    newFile([libPath, 'main.dart']);
+    newFile([libPath, 'pubspec.yaml'], r'''
+  name: foobar
+  ''');
+    String otherLibPath = newFolder([projPath, 'other_lib']);
+    newFile([otherLibPath, 'entry.dart']);
+    newFile([otherLibPath, 'pubspec.yaml'], r'''
+  name: other_lib
+  ''');
+    // Setup analysis options file with ignore list that ignores 'other_lib'
+    // and all descendants.
+    newFile([projPath, '.analysis_options'], r'''
+analyzer:
+  exclude:
+    - 'other_lib/**'
+  ''');
+    // Setup context.
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    // Verify that the context in other_lib wasn't created and that the
+    // context in lib was created.
+    var contexts = manager.contextsInAnalysisRoot(
+        resourceProvider.newFolder(projPath));
+    expect(contexts.length, 2);
+    expect(contexts[0].name, equals('/my/proj'));
+    expect(contexts[1].name, equals('/my/proj/lib'));
+  }
+
+  test_refresh_folder_with_packagespec() {
+    // create a context with a .packages file
+    String packagespecFile = posix.join(projPath, '.packages');
+    resourceProvider.newFile(packagespecFile, '');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    return pumpEventQueue().then((_) {
+      expect(callbacks.currentContextPaths.toList(), [projPath]);
+      callbacks.now++;
+      manager.refresh(null);
+      return pumpEventQueue().then((_) {
+        expect(callbacks.currentContextPaths.toList(), [projPath]);
+        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
+      });
+    });
+  }
+
+  test_refresh_folder_with_packagespec_subfolders() {
+    // Create a folder with no .packages file, containing two subfolders with
+    // .packages files.
+    String subdir1Path = posix.join(projPath, 'subdir1');
+    String subdir2Path = posix.join(projPath, 'subdir2');
+    String packagespec1Path = posix.join(subdir1Path, '.packages');
+    String packagespec2Path = posix.join(subdir2Path, '.packages');
+    resourceProvider.newFile(packagespec1Path, '');
+    resourceProvider.newFile(packagespec2Path, '');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    return pumpEventQueue().then((_) {
+      expect(callbacks.currentContextPaths.toSet(),
+          [subdir1Path, subdir2Path, projPath].toSet());
+      callbacks.now++;
+      manager.refresh(null);
+      return pumpEventQueue().then((_) {
+        expect(callbacks.currentContextPaths.toSet(),
+            [subdir1Path, subdir2Path, projPath].toSet());
+        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
+        expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now);
+        expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now);
+      });
+    });
+  }
+
+  test_refresh_folder_with_pubspec() {
+    // create a context with a pubspec.yaml file
+    String pubspecPath = posix.join(projPath, 'pubspec.yaml');
+    resourceProvider.newFile(pubspecPath, 'pubspec');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    return pumpEventQueue().then((_) {
+      expect(callbacks.currentContextPaths.toList(), [projPath]);
+      callbacks.now++;
+      manager.refresh(null);
+      return pumpEventQueue().then((_) {
+        expect(callbacks.currentContextPaths.toList(), [projPath]);
+        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
+      });
+    });
+  }
+
+  test_refresh_folder_with_pubspec_subfolders() {
+    // Create a folder with no pubspec.yaml, containing two subfolders with
+    // pubspec.yaml files.
+    String subdir1Path = posix.join(projPath, 'subdir1');
+    String subdir2Path = posix.join(projPath, 'subdir2');
+    String pubspec1Path = posix.join(subdir1Path, 'pubspec.yaml');
+    String pubspec2Path = posix.join(subdir2Path, 'pubspec.yaml');
+    resourceProvider.newFile(pubspec1Path, 'pubspec');
+    resourceProvider.newFile(pubspec2Path, 'pubspec');
+    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+    return pumpEventQueue().then((_) {
+      expect(callbacks.currentContextPaths.toSet(),
+          [subdir1Path, subdir2Path, projPath].toSet());
+      callbacks.now++;
+      manager.refresh(null);
+      return pumpEventQueue().then((_) {
+        expect(callbacks.currentContextPaths.toSet(),
+            [subdir1Path, subdir2Path, projPath].toSet());
+        expect(callbacks.currentContextTimestamps[projPath], callbacks.now);
+        expect(callbacks.currentContextTimestamps[subdir1Path], callbacks.now);
+        expect(callbacks.currentContextTimestamps[subdir2Path], callbacks.now);
+      });
+    });
+  }
+
   test_refresh_oneContext() {
     // create two contexts with pubspec.yaml files
     String pubspecPath = posix.join(projPath, 'pubspec.yaml');
@@ -283,14 +416,14 @@
     List<String> roots = <String>[projPath, proj2Path];
     manager.setRoots(roots, <String>[], <String, String>{});
     return pumpEventQueue().then((_) {
-      expect(manager.currentContextPaths.toList(), unorderedEquals(roots));
-      int then = manager.now;
-      manager.now++;
+      expect(callbacks.currentContextPaths.toList(), unorderedEquals(roots));
+      int then = callbacks.now;
+      callbacks.now++;
       manager.refresh([resourceProvider.getResource(proj2Path)]);
       return pumpEventQueue().then((_) {
-        expect(manager.currentContextPaths.toList(), unorderedEquals(roots));
-        expect(manager.currentContextTimestamps[projPath], then);
-        expect(manager.currentContextTimestamps[proj2Path], manager.now);
+        expect(callbacks.currentContextPaths.toList(), unorderedEquals(roots));
+        expect(callbacks.currentContextTimestamps[projPath], then);
+        expect(callbacks.currentContextTimestamps[proj2Path], callbacks.now);
       });
     });
   }
@@ -300,7 +433,7 @@
     resourceProvider.newFile(filePath, 'contents');
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // verify
-    var filePaths = manager.currentContextFilePaths[projPath];
+    var filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(1));
     expect(filePaths, contains(filePath));
     List<AnalysisContext> contextsInAnalysisRoot =
@@ -318,7 +451,7 @@
     resourceProvider.newFile(filePath, 'contents');
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // verify
-    var filePaths = manager.currentContextFilePaths[projPath];
+    var filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(1));
     expect(filePaths, contains(filePath));
   }
@@ -328,7 +461,7 @@
     resourceProvider.newDummyLink(filePath);
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // verify
-    var filePaths = manager.currentContextFilePaths[projPath];
+    var filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, isEmpty);
   }
 
@@ -336,9 +469,9 @@
     String examplePath = newFolder([projPath, EXAMPLE_NAME]);
     String libPath = newFolder([projPath, LIB_NAME]);
 
-    newFile([projPath, AbstractContextManager.PACKAGE_SPEC_NAME]);
+    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
     newFile([libPath, 'main.dart']);
-    newFile([examplePath, AbstractContextManager.PACKAGE_SPEC_NAME]);
+    newFile([examplePath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
     newFile([examplePath, 'example.dart']);
 
     packageMapProvider.packageMap['proj'] =
@@ -346,15 +479,15 @@
 
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
-    expect(manager.currentContextPaths, hasLength(2));
+    expect(callbacks.currentContextPaths, hasLength(2));
 
-    expect(manager.currentContextPaths, contains(projPath));
-    Set<Source> projSources = manager.currentContextSources[projPath];
+    expect(callbacks.currentContextPaths, contains(projPath));
+    Set<Source> projSources = callbacks.currentContextSources[projPath];
     expect(projSources, hasLength(1));
     expect(projSources.first.uri.toString(), 'file:///my/proj/lib/main.dart');
 
-    expect(manager.currentContextPaths, contains(examplePath));
-    Set<Source> exampleSources = manager.currentContextSources[examplePath];
+    expect(callbacks.currentContextPaths, contains(examplePath));
+    Set<Source> exampleSources = callbacks.currentContextSources[examplePath];
     expect(exampleSources, hasLength(1));
     expect(exampleSources.first.uri.toString(),
         'file:///my/proj/example/example.dart');
@@ -364,9 +497,9 @@
     String examplePath = newFolder([projPath, EXAMPLE_NAME]);
     String libPath = newFolder([projPath, LIB_NAME]);
 
-    newFile([projPath, AbstractContextManager.PUBSPEC_NAME]);
+    newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
     newFile([libPath, 'main.dart']);
-    newFile([examplePath, AbstractContextManager.PUBSPEC_NAME]);
+    newFile([examplePath, ContextManagerImpl.PUBSPEC_NAME]);
     newFile([examplePath, 'example.dart']);
 
     packageMapProvider.packageMap['proj'] =
@@ -374,15 +507,15 @@
 
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
-    expect(manager.currentContextPaths, hasLength(2));
+    expect(callbacks.currentContextPaths, hasLength(2));
 
-    expect(manager.currentContextPaths, contains(projPath));
-    Set<Source> projSources = manager.currentContextSources[projPath];
+    expect(callbacks.currentContextPaths, contains(projPath));
+    Set<Source> projSources = callbacks.currentContextSources[projPath];
     expect(projSources, hasLength(1));
     expect(projSources.first.uri.toString(), 'package:proj/main.dart');
 
-    expect(manager.currentContextPaths, contains(examplePath));
-    Set<Source> exampleSources = manager.currentContextSources[examplePath];
+    expect(callbacks.currentContextPaths, contains(examplePath));
+    Set<Source> exampleSources = callbacks.currentContextSources[examplePath];
     expect(exampleSources, hasLength(1));
     expect(exampleSources.first.uri.toString(),
         'file:///my/proj/example/example.dart');
@@ -392,9 +525,9 @@
     packageMapProvider.packageMap = null;
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // verify
-    expect(manager.currentContextPaths, hasLength(1));
-    expect(manager.currentContextPaths, contains(projPath));
-    expect(manager.currentContextFilePaths[projPath], hasLength(0));
+    expect(callbacks.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, contains(projPath));
+    expect(callbacks.currentContextFilePaths[projPath], hasLength(0));
   }
 
   void test_setRoots_addFolderWithPackagespec() {
@@ -409,12 +542,12 @@
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
     // verify
-    expect(manager.currentContextPaths, hasLength(1));
-    expect(manager.currentContextPaths, contains(projPath));
-    expect(manager.currentContextFilePaths[projPath], hasLength(1));
+    expect(callbacks.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, contains(projPath));
+    expect(callbacks.currentContextFilePaths[projPath], hasLength(1));
 
     // smoketest resolution
-    SourceFactory sourceFactory = manager.currentContext.sourceFactory;
+    SourceFactory sourceFactory = callbacks.currentContext.sourceFactory;
     Source resolvedSource =
         sourceFactory.resolveUri(source, 'package:unittest/unittest.dart');
     expect(resolvedSource, isNotNull);
@@ -427,9 +560,9 @@
     resourceProvider.newFile(pubspecPath, 'pubspec');
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // verify
-    expect(manager.currentContextPaths, hasLength(1));
-    expect(manager.currentContextPaths, contains(projPath));
-    expect(manager.currentContextFilePaths[projPath], hasLength(0));
+    expect(callbacks.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, contains(projPath));
+    expect(callbacks.currentContextFilePaths[projPath], hasLength(0));
   }
 
   void test_setRoots_addFolderWithPubspec_andPackagespec() {
@@ -439,7 +572,7 @@
     resourceProvider.newFile(packagespecPath, '');
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // verify
-    manager.assertContextPaths([projPath]);
+    callbacks.assertContextPaths([projPath]);
   }
 
   void test_setRoots_addFolderWithPubspecAndLib() {
@@ -448,7 +581,7 @@
     String srcPath = newFolder([libPath, SRC_NAME]);
     String testPath = newFolder([projPath, TEST_NAME]);
 
-    newFile([projPath, AbstractContextManager.PUBSPEC_NAME]);
+    newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
     String appPath = newFile([binPath, 'app.dart']);
     newFile([libPath, 'main.dart']);
     newFile([srcPath, 'internal.dart']);
@@ -458,10 +591,10 @@
         [resourceProvider.getResource(libPath)];
 
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    Set<Source> sources = manager.currentContextSources[projPath];
+    Set<Source> sources = callbacks.currentContextSources[projPath];
 
-    expect(manager.currentContextPaths, hasLength(1));
-    expect(manager.currentContextPaths, contains(projPath));
+    expect(callbacks.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, contains(projPath));
     expect(sources, hasLength(4));
     List<String> uris =
         sources.map((Source source) => source.uri.toString()).toList();
@@ -491,11 +624,11 @@
 
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProjectA, subProjectB]);
+    callbacks.assertContextPaths([root, subProjectA, subProjectB]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProjectA, [subProjectA_file]);
-    manager.assertContextFiles(subProjectB, [subProjectB_file]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
+    callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
   }
 
   void test_setRoots_addFolderWithPubspecFolders() {
@@ -519,11 +652,11 @@
     };
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProjectA, subProjectB]);
+    callbacks.assertContextPaths([root, subProjectA, subProjectB]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProjectA, [subProjectA_file]);
-    manager.assertContextFiles(subProjectB, [subProjectB_file]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
+    callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
     // verify package maps
     _checkPackageMap(root, isNull);
     _checkPackageMap(
@@ -572,8 +705,8 @@
     resourceProvider.newFile(file2, '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[file1], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [file2]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [file2]);
   }
 
   void test_setRoots_exclude_newRoot_withExcludedFolder() {
@@ -588,8 +721,8 @@
     resourceProvider.newFile(fileB, 'library b;');
     // set roots
     manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [fileA]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [fileA]);
   }
 
   void test_setRoots_exclude_sameRoot_addExcludedFile() {
@@ -602,12 +735,12 @@
     resourceProvider.newFile(file2, '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [file1, file2]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [file1, file2]);
     // exclude "2"
     manager.setRoots(<String>[project], <String>[file2], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [file1]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [file1]);
   }
 
   void test_setRoots_exclude_sameRoot_addExcludedFolder() {
@@ -622,12 +755,12 @@
     resourceProvider.newFile(fileB, 'library b;');
     // initially both "aaa/a" and "bbb/b" are included
     manager.setRoots(<String>[project], <String>[], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [fileA, fileB]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [fileA, fileB]);
     // exclude "bbb/"
     manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [fileA]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [fileA]);
   }
 
   void test_setRoots_exclude_sameRoot_removeExcludedFile() {
@@ -640,12 +773,12 @@
     resourceProvider.newFile(file2, '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[file2], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [file1]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [file1]);
     // stop excluding "2"
     manager.setRoots(<String>[project], <String>[], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [file1, file2]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [file1, file2]);
   }
 
   void test_setRoots_exclude_sameRoot_removeExcludedFile_inFolder() {
@@ -658,12 +791,12 @@
     resourceProvider.newFile(file2, '// 2');
     // set roots
     manager.setRoots(<String>[project], <String>[file2], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [file1]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [file1]);
     // stop excluding "2"
     manager.setRoots(<String>[project], <String>[], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [file1, file2]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [file1, file2]);
   }
 
   void test_setRoots_exclude_sameRoot_removeExcludedFolder() {
@@ -678,12 +811,12 @@
     resourceProvider.newFile(fileB, 'library b;');
     // exclude "bbb/"
     manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [fileA]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [fileA]);
     // stop excluding "bbb/"
     manager.setRoots(<String>[project], <String>[], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [fileA, fileB]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [fileA, fileB]);
   }
 
   void test_setRoots_newFolderWithPackageRoot() {
@@ -723,11 +856,11 @@
     packageMapProvider.packageMap = null;
     // add one root - there is a context
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    expect(manager.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, hasLength(1));
     // set empty roots - no contexts
     manager.setRoots(<String>[], <String>[], <String, String>{});
-    expect(manager.currentContextPaths, hasLength(0));
-    expect(manager.currentContextFilePaths, hasLength(0));
+    expect(callbacks.currentContextPaths, hasLength(0));
+    expect(callbacks.currentContextFilePaths, hasLength(0));
   }
 
   void test_setRoots_removeFolderWithPackagespec() {
@@ -736,11 +869,11 @@
     resourceProvider.newFile(pubspecPath, '');
     // add one root - there is a context
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    expect(manager.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, hasLength(1));
     // set empty roots - no contexts
     manager.setRoots(<String>[], <String>[], <String, String>{});
-    expect(manager.currentContextPaths, hasLength(0));
-    expect(manager.currentContextFilePaths, hasLength(0));
+    expect(callbacks.currentContextPaths, hasLength(0));
+    expect(callbacks.currentContextFilePaths, hasLength(0));
   }
 
   void test_setRoots_removeFolderWithPackagespecFolder() {
@@ -765,16 +898,17 @@
     // set roots
     manager.setRoots(
         <String>[projectA, projectB], <String>[], <String, String>{});
-    manager.assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
-    manager.assertContextFiles(projectA, [projectA_file]);
-    manager.assertContextFiles(projectB, [projectB_file]);
-    manager.assertContextFiles(subProjectA, [subProjectA_file]);
-    manager.assertContextFiles(subProjectB, [subProjectB_file]);
+    callbacks
+        .assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
+    callbacks.assertContextFiles(projectA, [projectA_file]);
+    callbacks.assertContextFiles(projectB, [projectB_file]);
+    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
+    callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
     // remove "projectB"
     manager.setRoots(<String>[projectA], <String>[], <String, String>{});
-    manager.assertContextPaths([projectA, subProjectA]);
-    manager.assertContextFiles(projectA, [projectA_file]);
-    manager.assertContextFiles(subProjectA, [subProjectA_file]);
+    callbacks.assertContextPaths([projectA, subProjectA]);
+    callbacks.assertContextFiles(projectA, [projectA_file]);
+    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
   }
 
   void test_setRoots_removeFolderWithPubspec() {
@@ -783,11 +917,11 @@
     resourceProvider.newFile(pubspecPath, 'pubspec');
     // add one root - there is a context
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    expect(manager.currentContextPaths, hasLength(1));
+    expect(callbacks.currentContextPaths, hasLength(1));
     // set empty roots - no contexts
     manager.setRoots(<String>[], <String>[], <String, String>{});
-    expect(manager.currentContextPaths, hasLength(0));
-    expect(manager.currentContextFilePaths, hasLength(0));
+    expect(callbacks.currentContextPaths, hasLength(0));
+    expect(callbacks.currentContextFilePaths, hasLength(0));
   }
 
   void test_setRoots_removeFolderWithPubspecFolder() {
@@ -812,16 +946,17 @@
     // set roots
     manager.setRoots(
         <String>[projectA, projectB], <String>[], <String, String>{});
-    manager.assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
-    manager.assertContextFiles(projectA, [projectA_file]);
-    manager.assertContextFiles(projectB, [projectB_file]);
-    manager.assertContextFiles(subProjectA, [subProjectA_file]);
-    manager.assertContextFiles(subProjectB, [subProjectB_file]);
+    callbacks
+        .assertContextPaths([projectA, subProjectA, projectB, subProjectB]);
+    callbacks.assertContextFiles(projectA, [projectA_file]);
+    callbacks.assertContextFiles(projectB, [projectB_file]);
+    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
+    callbacks.assertContextFiles(subProjectB, [subProjectB_file]);
     // remove "projectB"
     manager.setRoots(<String>[projectA], <String>[], <String, String>{});
-    manager.assertContextPaths([projectA, subProjectA]);
-    manager.assertContextFiles(projectA, [projectA_file]);
-    manager.assertContextFiles(subProjectA, [subProjectA_file]);
+    callbacks.assertContextPaths([projectA, subProjectA]);
+    callbacks.assertContextFiles(projectA, [projectA_file]);
+    callbacks.assertContextFiles(subProjectA, [subProjectA_file]);
   }
 
   void test_setRoots_removePackageRoot() {
@@ -842,7 +977,7 @@
   test_watch_addDummyLink() {
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // empty folder initially
-    Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+    Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, isEmpty);
     // add link
     String filePath = posix.join(projPath, 'foo.dart');
@@ -856,7 +991,7 @@
   test_watch_addFile() {
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // empty folder initially
-    Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+    Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(0));
     // add file
     String filePath = posix.join(projPath, 'foo.dart');
@@ -879,20 +1014,20 @@
     resourceProvider.newFile(fileA, 'library a;');
     // set roots
     manager.setRoots(<String>[project], <String>[folderB], <String, String>{});
-    manager.assertContextPaths([project]);
-    manager.assertContextFiles(project, [fileA]);
+    callbacks.assertContextPaths([project]);
+    callbacks.assertContextFiles(project, [fileA]);
     // add a file, ignored as excluded
     resourceProvider.newFile(fileB, 'library b;');
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([project]);
-      manager.assertContextFiles(project, [fileA]);
+      callbacks.assertContextPaths([project]);
+      callbacks.assertContextFiles(project, [fileA]);
     });
   }
 
   test_watch_addFileInSubfolder() {
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // empty folder initially
-    Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+    Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(0));
     // add file in subfolder
     String filePath = posix.join(projPath, 'foo', 'bar.dart');
@@ -913,14 +1048,14 @@
     resourceProvider.newFile(rootFile, 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root]);
+    callbacks.assertContextPaths([root]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(root, [rootFile]);
     // add packagespec - still just one root
     resourceProvider.newFile(rootPackagespec, '');
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root]);
-      manager.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextPaths([root]);
+      callbacks.assertContextFiles(root, [rootFile]);
       // TODO(pquitslund): verify that a new source factory is created --
       // likely this will need to happen in a corresponding ServerContextManagerTest.
     });
@@ -938,15 +1073,15 @@
     resourceProvider.newFile(subFile, 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root]);
+    callbacks.assertContextPaths([root]);
     // verify files
-    manager.assertContextFiles(root, [rootFile, subFile]);
+    callbacks.assertContextFiles(root, [rootFile, subFile]);
     // add .packages
     resourceProvider.newFile(subPubspec, '');
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root, subProject]);
-      manager.assertContextFiles(root, [rootFile]);
-      manager.assertContextFiles(subProject, [subFile]);
+      callbacks.assertContextPaths([root, subProject]);
+      callbacks.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextFiles(subProject, [subFile]);
     });
   }
 
@@ -964,15 +1099,15 @@
     resourceProvider.newFile(subFile, 'library sub;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProject]);
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProject, [subFile]);
+    callbacks.assertContextPaths([root, subProject]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProject, [subFile]);
     // add pubspec - ignore, because is already in a packagespec-based context
     resourceProvider.newFile(subSubPubspec, '');
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root, subProject]);
-      manager.assertContextFiles(root, [rootFile]);
-      manager.assertContextFiles(subProject, [subFile]);
+      callbacks.assertContextPaths([root, subProject]);
+      callbacks.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextFiles(subProject, [subFile]);
     });
   }
 
@@ -990,18 +1125,18 @@
     resourceProvider.newFile(subFile, 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProject]);
+    callbacks.assertContextPaths([root, subProject]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProject, [subFile]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProject, [subFile]);
 
     // add .packages
     resourceProvider.newFile(subPackagespec, '');
     return pumpEventQueue().then((_) {
       // Should NOT create another context.
-      manager.assertContextPaths([root, subProject]);
-      manager.assertContextFiles(root, [rootFile]);
-      manager.assertContextFiles(subProject, [subFile]);
+      callbacks.assertContextPaths([root, subProject]);
+      callbacks.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextFiles(subProject, [subFile]);
     });
   }
 
@@ -1014,14 +1149,14 @@
     resourceProvider.newFile(rootFile, 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root]);
+    callbacks.assertContextPaths([root]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(root, [rootFile]);
     // add pubspec - still just one root
     resourceProvider.newFile(rootPubspec, 'pubspec');
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root]);
-      manager.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextPaths([root]);
+      callbacks.assertContextFiles(root, [rootFile]);
     });
   }
 
@@ -1037,15 +1172,15 @@
     resourceProvider.newFile(subFile, 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root]);
+    callbacks.assertContextPaths([root]);
     // verify files
-    manager.assertContextFiles(root, [rootFile, subFile]);
+    callbacks.assertContextFiles(root, [rootFile, subFile]);
     // add pubspec
     resourceProvider.newFile(subPubspec, 'pubspec');
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root, subProject]);
-      manager.assertContextFiles(root, [rootFile]);
-      manager.assertContextFiles(subProject, [subFile]);
+      callbacks.assertContextPaths([root, subProject]);
+      callbacks.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextFiles(subProject, [subFile]);
     });
   }
 
@@ -1063,15 +1198,15 @@
     resourceProvider.newFile(subFile, 'library sub;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProject]);
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProject, [subFile]);
+    callbacks.assertContextPaths([root, subProject]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProject, [subFile]);
     // add pubspec - ignore, because is already in a pubspec-based context
     resourceProvider.newFile(subSubPubspec, 'pubspec');
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root, subProject]);
-      manager.assertContextFiles(root, [rootFile]);
-      manager.assertContextFiles(subProject, [subFile]);
+      callbacks.assertContextPaths([root, subProject]);
+      callbacks.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextFiles(subProject, [subFile]);
     });
   }
 
@@ -1082,7 +1217,7 @@
     Folder projFolder = file.parent;
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // the file was added
-    Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+    Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(1));
     expect(filePaths, contains(filePath));
     expect(file.exists, isTrue);
@@ -1103,7 +1238,7 @@
     Folder projFolder = file.parent;
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // the file was added
-    Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+    Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(1));
     expect(filePaths, contains(filePath));
     expect(file.exists, isTrue);
@@ -1127,13 +1262,13 @@
     resourceProvider.newFile(rootFile, 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root]);
-    manager.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextPaths([root]);
+    callbacks.assertContextFiles(root, [rootFile]);
     // delete the pubspec
     resourceProvider.deleteFile(rootPubspec);
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root]);
-      manager.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextPaths([root]);
+      callbacks.assertContextFiles(root, [rootFile]);
     });
   }
 
@@ -1150,15 +1285,15 @@
     resourceProvider.newFile(subFile, 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProject]);
+    callbacks.assertContextPaths([root, subProject]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProject, [subFile]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProject, [subFile]);
     // delete the pubspec
     resourceProvider.deleteFile(subPubspec);
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root]);
-      manager.assertContextFiles(root, [rootFile, subFile]);
+      callbacks.assertContextPaths([root]);
+      callbacks.assertContextFiles(root, [rootFile, subFile]);
     });
   }
 
@@ -1177,16 +1312,16 @@
     resourceProvider.newFile(subFile, 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProject]);
+    callbacks.assertContextPaths([root, subProject]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProject, [subFile]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProject, [subFile]);
     // delete the packagespec
     resourceProvider.deleteFile(subPackagespec);
     return pumpEventQueue().then((_) {
       // Should NOT merge
-      manager.assertContextPaths([root, subProject]);
-      manager.assertContextFiles(subProject, [subFile]);
+      callbacks.assertContextPaths([root, subProject]);
+      callbacks.assertContextFiles(subProject, [subFile]);
     });
   }
 
@@ -1200,13 +1335,13 @@
     resourceProvider.newFile(rootFile, 'library root;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root]);
-    manager.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextPaths([root]);
+    callbacks.assertContextFiles(root, [rootFile]);
     // delete the pubspec
     resourceProvider.deleteFile(rootPubspec);
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root]);
-      manager.assertContextFiles(root, [rootFile]);
+      callbacks.assertContextPaths([root]);
+      callbacks.assertContextFiles(root, [rootFile]);
     });
   }
 
@@ -1223,15 +1358,15 @@
     resourceProvider.newFile(subFile, 'library a;');
     // set roots
     manager.setRoots(<String>[root], <String>[], <String, String>{});
-    manager.assertContextPaths([root, subProject]);
+    callbacks.assertContextPaths([root, subProject]);
     // verify files
-    manager.assertContextFiles(root, [rootFile]);
-    manager.assertContextFiles(subProject, [subFile]);
+    callbacks.assertContextFiles(root, [rootFile]);
+    callbacks.assertContextFiles(subProject, [subFile]);
     // delete the pubspec
     resourceProvider.deleteFile(subPubspec);
     return pumpEventQueue().then((_) {
-      manager.assertContextPaths([root]);
-      manager.assertContextFiles(root, [rootFile, subFile]);
+      callbacks.assertContextPaths([root]);
+      callbacks.assertContextFiles(root, [rootFile, subFile]);
     });
   }
 
@@ -1241,15 +1376,15 @@
     resourceProvider.newFile(filePath, 'contents');
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // the file was added
-    Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+    Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(1));
     expect(filePaths, contains(filePath));
-    expect(filePaths[filePath], equals(manager.now));
+    expect(filePaths[filePath], equals(callbacks.now));
     // update the file
-    manager.now++;
+    callbacks.now++;
     resourceProvider.modifyFile(filePath, 'new contents');
     return pumpEventQueue().then((_) {
-      return expect(filePaths[filePath], equals(manager.now));
+      return expect(filePaths[filePath], equals(callbacks.now));
     });
   }
 
@@ -1302,70 +1437,6 @@
     });
   }
 
-  test_watch_modifyPackageMapDependency_outsideProject() {
-    // create a dependency file
-    String dependencyPath = '/my/other/dep';
-    resourceProvider.newFile(dependencyPath, 'contents');
-    packageMapProvider.dependencies.add(dependencyPath);
-    // create a Dart file
-    String dartFilePath = posix.join(projPath, 'main.dart');
-    resourceProvider.newFile(dartFilePath, 'contents');
-    // the created context has the expected empty package map
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    _checkPackageMap(projPath, isEmpty);
-    // configure package map
-    String packagePath = '/package/foo';
-    resourceProvider.newFolder(packagePath);
-    packageMapProvider.packageMap = {'foo': projPath};
-    // Changing a .dart file in the project shouldn't cause a new
-    // package map to be picked up.
-    resourceProvider.modifyFile(dartFilePath, 'new contents');
-    return pumpEventQueue().then((_) {
-      _checkPackageMap(projPath, isEmpty);
-      // However, changing the package map dependency should.
-      resourceProvider.modifyFile(dependencyPath, 'new contents');
-      return pumpEventQueue().then((_) {
-        _checkPackageMap(projPath, equals(packageMapProvider.packageMap));
-      });
-    });
-  }
-
-  test_watch_modifyPackageMapDependency_redundantly() async {
-    // Create two dependency files
-    String dependencyPath1 = posix.join(projPath, 'dep1');
-    String dependencyPath2 = posix.join(projPath, 'dep2');
-    resourceProvider.newFile(dependencyPath1, 'contents');
-    resourceProvider.newFile(dependencyPath2, 'contents');
-    packageMapProvider.dependencies.add(dependencyPath1);
-    packageMapProvider.dependencies.add(dependencyPath2);
-    // Create a dart file
-    String dartFilePath = posix.join(projPath, 'main.dart');
-    resourceProvider.newFile(dartFilePath, 'contents');
-    // Verify that the created context has the expected empty package map.
-    manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    _checkPackageMap(projPath, isEmpty);
-    expect(packageMapProvider.computeCount, 1);
-    // Set up a different package map
-    String packagePath = '/package/foo';
-    resourceProvider.newFolder(packagePath);
-    packageMapProvider.packageMap = {'foo': projPath};
-    // Change both dependencies.
-    resourceProvider.modifyFile(dependencyPath1, 'new contents');
-    resourceProvider.modifyFile(dependencyPath2, 'new contents');
-    // Arrange for the next call to computePackageMap to return the correct
-    // timestamps for the dependencies.
-    packageMapProvider.modificationTimes = <String, int>{};
-    for (String path in [dependencyPath1, dependencyPath2]) {
-      File resource = resourceProvider.getResource(path);
-      packageMapProvider.modificationTimes[path] = resource.modificationStamp;
-    }
-    // This should cause the new package map to be picked up, by executing
-    // computePackageMap just one additional time.
-    await pumpEventQueue();
-    _checkPackageMap(projPath, equals(packageMapProvider.packageMap));
-    expect(packageMapProvider.computeCount, 2);
-  }
-
   test_watch_modifyPackagespec() {
     String packagesPath = '$projPath/.packages';
     String filePath = '$projPath/bin/main.dart';
@@ -1375,18 +1446,18 @@
 
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
-    Map<String, int> filePaths = manager.currentContextFilePaths[projPath];
+    Map<String, int> filePaths = callbacks.currentContextFilePaths[projPath];
     expect(filePaths, hasLength(1));
     expect(filePaths, contains(filePath));
-    Packages packages = manager.currentContextPackagespecs[projPath];
+    Packages packages = callbacks.currentContextDispositions[projPath].packages;
     expect(packages.packages, isEmpty);
 
     // update .packages
-    manager.now++;
+    callbacks.now++;
     resourceProvider.modifyFile(packagesPath, 'main:./lib/');
     return pumpEventQueue().then((_) {
       // verify new package info
-      packages = manager.currentContextPackagespecs[projPath];
+      packages = callbacks.currentContextDispositions[projPath].packages;
       expect(packages.packages, unorderedEquals(['main']));
     });
   }
@@ -1396,9 +1467,9 @@
    * using a package map matching [expectation].
    */
   void _checkPackageMap(String path, expectation) {
-    UriResolver resolver = manager.currentContextPackageUriResolvers[path];
+    FolderDisposition disposition = callbacks.currentContextDispositions[path];
     Map<String, List<Folder>> packageMap =
-        resolver is PackageMapUriResolver ? resolver.packageMap : null;
+        disposition is PackageMapDisposition ? disposition.packageMap : null;
     expect(packageMap, expectation);
   }
 
@@ -1407,14 +1478,14 @@
    * using a package root maching [expectation].
    */
   void _checkPackageRoot(String path, expectation) {
-    UriResolver resolver = manager.currentContextPackageUriResolvers[path];
-    expect(resolver, new isInstanceOf<PackageUriResolver>());
-    PackageUriResolver packageUriResolver = resolver;
-    expect(packageUriResolver.packagesDirectory_forTesting, expectation);
+    FolderDisposition disposition = callbacks.currentContextDispositions[path];
+    expect(disposition.packageRoot, expectation);
+    // TODO(paulberry): we should also verify that the package map itself is
+    // correct.  See dartbug.com/23909.
   }
 }
 
-class TestContextManager extends AbstractContextManager {
+class TestContextManagerCallbacks extends ContextManagerCallbacks {
   /**
    * Source of timestamps stored in [currentContextFilePaths].
    */
@@ -1444,21 +1515,17 @@
   };
 
   /**
-   * Map from context to package URI resolver.
+   * Map from context to folder disposition.
    */
-  final Map<String, UriResolver> currentContextPackageUriResolvers =
-      <String, UriResolver>{};
+  final Map<String, FolderDisposition> currentContextDispositions =
+      <String, FolderDisposition>{};
 
   /**
-   * Map from context to packages object.
+   * Resource provider used for this test.
    */
-  final Map<String, Packages> currentContextPackagespecs = <String, Packages>{};
+  final ResourceProvider resourceProvider;
 
-  TestContextManager(MemoryResourceProvider resourceProvider,
-      ResolverProvider packageResolverProvider,
-      OptimizingPubPackageMapProvider packageMapProvider)
-      : super(resourceProvider, packageResolverProvider, packageMapProvider,
-          InstrumentationService.NULL_SERVICE);
+  TestContextManagerCallbacks(this.resourceProvider);
 
   /**
    * Iterable of the paths to contexts that currently exist.
@@ -1466,21 +1533,18 @@
   Iterable<String> get currentContextPaths => currentContextTimestamps.keys;
 
   @override
-  AnalysisContext addContext(
-      Folder folder, UriResolver packageUriResolver, Packages packages) {
+  AnalysisContext addContext(Folder folder, FolderDisposition disposition) {
     String path = folder.path;
     expect(currentContextPaths, isNot(contains(path)));
     currentContextTimestamps[path] = now;
     currentContextFilePaths[path] = <String, int>{};
     currentContextSources[path] = new HashSet<Source>();
-    currentContextPackageUriResolvers[path] = packageUriResolver;
-    currentContextPackagespecs[path] = packages;
+    currentContextDispositions[path] = disposition;
     currentContext = AnalysisEngine.instance.createAnalysisContext();
     List<UriResolver> resolvers = [new FileUriResolver()];
-    if (packageUriResolver != null) {
-      resolvers.add(packageUriResolver);
-    }
-    currentContext.sourceFactory = new SourceFactory(resolvers, packages);
+    resolvers.addAll(disposition.createPackageUriResolvers(resourceProvider));
+    currentContext.sourceFactory =
+        new SourceFactory(resolvers, disposition.packages);
     return currentContext;
   }
 
@@ -1517,13 +1581,13 @@
   }
 
   @override
-  void removeContext(Folder folder) {
+  void removeContext(Folder folder, List<String> flushedFiles) {
     String path = folder.path;
     expect(currentContextPaths, contains(path));
     currentContextTimestamps.remove(path);
     currentContextFilePaths.remove(path);
     currentContextSources.remove(path);
-    currentContextPackageUriResolvers.remove(path);
+    currentContextDispositions.remove(path);
   }
 
   @override
@@ -1542,9 +1606,8 @@
 
   @override
   void updateContextPackageUriResolver(
-      Folder contextFolder, UriResolver packageUriResolver, Packages packages) {
-    currentContextPackageUriResolvers[contextFolder.path] = packageUriResolver;
-    currentContextPackagespecs[contextFolder.path] = packages;
+      Folder contextFolder, FolderDisposition disposition) {
+    currentContextDispositions[contextFolder.path] = disposition;
   }
 }
 
@@ -1564,7 +1627,7 @@
   TestUriResolver(this.uriMap);
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     return uriMap[uri];
   }
 }
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 63cd20f..08916ce 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -21,9 +21,9 @@
 import 'package:analysis_server/src/services/index/index.dart' show Index;
 import 'package:analysis_server/src/services/index/local_memory_index.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
-import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -657,7 +657,7 @@
 
   Test_AnalysisServer(ServerCommunicationChannel channel,
       ResourceProvider resourceProvider,
-      OptimizingPubPackageMapProvider packageMapProvider, Index index,
+      PubPackageMapProvider packageMapProvider, Index index,
       ServerPlugin serverPlugin, AnalysisServerOptions analysisServerOptions,
       DartSdk defaultSdk, InstrumentationService instrumentationService)
       : super(channel, resourceProvider, packageMapProvider, index,
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 8fa9234..2ff54e1 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -8,6 +8,7 @@
 
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
+import 'package:analysis_server/src/context_manager.dart';
 import 'package:analysis_server/src/domain_execution.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
 import 'package:analysis_server/src/protocol.dart';
@@ -225,7 +226,7 @@
       when(context.getLibrariesReferencedFromHtml(anyObject))
           .thenReturn([source6, source7]);
 
-      ServerContextManager manager = new ServerContextManagerMock();
+      ContextManager manager = new ServerContextManagerMock();
       when(manager.isInAnalysisRoot(anyString)).thenReturn(true);
 
       AnalysisServer server = new AnalysisServerMock();
diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart
new file mode 100644
index 0000000..e4402ef
--- /dev/null
+++ b/pkg/analysis_server/test/edit/organize_directives_test.dart
@@ -0,0 +1,149 @@
+// 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.edit.organize_directives;
+
+import 'dart:async';
+
+import 'package:analysis_server/src/edit/edit_domain.dart';
+import 'package:analysis_server/src/protocol.dart';
+import 'package:plugin/manager.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart' hide ERROR;
+
+import '../analysis_abstract.dart';
+import '../mocks.dart';
+
+main() {
+  groupSep = ' | ';
+  defineReflectiveTests(OrganizeDirectivesTest);
+}
+
+@reflectiveTest
+class OrganizeDirectivesTest extends AbstractAnalysisTest {
+  SourceFileEdit fileEdit;
+
+  @override
+  void setUp() {
+    super.setUp();
+    createProject();
+    ExtensionManager manager = new ExtensionManager();
+    manager.processPlugins([server.serverPlugin]);
+    handler = new EditDomainHandler(server);
+  }
+
+  Future test_BAD_doesNotExist() async {
+    await waitForTasksFinished();
+    Request request =
+        new EditOrganizeDirectivesParams('/no/such/file.dart').toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(
+        response, isResponseFailure('0', RequestErrorCode.FILE_NOT_ANALYZED));
+  }
+
+  Future test_BAD_hasParseError() async {
+    addTestFile('''
+import 'dart:async'
+
+main() {}
+''');
+    await waitForTasksFinished();
+    Request request = new EditOrganizeDirectivesParams(testFile).toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.ORGANIZE_DIRECTIVES_ERROR));
+  }
+
+  Future test_BAD_notDartFile() async {
+    await waitForTasksFinished();
+    Request request =
+        new EditOrganizeDirectivesParams('/not-a-Dart-file.txt').toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(
+        response, isResponseFailure('0', RequestErrorCode.FILE_NOT_ANALYZED));
+  }
+
+  Future test_OK_remove_unresolvedDirectives() {
+    addFile('$testFolder/existing_part1.dart', 'part of lib;');
+    addFile('$testFolder/existing_part2.dart', 'part of lib;');
+    addTestFile('''
+library lib;
+
+export 'dart:noSuchExportSdkLibrary';
+export 'dart:async';
+export 'package:noSuchExportPackage/andLib.dart';
+export 'dart:math';
+
+import 'dart:async';
+import 'dart:noSuchImportSdkLibrary';
+import 'dart:math';
+import 'package:noSuchImportPackage/andLib.dart';
+
+part 'existing_part1.dart';
+part 'no_such_part.dart';
+part 'existing_part2.dart';
+
+main(Future f) {
+  print(PI);
+}
+''');
+    return _assertOrganized(r'''
+library lib;
+
+import 'dart:async';
+import 'dart:math';
+
+export 'dart:async';
+export 'dart:math';
+
+part 'existing_part1.dart';
+part 'existing_part2.dart';
+
+main(Future f) {
+  print(PI);
+}
+''');
+  }
+
+  Future test_OK_remove_unusedImports() {
+    addTestFile('''
+library lib;
+
+import 'dart:async';
+import 'dart:math';
+import 'dart:convert';
+import 'dart:collection';
+
+main() {
+  print(PI);
+  new HashMap();
+}
+''');
+    return _assertOrganized(r'''
+library lib;
+
+import 'dart:collection';
+import 'dart:math';
+
+main() {
+  print(PI);
+  new HashMap();
+}
+''');
+  }
+
+  Future _assertOrganized(String expectedCode) async {
+    await waitForTasksFinished();
+    _requestOrganize();
+    String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits);
+    expect(resultCode, expectedCode);
+  }
+
+  void _requestOrganize() {
+    Request request = new EditOrganizeDirectivesParams(testFile).toRequest('0');
+    Response response = handleSuccessfulRequest(request);
+    var result = new EditOrganizeDirectivesResult.fromResponse(response);
+    fileEdit = result.edit;
+  }
+}
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index 6aa638c..194baa9 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -33,38 +33,35 @@
     handler = new EditDomainHandler(server);
   }
 
-  Future test_BAD_doesNotExist() {
-    return waitForTasksFinished().then((_) {
-      Request request =
-          new EditSortMembersParams('/no/such/file.dart').toRequest('0');
-      Response response = handler.handleRequest(request);
-      expect(response,
-          isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
-    });
+  Future test_BAD_doesNotExist() async {
+    await waitForTasksFinished();
+    Request request =
+        new EditSortMembersParams('/no/such/file.dart').toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
   }
 
-  Future test_BAD_hasParseError() {
+  Future test_BAD_hasParseError() async {
     addTestFile('''
 main() {
   print()
 }
 ''');
-    return waitForTasksFinished().then((_) {
-      Request request = new EditSortMembersParams(testFile).toRequest('0');
-      Response response = handler.handleRequest(request);
-      expect(response,
-          isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_PARSE_ERRORS));
-    });
+    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() {
-    return waitForTasksFinished().then((_) {
-      Request request =
-          new EditSortMembersParams('/not-a-Dart-file.txt').toRequest('0');
-      Response response = handler.handleRequest(request);
-      expect(response,
-          isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
-    });
+  Future test_BAD_notDartFile() async {
+    await waitForTasksFinished();
+    Request request =
+        new EditSortMembersParams('/not-a-Dart-file.txt').toRequest('0');
+    Response response = handler.handleRequest(request);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.SORT_MEMBERS_INVALID_FILE));
   }
 
   Future test_OK_classMembers_method() {
@@ -148,12 +145,11 @@
 ''');
   }
 
-  Future _assertSorted(String expectedCode) {
-    return waitForTasksFinished().then((_) {
-      _requestSort();
-      String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits);
-      expect(resultCode, expectedCode);
-    });
+  Future _assertSorted(String expectedCode) async {
+    await waitForTasksFinished();
+    _requestSort();
+    String resultCode = SourceEdit.applySequence(testCode, fileEdit.edits);
+    expect(resultCode, expectedCode);
   }
 
   void _requestSort() {
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index 40e83f1..e9a9ea1 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -9,6 +9,7 @@
 import 'assists_test.dart' as assists_test;
 import 'fixes_test.dart' as fixes_test;
 import 'format_test.dart' as format_test;
+import 'organize_directives_test.dart' as organize_directives_test;
 import 'refactoring_test.dart' as refactoring_test;
 import 'sort_members_test.dart' as sort_members_test;
 
@@ -21,6 +22,7 @@
     assists_test.main();
     fixes_test.main();
     format_test.main();
+    organize_directives_test.main();
     refactoring_test.main();
     sort_members_test.main();
   });
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index 4da1b0c..8f3915e 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -1390,6 +1390,39 @@
   }
 
   /**
+   * Organizes all of the directives - removes unused imports and sorts
+   * directives of the given Dart file according to the Dart Style Guide.
+   *
+   * If a request is made for a file that does not exist, does not belong to an
+   * analysis root or is not a Dart file, FILE_NOT_ANALYZED will be generated.
+   *
+   * If directives of the Dart file cannot be organized, for example because it
+   * has scan or parse errors, or by other reasons, ORGANIZE_DIRECTIVES_ERROR
+   * will be generated. The message will provide datails about the reason.
+   *
+   * Parameters
+   *
+   * file ( FilePath )
+   *
+   *   The Dart file to organize directives in.
+   *
+   * Returns
+   *
+   * edit ( SourceFileEdit )
+   *
+   *   The file edit that is to be applied to the given file to effect the
+   *   organizing.
+   */
+  Future<EditOrganizeDirectivesResult> sendEditOrganizeDirectives(String file) {
+    var params = new EditOrganizeDirectivesParams(file).toJson();
+    return server.send("edit.organizeDirectives", params)
+        .then((result) {
+      ResponseDecoder decoder = new ResponseDecoder(null);
+      return new EditOrganizeDirectivesResult.fromJson(decoder, 'result', result);
+    });
+  }
+
+  /**
    * Create an execution context for the executable file with the given path.
    * The context that is created will persist until execution.deleteContext is
    * used to delete it. Clients, therefore, are responsible for managing the
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index f46b338..3345554 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -16,6 +16,7 @@
 
 import 'integration_test_methods.dart';
 import 'protocol_matchers.dart';
+import 'package:analysis_server/src/server/driver.dart' as analysisServer;
 
 const Matcher isBool = const isInstanceOf<bool>('bool');
 
@@ -590,7 +591,8 @@
    * "--pause-isolates-on-exit", allowing the observatory to be used.
    */
   Future start({bool debugServer: false, int diagnosticPort,
-      bool profileServer: false, bool useAnalysisHighlight2: false}) {
+      bool profileServer: false, bool newTaskModel: false,
+      bool useAnalysisHighlight2: false}) {
     if (_process != null) {
       throw new Exception('Process already started');
     }
@@ -619,6 +621,9 @@
     if (useAnalysisHighlight2) {
       arguments.add('--useAnalysisHighlight2');
     }
+    if (newTaskModel) {
+      arguments.add('--${analysisServer.Driver.ENABLE_NEW_TASK_MODEL}');
+    }
     return Process.start(dartBinary, arguments).then((Process process) {
       _process = process;
       process.exitCode.then((int code) {
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 0a5ae19..24cc21e 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -853,6 +853,30 @@
   }));
 
 /**
+ * edit.organizeDirectives params
+ *
+ * {
+ *   "file": FilePath
+ * }
+ */
+final Matcher isEditOrganizeDirectivesParams = new LazyMatcher(() => new MatchesJsonObject(
+  "edit.organizeDirectives params", {
+    "file": isFilePath
+  }));
+
+/**
+ * edit.organizeDirectives result
+ *
+ * {
+ *   "edit": SourceFileEdit
+ * }
+ */
+final Matcher isEditOrganizeDirectivesResult = new LazyMatcher(() => new MatchesJsonObject(
+  "edit.organizeDirectives result", {
+    "edit": isSourceFileEdit
+  }));
+
+/**
  * execution.createContext params
  *
  * {
@@ -1936,6 +1960,7 @@
  *
  * enum {
  *   CONTENT_MODIFIED
+ *   FILE_NOT_ANALYZED
  *   FORMAT_INVALID_FILE
  *   FORMAT_WITH_ERRORS
  *   GET_ERRORS_INVALID_FILE
@@ -1946,6 +1971,7 @@
  *   INVALID_PARAMETER
  *   INVALID_REQUEST
  *   NO_INDEX_GENERATED
+ *   ORGANIZE_DIRECTIVES_ERROR
  *   REFACTORING_REQUEST_CANCELLED
  *   SERVER_ALREADY_STARTED
  *   SERVER_ERROR
@@ -1959,6 +1985,7 @@
  */
 final Matcher isRequestErrorCode = new MatchesEnum("RequestErrorCode", [
   "CONTENT_MODIFIED",
+  "FILE_NOT_ANALYZED",
   "FORMAT_INVALID_FILE",
   "FORMAT_WITH_ERRORS",
   "GET_ERRORS_INVALID_FILE",
@@ -1969,6 +1996,7 @@
   "INVALID_PARAMETER",
   "INVALID_REQUEST",
   "NO_INDEX_GENERATED",
+  "ORGANIZE_DIRECTIVES_ERROR",
   "REFACTORING_REQUEST_CANCELLED",
   "SERVER_ALREADY_STARTED",
   "SERVER_ERROR",
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 1aa8f47..3358b47 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -4,20 +4,20 @@
 
 library mocks;
 
-@MirrorsUsed(targets: 'mocks', override: '*')
-import 'dart:mirrors';
 import 'dart:async';
 import 'dart:io';
+@MirrorsUsed(targets: 'mocks', override: '*')
+import 'dart:mirrors';
 
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/operation/operation.dart';
 import 'package:analysis_server/src/operation/operation_analysis.dart';
 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind;
-import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
 import 'package:analyzer/file_system/file_system.dart' as resource;
 import 'package:analyzer/file_system/memory_file_system.dart' as resource;
 import 'package:analyzer/source/package_map_provider.dart';
+import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -152,7 +152,7 @@
 /**
  * A mock [PackageMapProvider].
  */
-class MockPackageMapProvider implements OptimizingPubPackageMapProvider {
+class MockPackageMapProvider implements PubPackageMapProvider {
   /**
    * Package map that will be returned by the next call to [computePackageMap].
    */
@@ -170,36 +170,17 @@
   Set<String> dependencies = new Set<String>();
 
   /**
-   * Modification times that will be returned by the next call to
-   * [computePackageMap].  This will be filtered to include only those paths
-   * mentioned in the `dependencies` field of [computePackageMap]'s
-   * `previousInfo` argument.
-   */
-  Map<String, int> modificationTimes = <String, int>{};
-
-  /**
    * Number of times [computePackageMap] has been called.
    */
   int computeCount = 0;
 
   @override
-  OptimizingPubPackageMapInfo computePackageMap(resource.Folder folder,
-      [OptimizingPubPackageMapInfo previousInfo]) {
+  PackageMapInfo computePackageMap(resource.Folder folder) {
     ++computeCount;
-    Map<String, int> filteredModificationTimes = <String, int>{};
-    if (previousInfo != null) {
-      for (String dependency in previousInfo.dependencies) {
-        if (modificationTimes.containsKey(dependency)) {
-          filteredModificationTimes[dependency] = modificationTimes[dependency];
-        }
-      }
-    }
     if (packageMaps != null) {
-      return new OptimizingPubPackageMapInfo(
-          packageMaps[folder.path], dependencies, filteredModificationTimes);
+      return new PackageMapInfo(packageMaps[folder.path], dependencies);
     }
-    return new OptimizingPubPackageMapInfo(
-        packageMap, dependencies, filteredModificationTimes);
+    return new PackageMapInfo(packageMap, dependencies);
   }
 
   noSuchMethod(Invocation invocation) {
diff --git a/pkg/analysis_server/test/operation/operation_queue_test.dart b/pkg/analysis_server/test/operation/operation_queue_test.dart
index 71569e8..47f0bcf 100644
--- a/pkg/analysis_server/test/operation/operation_queue_test.dart
+++ b/pkg/analysis_server/test/operation/operation_queue_test.dart
@@ -5,6 +5,7 @@
 library test.operation.queue;
 
 import 'package:analysis_server/src/analysis_server.dart';
+import 'package:analysis_server/src/context_manager.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';
@@ -39,7 +40,6 @@
 }
 
 class AnalysisServerMock extends TypedMock implements AnalysisServer {
-
   @override
   final ResourceProvider resourceProvider;
 
@@ -51,8 +51,7 @@
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
-class ServerContextManagerMock extends TypedMock
-    implements ServerContextManager {
+class ServerContextManagerMock extends TypedMock implements ContextManager {
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
diff --git a/pkg/analysis_server/test/server_options_test.dart b/pkg/analysis_server/test/server_options_test.dart
new file mode 100644
index 0000000..f3a3790
--- /dev/null
+++ b/pkg/analysis_server/test/server_options_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This code was auto-generated, is not intended to be edited, and is subject to
+// significant change. Please see the README file for more information.
+
+library analysis_server.test.server_options;
+
+import 'package:analysis_server/src/server_options.dart';
+import 'package:unittest/unittest.dart';
+
+void main() {
+  groupSep = ' | ';
+
+  group('server_options', () {
+    test('basic - []', () {
+      var options = new ServerOptions.fromContents('''# ignored
+foo: bar
+baz: padded   
+''');
+      expect(options['foo'], equals('bar'));
+      expect(options['baz'], equals('padded'));
+    });
+    test('basic - isSet', () {
+      var options = new ServerOptions.fromContents('''foo: true
+bar: TRUE
+baz: false
+foobar: off
+''');
+      expect(options.isSet('foo'), isTrue);
+      expect(options.isSet('bar'), isTrue);
+      expect(options.isSet('baz'), isFalse);
+      expect(options.isSet('foobar'), isFalse);
+      expect(options.isSet('does_not_exist'), isFalse);
+      expect(options.isSet('does_not_exist', defaultValue: true), isTrue);
+    });
+
+    test('basic - getStringValue', () {
+      var options = new ServerOptions.fromContents('''foo: someValue
+''');
+      expect(options.getStringValue('foo'), equals('someValue'));
+      expect(options.getStringValue('not_there'), isNull);
+      expect(options.getStringValue('not_there', defaultValue: 'bar'),
+          equals('bar'));
+    });
+  });
+}
diff --git a/pkg/analysis_server/test/services/completion/completion_target_test.dart b/pkg/analysis_server/test/services/completion/completion_target_test.dart
index 57fb4e9..072f97c 100644
--- a/pkg/analysis_server/test/services/completion/completion_target_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_target_test.dart
@@ -498,6 +498,30 @@
     assertTarget('zoo', 'zoo(z) {}');
   }
 
+  test_SwitchStatement_c() {
+    // Token('c') SwitchStatement
+    addTestSource('main() { switch(x) {c^} }');
+    assertTarget('}', 'switch (x) {}');
+  }
+
+  test_SwitchStatement_c2() {
+    // Token('c') SwitchStatement
+    addTestSource('main() { switch(x) { c^ } }');
+    assertTarget('}', 'switch (x) {}');
+  }
+
+  test_SwitchStatement_empty() {
+    // SwitchStatement
+    addTestSource('main() { switch(x) {^} }');
+    assertTarget('}', 'switch (x) {}');
+  }
+
+  test_SwitchStatement_empty2() {
+    // SwitchStatement
+    addTestSource('main() { switch(x) { ^ } }');
+    assertTarget('}', 'switch (x) {}');
+  }
+
   test_TypeArgumentList() {
     // TypeName  TypeArgumentList  TypeName
     addTestSource('main() { C<^> c; }');
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 249e1c0..6bcbce1 100644
--- a/pkg/analysis_server/test/services/completion/completion_test_util.dart
+++ b/pkg/analysis_server/test/services/completion/completion_test_util.dart
@@ -115,7 +115,7 @@
       {CompletionSuggestionKind csKind: CompletionSuggestionKind.INVOCATION,
       int relevance: DART_RELEVANCE_DEFAULT, String importUri,
       protocol.ElementKind elemKind: null, bool isDeprecated: false,
-      bool isPotential: false}) {
+      bool isPotential: false, String elemFile, int elemOffset}) {
     CompletionSuggestion cs =
         getSuggest(completion: completion, csKind: csKind, elemKind: elemKind);
     if (cs == null) {
@@ -133,18 +133,34 @@
     expect(cs.selectionLength, equals(0));
     expect(cs.isDeprecated, equals(isDeprecated));
     expect(cs.isPotential, equals(isPotential));
+    if (cs.element != null) {
+      expect(cs.element.location, isNotNull);
+      expect(cs.element.location.file, isNotNull);
+      expect(cs.element.location.offset, isNotNull);
+      expect(cs.element.location.length, isNotNull);
+      expect(cs.element.location.startColumn, isNotNull);
+      expect(cs.element.location.startLine, isNotNull);
+    }
+    if (elemFile != null) {
+      expect(cs.element.location.file, elemFile);
+    }
+    if (elemOffset != null) {
+      expect(cs.element.location.offset, elemOffset);
+    }
     return cs;
   }
 
   CompletionSuggestion assertSuggestClass(String name,
       {int relevance: DART_RELEVANCE_DEFAULT, String importUri,
       CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      bool isDeprecated: false}) {
+      bool isDeprecated: false, String elemFile, int elemOffset}) {
     CompletionSuggestion cs = assertSuggest(name,
         csKind: kind,
         relevance: relevance,
         importUri: importUri,
-        isDeprecated: isDeprecated);
+        isDeprecated: isDeprecated,
+        elemFile: elemFile,
+        elemOffset: elemOffset);
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.CLASS));
@@ -171,9 +187,10 @@
   }
 
   CompletionSuggestion assertSuggestConstructor(String name,
-      {int relevance: DART_RELEVANCE_DEFAULT, String importUri}) {
-    CompletionSuggestion cs =
-        assertSuggest(name, relevance: relevance, importUri: importUri);
+      {int relevance: DART_RELEVANCE_DEFAULT, String importUri,
+      int elemOffset}) {
+    CompletionSuggestion cs = assertSuggest(name,
+        relevance: relevance, importUri: importUri, elemOffset: elemOffset);
     protocol.Element element = cs.element;
     expect(element, isNotNull);
     expect(element.kind, equals(protocol.ElementKind.CONSTRUCTOR));
@@ -573,7 +590,8 @@
 
   CompletionSuggestion assertSuggestImportedClass(String name,
       {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT, String importUri}) {
+      int relevance: DART_RELEVANCE_DEFAULT, String importUri,
+      String elemFile}) {
     return assertNotSuggested(name);
   }
 
@@ -683,7 +701,8 @@
 
   CompletionSuggestion assertSuggestLocalClass(String name,
       {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
+      int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false,
+      String elemFile, int elemOffset}) {
     return assertNotSuggested(name);
   }
 
@@ -692,7 +711,8 @@
     return assertNotSuggested(name);
   }
 
-  CompletionSuggestion assertSuggestLocalConstructor(String name) {
+  CompletionSuggestion assertSuggestLocalConstructor(String name,
+      {int elemOffset}) {
     return assertNotSuggested(name);
   }
 
@@ -1249,7 +1269,7 @@
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
 
-      assertSuggestLocalClass('X');
+      assertSuggestLocalClass('X', elemFile: testFile);
       assertSuggestLocalClass('Z');
       assertSuggestLocalMethod('a', 'X', null);
       assertSuggestLocalMethod('b', 'X', 'void');
@@ -1260,7 +1280,7 @@
       assertNotSuggested('x');
       assertNotSuggested('partT8');
 
-      assertSuggestImportedClass('A');
+      assertSuggestImportedClass('A', elemFile: '/testAB.dart');
       assertNotSuggested('_B');
       assertSuggestImportedClass('C');
       assertNotSuggested('partBoo');
@@ -1945,7 +1965,7 @@
     return computeFull((bool result) {
       expect(request.replacementOffset, completionOffset);
       expect(request.replacementLength, 0);
-      assertSuggestLocalClass('A');
+      assertSuggestLocalClass('A', elemOffset: 6);
       assertSuggestImportedClass('Object');
       assertNotSuggested('x');
     });
@@ -3986,6 +4006,35 @@
     });
   }
 
+  test_SwitchStatement_c() {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {c^}}}');
+    computeFast();
+    return computeFull((bool result) {
+      assertNoSuggestions();
+    });
+  }
+
+  test_SwitchStatement_case() {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {case 0: ^}}}');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestLocalClass('A');
+      assertSuggestLocalMethod('g', 'A', 'String');
+      assertSuggestImportedClass('String');
+    });
+  }
+
+  test_SwitchStatement_empty() {
+    // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class A {String g(int x) {switch(x) {^}}}');
+    computeFast();
+    return computeFull((bool result) {
+      assertNoSuggestions();
+    });
+  }
+
   test_ThisExpression_block() {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
diff --git a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
index c33ec14..42a32cd 100644
--- a/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/imported_reference_contributor_test.dart
@@ -125,9 +125,13 @@
   @override
   CompletionSuggestion assertSuggestImportedClass(String name,
       {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT, String importUri}) {
+      int relevance: DART_RELEVANCE_DEFAULT, String importUri,
+      String elemFile}) {
     return assertSuggestClass(name,
-        relevance: relevance, kind: kind, importUri: importUri);
+        relevance: relevance,
+        kind: kind,
+        importUri: importUri,
+        elemFile: elemFile);
   }
 
   @override
diff --git a/pkg/analysis_server/test/services/completion/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/keyword_contributor_test.dart
index c9666b1..6db5b89 100644
--- a/pkg/analysis_server/test/services/completion/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/keyword_contributor_test.dart
@@ -1128,6 +1128,33 @@
         relevance: DART_RELEVANCE_HIGH);
   }
 
+  test_switch_start5() {
+    addTestSource('main() {switch(1) {c^ default:}}');
+    expect(computeFast(), isTrue);
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+    expect(request.replacementOffset, 19);
+    expect(request.replacementLength, 1);
+  }
+
+  test_switch_start6() {
+    addTestSource('main() {switch(1) {c^}}');
+    expect(computeFast(), isTrue);
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+    expect(request.replacementOffset, 19);
+    expect(request.replacementLength, 1);
+  }
+
+  test_switch_start7() {
+    addTestSource('main() {switch(1) { c^ }}');
+    expect(computeFast(), isTrue);
+    assertSuggestKeywords([Keyword.CASE, Keyword.DEFAULT],
+        relevance: DART_RELEVANCE_HIGH);
+    expect(request.replacementOffset, 20);
+    expect(request.replacementLength, 1);
+  }
+
   test_switch_statement() {
     addTestSource('main() {switch(1) {case 1:^}}');
     expect(computeFast(), isTrue);
diff --git a/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart
index e46a771..36310da 100644
--- a/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/local_reference_contributor_test.dart
@@ -24,9 +24,14 @@
   @override
   CompletionSuggestion assertSuggestLocalClass(String name,
       {CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
-      int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false}) {
+      int relevance: DART_RELEVANCE_DEFAULT, bool isDeprecated: false,
+      String elemFile, int elemOffset}) {
     return assertSuggestClass(name,
-        kind: kind, relevance: relevance, isDeprecated: isDeprecated);
+        elemFile: elemFile,
+        elemOffset: elemOffset,
+        isDeprecated: isDeprecated,
+        kind: kind,
+        relevance: relevance);
   }
 
   @override
@@ -36,8 +41,9 @@
   }
 
   @override
-  CompletionSuggestion assertSuggestLocalConstructor(String name) {
-    return assertSuggestConstructor(name);
+  CompletionSuggestion assertSuggestLocalConstructor(String name,
+      {int elemOffset}) {
+    return assertSuggestConstructor(name, elemOffset: elemOffset);
   }
 
   @override
@@ -602,7 +608,7 @@
     return computeFull((bool result) {
       CompletionSuggestion suggestion;
 
-      suggestion = assertSuggestLocalConstructor('A');
+      suggestion = assertSuggestLocalConstructor('A', elemOffset: -1);
       expect(suggestion.element.parameters, '()');
       expect(suggestion.element.returnType, 'A');
       expect(suggestion.declaringType, 'A');
diff --git a/pkg/analysis_server/test/services/completion/optype_test.dart b/pkg/analysis_server/test/services/completion/optype_test.dart
index 27e32b7..04ce497 100644
--- a/pkg/analysis_server/test/services/completion/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/optype_test.dart
@@ -1124,19 +1124,72 @@
     assertOpType(typeNames: true);
   }
 
-  test_SwitchCase() {
-    // SimpleIdentifier  SwitchCase  SwitchStatement
-    addTestSource('''m() {switch (x) {case ^D: return;}}''');
-    // TODO (danrubel) should refine this to return constants
+  test_SwitchCase_before() {
+    // SwitchCase  SwitchStatement  Block
+    addTestSource('main() {switch(k) {^case 1:}}');
+    assertOpType();
+  }
+
+  test_SwitchCase_between() {
+    // SwitchCase  SwitchStatement  Block
+    addTestSource('main() {switch(k) {case 1: ^ case 2: return}}');
     assertOpType(returnValue: true, typeNames: true, voidReturn: true);
   }
 
-  test_SwitchStatement() {
+  test_SwitchCase_expression1() {
+    // SimpleIdentifier  SwitchCase  SwitchStatement
+    addTestSource('''m() {switch (x) {case ^D: return;}}''');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchCase_expression2() {
+    // SimpleIdentifier  SwitchCase  SwitchStatement
+    addTestSource('''m() {switch (x) {case ^}}''');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchDefault_before() {
+    // SwitchDefault  SwitchStatement  Block
+    addTestSource('main() {switch(k) { ^ default: return;}}');
+    assertOpType();
+  }
+
+  test_SwitchDefault_between() {
+    // SwitchDefault  SwitchStatement  Block
+    addTestSource('main() {switch(k) {case 1: ^ default: return;}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_SwitchStatement_body_empty() {
+    // Token('}')  SwitchStatement  Block
+    addTestSource('main() {switch(k) {^}}');
+    assertOpType();
+  }
+
+  test_SwitchStatement_body_end() {
+    // Token('}')  SwitchStatement  Block
+    addTestSource('main() {switch(k) {case 1:^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_SwitchStatement_expression1() {
     // SimpleIdentifier  SwitchStatement  Block
     addTestSource('main() {switch(^k) {case 1:{}}}');
     assertOpType(returnValue: true, typeNames: true);
   }
 
+  test_SwitchStatement_expression2() {
+    // SimpleIdentifier  SwitchStatement  Block
+    addTestSource('main() {switch(k^) {case 1:{}}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchStatement_expression_empty() {
+    // SimpleIdentifier  SwitchStatement  Block
+    addTestSource('main() {switch(^) {case 1:{}}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
   test_ThisExpression_block() {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
diff --git a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart b/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
index 7e77a87..7778869 100644
--- a/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/prefixed_element_contributor_test.dart
@@ -238,7 +238,18 @@
     addTestSource('import "dart:async" deferred as bar; foo() {bar.^}');
     return computeFull((bool result) {
       assertSuggestClass('Future');
-      assertSuggestFunction('loadLibrary', 'void');
+      assertSuggestFunction('loadLibrary', 'Future<dynamic>');
+    });
+  }
+
+  test_libraryPrefix_with_exports() {
+    addSource('/libA.dart', 'library libA; class A { }');
+    addSource('/libB.dart', 'library libB; export "/libA.dart"; class B { }');
+    addTestSource('import "/libB.dart" as foo; main() {foo.^} class C { }');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestClass('B');
+      assertSuggestClass('A');
     });
   }
 
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 8e27fa5..e1c9f62 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -106,7 +106,9 @@
   }
 
   void test_addTypeAnnotation_BAD_privateType_closureParameter() {
-    addSource('/my_lib.dart', '''
+    addSource(
+        '/my_lib.dart',
+        '''
 library my_lib;
 class A {}
 class _B extends A {}
@@ -122,7 +124,9 @@
   }
 
   void test_addTypeAnnotation_BAD_privateType_declaredIdentifier() {
-    addSource('/my_lib.dart', '''
+    addSource(
+        '/my_lib.dart',
+        '''
 library my_lib;
 class A {}
 class _B extends A {}
@@ -141,7 +145,9 @@
   }
 
   void test_addTypeAnnotation_BAD_privateType_list() {
-    addSource('/my_lib.dart', '''
+    addSource(
+        '/my_lib.dart',
+        '''
 library my_lib;
 class A {}
 class _B extends A {}
@@ -157,7 +163,9 @@
   }
 
   void test_addTypeAnnotation_BAD_privateType_variable() {
-    addSource('/my_lib.dart', '''
+    addSource(
+        '/my_lib.dart',
+        '''
 library my_lib;
 class A {}
 class _B extends A {}
@@ -178,7 +186,10 @@
   final f = 0;
 }
 ''');
-    assertHasAssistAt('final ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'final ',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 class A {
   final int f = 0;
 }
@@ -191,7 +202,10 @@
   var f = 0;
 }
 ''');
-    assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'var ',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 class A {
   int f = 0;
 }
@@ -239,7 +253,10 @@
   }
 }
 ''');
-    assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'item in',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 class A<T> {
   main(List<List<T>> items) {
     for (List<T> item in items) {
@@ -257,14 +274,20 @@
 }
 ''');
     // on identifier
-    assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'item in',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main(List<String> items) {
   for (String item in items) {
   }
 }
 ''');
     // on "for"
-    assertHasAssistAt('for (', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'for (',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main(List<String> items) {
   for (String item in items) {
   }
@@ -273,7 +296,9 @@
   }
 
   void test_addTypeAnnotation_declaredIdentifier_OK_addImport_dartUri() {
-    addSource('/my_lib.dart', r'''
+    addSource(
+        '/my_lib.dart',
+        r'''
 import 'dart:async';
 List<Future<int>> getFutures() => null;
 ''');
@@ -284,7 +309,10 @@
   }
 }
 ''');
-    assertHasAssistAt('future in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'future in',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 import 'my_lib.dart';
 import 'dart:async';
 main() {
@@ -301,7 +329,10 @@
   }
 }
 ''');
-    assertHasAssistAt('item in', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'item in',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main(List<String> items) {
   for (final String item in items) {
   }
@@ -317,7 +348,10 @@
   }
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 class A {
   main(List<int> items) {
     List<int> v = items;
@@ -334,7 +368,10 @@
   }
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 class A<T> {
   main(List<T> items) {
     List<T> v = items;
@@ -344,7 +381,9 @@
   }
 
   void test_addTypeAnnotation_local_OK_addImport_dartUri() {
-    addSource('/my_lib.dart', r'''
+    addSource(
+        '/my_lib.dart',
+        r'''
 import 'dart:async';
 Future<int> getFutureInt() => null;
 ''');
@@ -354,7 +393,10 @@
   var v = getFutureInt();
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 import 'my_lib.dart';
 import 'dart:async';
 main() {
@@ -365,7 +407,9 @@
 
   void test_addTypeAnnotation_local_OK_addImport_notLibraryUnit() {
     // prepare library
-    addSource('/my_lib.dart', r'''
+    addSource(
+        '/my_lib.dart',
+        r'''
 import 'dart:async';
 Future<int> getFutureInt() => null;
 ''');
@@ -398,7 +442,9 @@
     {
       var testFileEdit = change.getFileEdit('/app.dart');
       var resultCode = SourceEdit.applySequence(appCode, testFileEdit.edits);
-      expect(resultCode, '''
+      expect(
+          resultCode,
+          '''
 library my_app;
 import 'my_lib.dart';
 import 'dart:async';
@@ -408,7 +454,9 @@
     {
       var testFileEdit = change.getFileEdit('/test.dart');
       var resultCode = SourceEdit.applySequence(testCode, testFileEdit.edits);
-      expect(resultCode, '''
+      expect(
+          resultCode,
+          '''
 part of my_app;
 main() {
   Future<int> v = getFutureInt();
@@ -418,10 +466,14 @@
   }
 
   void test_addTypeAnnotation_local_OK_addImport_relUri() {
-    addSource('/aa/bbb/lib_a.dart', r'''
+    addSource(
+        '/aa/bbb/lib_a.dart',
+        r'''
 class MyClass {}
 ''');
-    addSource('/ccc/lib_b.dart', r'''
+    addSource(
+        '/ccc/lib_b.dart',
+        r'''
 import '../aa/bbb/lib_a.dart';
 MyClass newMyClass() => null;
 ''');
@@ -431,7 +483,10 @@
   var v = newMyClass();
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 import 'ccc/lib_b.dart';
 import 'aa/bbb/lib_a.dart';
 main() {
@@ -446,7 +501,10 @@
   var v = () => 1;
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main() {
   Function v = () => 1;
 }
@@ -459,7 +517,10 @@
   var v = 0;
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main() {
   int v = 0;
 }
@@ -472,7 +533,10 @@
   var v = <String>[];
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main() {
   List<String> v = <String>[];
 }
@@ -487,7 +551,10 @@
   var x = f();
 }
 ''');
-    assertHasAssistAt('x =', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'x =',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 class C {}
 C f() => null;
 main() {
@@ -502,7 +569,10 @@
   var v = 123;
 }
 ''');
-    assertHasAssistAt('23', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        '23',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main() {
   int v = 123;
 }
@@ -515,7 +585,10 @@
   var abc = 0;
 }
 ''');
-    assertHasAssistAt('bc', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'bc',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main() {
   int abc = 0;
 }
@@ -528,7 +601,10 @@
   var v = 0;
 }
 ''');
-    assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'var ',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main() {
   int v = 0;
 }
@@ -541,7 +617,10 @@
   var v = 123; // marker
 }
 ''');
-    assertHasAssistAt(' // marker', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        ' // marker',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 main() {
   int v = 123; // marker
 }
@@ -603,7 +682,10 @@
   var v = getValue();
 }
 ''');
-    assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'var ',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 class _A {}
 _A getValue() => new _A();
 main() {
@@ -639,7 +721,10 @@
   foo((test) {});
 }
 ''');
-    assertHasAssistAt('test', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'test',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 foo(f(int p)) {}
 main() {
   foo((int test) {});
@@ -651,7 +736,10 @@
     resolveTestUnit('''
 var V = 0;
 ''');
-    assertHasAssistAt('var ', DartAssistKind.ADD_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'var ',
+        DartAssistKind.ADD_TYPE_ANNOTATION,
+        '''
 int V = 0;
 ''');
   }
@@ -678,7 +766,9 @@
 }
 List<int> readBytes() => <int>[];
 ''');
-    assertHasAssistAt('readBytes();', DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE,
+    assertHasAssistAt(
+        'readBytes();',
+        DartAssistKind.ASSIGN_TO_LOCAL_VARIABLE,
         '''
 main() {
   List<int> bytes;
@@ -686,10 +776,11 @@
 }
 List<int> readBytes() => <int>[];
 ''');
-    _assertLinkedGroup(change.linkedEditGroups[0], [
-      'readBytes = '
-    ], expectedSuggestions(
-        LinkedEditSuggestionKind.VARIABLE, ['list', 'bytes2', 'readBytes']));
+    _assertLinkedGroup(
+        change.linkedEditGroups[0],
+        ['readBytes = '],
+        expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
+            ['list', 'bytes2', 'readBytes']));
   }
 
   void test_assignToLocalVariable_alreadyAssignment() {
@@ -735,17 +826,52 @@
     resolveTestUnit('''
 setup(x) {}
 main() {
-  setup(() => print('done'));
+  setup(() => 42);
 }
 ''');
-    assertHasAssistAt('() => print', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
+    assertHasAssistAt(
+        '() => 42',
+        DartAssistKind.CONVERT_INTO_BLOCK_BODY,
+        '''
 setup(x) {}
 main() {
   setup(() {
-    return print('done');
+    return 42;
   });
 }
 ''');
+    {
+      Position exitPos = change.selection;
+      expect(exitPos, isNotNull);
+      expect(exitPos.file, testFile);
+      expect(exitPos.offset - 3, resultCode.indexOf('42;'));
+    }
+  }
+
+  void test_convertToBlockBody_OK_closure_voidExpression() {
+    resolveTestUnit('''
+setup(x) {}
+main() {
+  setup(() => print('done'));
+}
+''');
+    assertHasAssistAt(
+        '() => print',
+        DartAssistKind.CONVERT_INTO_BLOCK_BODY,
+        '''
+setup(x) {}
+main() {
+  setup(() {
+    print('done');
+  });
+}
+''');
+    {
+      Position exitPos = change.selection;
+      expect(exitPos, isNotNull);
+      expect(exitPos.file, testFile);
+      expect(exitPos.offset - 3, resultCode.indexOf("');"));
+    }
   }
 
   void test_convertToBlockBody_OK_constructor() {
@@ -754,7 +880,10 @@
   factory A() => null;
 }
 ''');
-    assertHasAssistAt('A()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
+    assertHasAssistAt(
+        'A()',
+        DartAssistKind.CONVERT_INTO_BLOCK_BODY,
+        '''
 class A {
   factory A() {
     return null;
@@ -769,7 +898,10 @@
   mmm() => 123;
 }
 ''');
-    assertHasAssistAt('mmm()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
+    assertHasAssistAt(
+        'mmm()',
+        DartAssistKind.CONVERT_INTO_BLOCK_BODY,
+        '''
 class A {
   mmm() {
     return 123;
@@ -782,7 +914,10 @@
     resolveTestUnit('''
 fff() => 123;
 ''');
-    assertHasAssistAt('fff()', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
+    assertHasAssistAt(
+        'fff()',
+        DartAssistKind.CONVERT_INTO_BLOCK_BODY,
+        '''
 fff() {
   return 123;
 }
@@ -793,7 +928,10 @@
     resolveTestUnit('''
 fff() => 123;
 ''');
-    assertHasAssistAt('23;', DartAssistKind.CONVERT_INTO_BLOCK_BODY, '''
+    assertHasAssistAt(
+        '23;',
+        DartAssistKind.CONVERT_INTO_BLOCK_BODY,
+        '''
 fff() {
   return 123;
 }
@@ -825,7 +963,10 @@
   });
 }
 ''');
-    assertHasAssistAt('42;', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
+    assertHasAssistAt(
+        '42;',
+        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
+        '''
 setup(x) {}
 main() {
   setup(() => 42);
@@ -833,6 +974,26 @@
 ''');
   }
 
+  void test_convertToExpressionBody_OK_closure_voidExpression() {
+    resolveTestUnit('''
+setup(x) {}
+main() {
+  setup(() {
+    print('test');
+  });
+}
+''');
+    assertHasAssistAt(
+        'print(',
+        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
+        '''
+setup(x) {}
+main() {
+  setup(() => print('test'));
+}
+''');
+  }
+
   void test_convertToExpressionBody_OK_constructor() {
     resolveTestUnit('''
 class A {
@@ -841,7 +1002,10 @@
   }
 }
 ''');
-    assertHasAssistAt('A()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
+    assertHasAssistAt(
+        'A()',
+        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
+        '''
 class A {
   factory A() => null;
 }
@@ -854,7 +1018,10 @@
   return 42;
 }
 ''');
-    assertHasAssistAt('{', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
+    assertHasAssistAt(
+        '{',
+        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
+        '''
 fff() => 42;
 ''');
   }
@@ -865,7 +1032,10 @@
   return 42;
 }
 ''');
-    assertHasAssistAt('ff()', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
+    assertHasAssistAt(
+        'ff()',
+        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
+        '''
 fff() => 42;
 ''');
   }
@@ -878,8 +1048,10 @@
   }
 }
 ''');
-    assertHasAssistAt('{ // marker',
-        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
+    assertHasAssistAt(
+        '{ // marker',
+        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
+        '''
 class A {
   m() => 42;
 }
@@ -892,7 +1064,10 @@
   return 42;
 }
 ''');
-    assertHasAssistAt('return', DartAssistKind.CONVERT_INTO_EXPRESSION_BODY, '''
+    assertHasAssistAt(
+        'return',
+        DartAssistKind.CONVERT_INTO_EXPRESSION_BODY,
+        '''
 fff() => 42;
 ''');
   }
@@ -968,7 +1143,10 @@
   A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
 }
 ''');
-    assertHasAssistAt('aaa, ', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
+    assertHasAssistAt(
+        'aaa, ',
+        DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
+        '''
 class A {
   double aaa2;
   int bbb2;
@@ -985,7 +1163,10 @@
   }
 }
 ''');
-    assertHasAssistAt('test {', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
+    assertHasAssistAt(
+        'test {',
+        DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
+        '''
 class A {
   int test2;
   A(this.test2) {
@@ -1002,7 +1183,10 @@
   }
 }
 ''');
-    assertHasAssistAt('test)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
+    assertHasAssistAt(
+        'test)',
+        DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
+        '''
 class A {
   int test;
   A(this.test) {
@@ -1019,7 +1203,10 @@
   A(int aaa, int bbb) : aaa2 = aaa, bbb2 = bbb;
 }
 ''');
-    assertHasAssistAt('bbb)', DartAssistKind.CONVERT_TO_FIELD_PARAMETER, '''
+    assertHasAssistAt(
+        'bbb)',
+        DartAssistKind.CONVERT_TO_FIELD_PARAMETER,
+        '''
 class A {
   double aaa2;
   int bbb2;
@@ -1091,7 +1278,10 @@
   }
 }
 ''');
-    assertHasAssistAt('item in', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
+    assertHasAssistAt(
+        'item in',
+        DartAssistKind.CONVERT_INTO_FOR_INDEX,
+        '''
 main(List<String> items) {
   for (int i = 0; i < items.length; i++) {
     String item = items[i];
@@ -1109,7 +1299,10 @@
   }
 }
 ''');
-    assertHasAssistAt('tring item', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
+    assertHasAssistAt(
+        'tring item',
+        DartAssistKind.CONVERT_INTO_FOR_INDEX,
+        '''
 main(List<String> items) {
   for (int i = 0; i < items.length; i++) {
     String item = items[i];
@@ -1127,7 +1320,10 @@
   }
 }
 ''');
-    assertHasAssistAt('for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
+    assertHasAssistAt(
+        'for (String',
+        DartAssistKind.CONVERT_INTO_FOR_INDEX,
+        '''
 main(List<String> items) {
   for (int i = 0; i < items.length; i++) {
     String item = items[i];
@@ -1145,7 +1341,10 @@
   }
 }
 ''');
-    assertHasAssistAt('for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
+    assertHasAssistAt(
+        'for (String',
+        DartAssistKind.CONVERT_INTO_FOR_INDEX,
+        '''
 main(List<String> items) {
   for (int j = 0; j < items.length; j++) {
     String item = items[j];
@@ -1164,7 +1363,10 @@
   }
 }
 ''');
-    assertHasAssistAt('for (String', DartAssistKind.CONVERT_INTO_FOR_INDEX, '''
+    assertHasAssistAt(
+        'for (String',
+        DartAssistKind.CONVERT_INTO_FOR_INDEX,
+        '''
 main(List<String> items) {
   for (int k = 0; k < items.length; k++) {
     String item = items[k];
@@ -1181,7 +1383,10 @@
   !(p is String);
 }
 ''');
-    assertHasAssistAt('p is', DartAssistKind.CONVERT_INTO_IS_NOT, '''
+    assertHasAssistAt(
+        'p is',
+        DartAssistKind.CONVERT_INTO_IS_NOT,
+        '''
 main(p) {
   p is! String;
 }
@@ -1194,7 +1399,10 @@
   !(p is String);
 }
 ''');
-    assertHasAssistAt('String)', DartAssistKind.CONVERT_INTO_IS_NOT, '''
+    assertHasAssistAt(
+        'String)',
+        DartAssistKind.CONVERT_INTO_IS_NOT,
+        '''
 main(p) {
   p is! String;
 }
@@ -1207,7 +1415,10 @@
   !(p is String);
 }
 ''');
-    assertHasAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT, '''
+    assertHasAssistAt(
+        'is String',
+        DartAssistKind.CONVERT_INTO_IS_NOT,
+        '''
 main(p) {
   p is! String;
 }
@@ -1220,7 +1431,10 @@
   !!(p is String);
 }
 ''');
-    assertHasAssistAt('is String', DartAssistKind.CONVERT_INTO_IS_NOT, '''
+    assertHasAssistAt(
+        'is String',
+        DartAssistKind.CONVERT_INTO_IS_NOT,
+        '''
 main(p) {
   !(p is! String);
 }
@@ -1233,7 +1447,10 @@
   !!(p is String);
 }
 ''');
-    assertHasAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT, '''
+    assertHasAssistAt(
+        '!(p',
+        DartAssistKind.CONVERT_INTO_IS_NOT,
+        '''
 main(p) {
   !(p is! String);
 }
@@ -1246,7 +1463,10 @@
   !(p is String);
 }
 ''');
-    assertHasAssistAt('!(p', DartAssistKind.CONVERT_INTO_IS_NOT, '''
+    assertHasAssistAt(
+        '!(p',
+        DartAssistKind.CONVERT_INTO_IS_NOT,
+        '''
 main(p) {
   p is! String;
 }
@@ -1259,7 +1479,10 @@
   !(p is String);
 }
 ''');
-    assertHasAssistAt('(p is', DartAssistKind.CONVERT_INTO_IS_NOT, '''
+    assertHasAssistAt(
+        '(p is',
+        DartAssistKind.CONVERT_INTO_IS_NOT,
+        '''
 main(p) {
   p is! String;
 }
@@ -1355,7 +1578,10 @@
   !str.isEmpty;
 }
 ''');
-    assertHasAssistAt('isEmpty', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, '''
+    assertHasAssistAt(
+        'isEmpty',
+        DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY,
+        '''
 main(String str) {
   str.isNotEmpty;
 }
@@ -1368,7 +1594,10 @@
   !str.isEmpty;
 }
 ''');
-    assertHasAssistAt('str.', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, '''
+    assertHasAssistAt(
+        'str.',
+        DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY,
+        '''
 main(String str) {
   str.isNotEmpty;
 }
@@ -1381,7 +1610,10 @@
   !'text'.isEmpty;
 }
 ''');
-    assertHasAssistAt('isEmpty', DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY, '''
+    assertHasAssistAt(
+        'isEmpty',
+        DartAssistKind.CONVERT_INTO_IS_NOT_EMPTY,
+        '''
 main(String str) {
   'text'.isNotEmpty;
 }
@@ -1436,7 +1668,10 @@
   }
 }
 ''');
-    assertHasAssistAt('test)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, '''
+    assertHasAssistAt(
+        'test)',
+        DartAssistKind.CONVERT_TO_NORMAL_PARAMETER,
+        '''
 class A {
   var test;
   A(test) : test = test {
@@ -1453,7 +1688,10 @@
   }
 }
 ''');
-    assertHasAssistAt('test)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, '''
+    assertHasAssistAt(
+        'test)',
+        DartAssistKind.CONVERT_TO_NORMAL_PARAMETER,
+        '''
 class A {
   int test;
   A(int test) : test = test {
@@ -1470,7 +1708,10 @@
   A(this.bbb) : aaa = 1.0;
 }
 ''');
-    assertHasAssistAt('bbb)', DartAssistKind.CONVERT_TO_NORMAL_PARAMETER, '''
+    assertHasAssistAt(
+        'bbb)',
+        DartAssistKind.CONVERT_TO_NORMAL_PARAMETER,
+        '''
 class A {
   double aaa;
   int bbb;
@@ -1553,7 +1794,10 @@
   print(a.test);
 }
 ''');
-    assertHasAssistAt('test = 42', DartAssistKind.ENCAPSULATE_FIELD, '''
+    assertHasAssistAt(
+        'test = 42',
+        DartAssistKind.ENCAPSULATE_FIELD,
+        '''
 class A {
   int _test = 42;
 
@@ -1579,7 +1823,10 @@
   print(a.test);
 }
 ''');
-    assertHasAssistAt('test = 42', DartAssistKind.ENCAPSULATE_FIELD, '''
+    assertHasAssistAt(
+        'test = 42',
+        DartAssistKind.ENCAPSULATE_FIELD,
+        '''
 class A {
   var _test = 42;
 
@@ -1608,7 +1855,10 @@
   return a $initialOperator b;
 }
 ''');
-      assertHasAssistAt(initialOperator, DartAssistKind.EXCHANGE_OPERANDS, '''
+      assertHasAssistAt(
+          initialOperator,
+          DartAssistKind.EXCHANGE_OPERANDS,
+          '''
 bool main(int a, int b) {
   return b $resultOperator a;
 }
@@ -1622,7 +1872,10 @@
   1 * 2 * 3 + 4;
 }
 ''');
-    assertHasAssistAt('* 2', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        '* 2',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   2 * 3 * 1 + 4;
 }
@@ -1635,7 +1888,10 @@
   1 + 2 - 3 + 4;
 }
 ''');
-    assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        '+ 2',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   2 + 1 - 3 + 4;
 }
@@ -1648,7 +1904,10 @@
   1 + 2 + 3;
 }
 ''');
-    assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        '+ 2',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   2 + 3 + 1;
 }
@@ -1661,7 +1920,10 @@
   1 + 2 + 3;
 }
 ''');
-    assertHasAssistAt('+ 3', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        '+ 3',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   3 + 1 + 2;
 }
@@ -1674,7 +1936,10 @@
   1 + 2;
 }
 ''');
-    assertHasAssistAt(' 2', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        ' 2',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   2 + 1;
 }
@@ -1687,7 +1952,10 @@
   1 + 2;
 }
 ''');
-    assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        '+ 2',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   2 + 1;
 }
@@ -1701,7 +1969,10 @@
 }
 ''');
     length = '1 + 2'.length;
-    assertHasAssistAt('1 + 2', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        '1 + 2',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   2 + 1;
 }
@@ -1715,7 +1986,10 @@
 }
 ''');
     length = 2;
-    assertHasAssistAt('+ 2', DartAssistKind.EXCHANGE_OPERANDS, '''
+    assertHasAssistAt(
+        '+ 2',
+        DartAssistKind.EXCHANGE_OPERANDS,
+        '''
 main() {
   2 + 1;
 }
@@ -1784,7 +2058,10 @@
   return x.foo();
 }
 ''');
-    assertHasAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW, '''
+    assertHasAssistAt(
+        'import ',
+        DartAssistKind.IMPORT_ADD_SHOW,
+        '''
 import 'dart:math' show PI;
 main(x) {
   PI;
@@ -1802,7 +2079,10 @@
   max(1, 2);
 }
 ''');
-    assertHasAssistAt('import ', DartAssistKind.IMPORT_ADD_SHOW, '''
+    assertHasAssistAt(
+        'import ',
+        DartAssistKind.IMPORT_ADD_SHOW,
+        '''
 import 'dart:math' show E, PI, max;
 main() {
   PI;
@@ -1821,7 +2101,10 @@
   max(1, 2);
 }
 ''');
-    assertHasAssistAt('art:math', DartAssistKind.IMPORT_ADD_SHOW, '''
+    assertHasAssistAt(
+        'art:math',
+        DartAssistKind.IMPORT_ADD_SHOW,
+        '''
 import 'dart:math' show E, PI, max;
 main() {
   PI;
@@ -1871,10 +2154,11 @@
 ''';
     assertHasAssistAt(
         'is MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
-    _assertLinkedGroup(change.linkedEditGroups[0], [
-      'myTypeName = '
-    ], expectedSuggestions(
-        LinkedEditSuggestionKind.VARIABLE, ['myTypeName', 'typeName', 'name']));
+    _assertLinkedGroup(
+        change.linkedEditGroups[0],
+        ['myTypeName = '],
+        expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
+            ['myTypeName', 'typeName', 'name']));
     // another good location
     assertHasAssistAt(
         'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
@@ -1900,10 +2184,11 @@
 ''';
     assertHasAssistAt(
         'is! MyType', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
-    _assertLinkedGroup(change.linkedEditGroups[0], [
-      'myTypeName = '
-    ], expectedSuggestions(
-        LinkedEditSuggestionKind.VARIABLE, ['myTypeName', 'typeName', 'name']));
+    _assertLinkedGroup(
+        change.linkedEditGroups[0],
+        ['myTypeName = '],
+        expectedSuggestions(LinkedEditSuggestionKind.VARIABLE,
+            ['myTypeName', 'typeName', 'name']));
     // another good location
     assertHasAssistAt(
         'if (p', DartAssistKind.INTRODUCE_LOCAL_CAST_TYPE, expected);
@@ -1948,7 +2233,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (', DartAssistKind.INVERT_IF_STATEMENT, '''
+    assertHasAssistAt(
+        'if (',
+        DartAssistKind.INVERT_IF_STATEMENT,
+        '''
 main() {
   if (false) {
     1;
@@ -1968,7 +2256,10 @@
     1;
 }
 ''');
-    assertHasAssistAt('if (', DartAssistKind.INVERT_IF_STATEMENT, '''
+    assertHasAssistAt(
+        'if (',
+        DartAssistKind.INVERT_IF_STATEMENT,
+        '''
 main() {
   if (false)
     1;
@@ -1988,7 +2279,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        'if (1 ==',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if (1 == 1 && (2 == 2 || 3 == 3)) {
     print(0);
@@ -2008,7 +2302,10 @@
 }
 bool isCheck() => false;
 ''');
-    assertHasAssistAt('if (isCheck', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        'if (isCheck',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if (isCheck() && 2 == 2) {
     print(0);
@@ -2028,7 +2325,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        'if (1 ==',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if ((1 == 1 || 2 == 2) && 3 == 3) {
     print(0);
@@ -2047,7 +2347,10 @@
   }
 }
 ''');
-    assertHasAssistAt('1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        '1 ==',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2066,7 +2369,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        'if (1 ==',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2084,7 +2390,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        'if (1 ==',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2105,7 +2414,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        'if (1 ==',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(1);
@@ -2125,7 +2437,10 @@
     }
 }
 ''');
-    assertHasAssistAt('if (1 ==', DartAssistKind.JOIN_IF_WITH_INNER, '''
+    assertHasAssistAt(
+        'if (1 ==',
+        DartAssistKind.JOIN_IF_WITH_INNER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2194,7 +2509,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (2 ==', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (2 ==',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if (1 == 1 && (2 == 2 || 3 == 3)) {
     print(0);
@@ -2214,7 +2532,10 @@
 }
 bool isCheck() => false;
 ''');
-    assertHasAssistAt('if (isCheck', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (isCheck',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if (1 == 1 && isCheck()) {
     print(0);
@@ -2234,7 +2555,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (3 == 3', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (3 == 3',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if ((1 == 1 || 2 == 2) && 3 == 3) {
     print(0);
@@ -2253,7 +2577,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (2 == 2',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2272,7 +2599,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (2 == 2',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2290,7 +2620,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (2 == 2',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2311,7 +2644,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (2 == 2',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(1);
@@ -2331,7 +2667,10 @@
     }
 }
 ''');
-    assertHasAssistAt('if (2 == 2', DartAssistKind.JOIN_IF_WITH_OUTER, '''
+    assertHasAssistAt(
+        'if (2 == 2',
+        DartAssistKind.JOIN_IF_WITH_OUTER,
+        '''
 main() {
   if (1 == 1 && 2 == 2) {
     print(0);
@@ -2397,7 +2736,10 @@
   v = 1;
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.JOIN_VARIABLE_DECLARATION,
+        '''
 main() {
   var v = 1;
 }
@@ -2494,7 +2836,10 @@
   v = 1;
 }
 ''');
-    assertHasAssistAt('v;', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
+    assertHasAssistAt(
+        'v;',
+        DartAssistKind.JOIN_VARIABLE_DECLARATION,
+        '''
 main() {
   var v = 1;
 }
@@ -2508,7 +2853,10 @@
   v = 1;
 }
 ''');
-    assertHasAssistAt('int v', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
+    assertHasAssistAt(
+        'int v',
+        DartAssistKind.JOIN_VARIABLE_DECLARATION,
+        '''
 main() {
   int v = 1;
 }
@@ -2522,7 +2870,10 @@
   v = 1;
 }
 ''');
-    assertHasAssistAt('var v', DartAssistKind.JOIN_VARIABLE_DECLARATION, '''
+    assertHasAssistAt(
+        'var v',
+        DartAssistKind.JOIN_VARIABLE_DECLARATION,
+        '''
 main() {
   var v = 1;
 }
@@ -2595,7 +2946,10 @@
   int v = 1;
 }
 ''');
-    assertHasAssistAt('v = ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v = ',
+        DartAssistKind.REMOVE_TYPE_ANNOTATION,
+        '''
 class A {
   var v = 1;
 }
@@ -2608,7 +2962,10 @@
   final int v = 1;
 }
 ''');
-    assertHasAssistAt('v = ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'v = ',
+        DartAssistKind.REMOVE_TYPE_ANNOTATION,
+        '''
 class A {
   final v = 1;
 }
@@ -2621,7 +2978,10 @@
   int a = 1, b = 2;
 }
 ''');
-    assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'int ',
+        DartAssistKind.REMOVE_TYPE_ANNOTATION,
+        '''
 main() {
   var a = 1, b = 2;
 }
@@ -2634,7 +2994,10 @@
   const int v = 1;
 }
 ''');
-    assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'int ',
+        DartAssistKind.REMOVE_TYPE_ANNOTATION,
+        '''
 main() {
   const v = 1;
 }
@@ -2647,7 +3010,10 @@
   final int v = 1;
 }
 ''');
-    assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'int ',
+        DartAssistKind.REMOVE_TYPE_ANNOTATION,
+        '''
 main() {
   final v = 1;
 }
@@ -2658,7 +3024,10 @@
     resolveTestUnit('''
 int V = 1;
 ''');
-    assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'int ',
+        DartAssistKind.REMOVE_TYPE_ANNOTATION,
+        '''
 var V = 1;
 ''');
   }
@@ -2667,7 +3036,10 @@
     resolveTestUnit('''
 final int V = 1;
 ''');
-    assertHasAssistAt('int ', DartAssistKind.REMOVE_TYPE_ANNOTATION, '''
+    assertHasAssistAt(
+        'int ',
+        DartAssistKind.REMOVE_TYPE_ANNOTATION,
+        '''
 final V = 1;
 ''');
   }
@@ -2680,7 +3052,9 @@
 }
 ''');
     // on conditional
-    assertHasAssistAt('11 :', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
+    assertHasAssistAt(
+        '11 :',
+        DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
         '''
 main() {
   var v;
@@ -2692,7 +3066,9 @@
 }
 ''');
     // on variable
-    assertHasAssistAt('v =', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
         '''
 main() {
   var v;
@@ -2711,8 +3087,10 @@
   return true ? 111 : 222;
 }
 ''');
-    assertHasAssistAt('return ',
-        DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE, '''
+    assertHasAssistAt(
+        'return ',
+        DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
+        '''
 main() {
   if (true) {
     return 111;
@@ -2729,7 +3107,9 @@
   int a = 1, vvv = true ? 111 : 222, b = 2;
 }
 ''');
-    assertHasAssistAt('11 :', DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
+    assertHasAssistAt(
+        '11 :',
+        DartAssistKind.REPLACE_CONDITIONAL_WITH_IF_ELSE,
         '''
 main() {
   int a = 1, vvv, b = 2;
@@ -2769,8 +3149,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (true)',
-        DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, '''
+    assertHasAssistAt(
+        'if (true)',
+        DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL,
+        '''
 main() {
   int vvv;
   vvv = true ? 111 : 222;
@@ -2788,8 +3170,10 @@
   }
 }
 ''');
-    assertHasAssistAt('if (true)',
-        DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL, '''
+    assertHasAssistAt(
+        'if (true)',
+        DartAssistKind.REPLACE_IF_ELSE_WITH_CONDITIONAL,
+        '''
 main() {
   return true ? 111 : 222;
 }
@@ -2843,7 +3227,10 @@
   }
 }
 ''');
-    assertHasAssistAt('&& 2 == 2', DartAssistKind.SPLIT_AND_CONDITION, '''
+    assertHasAssistAt(
+        '&& 2 == 2',
+        DartAssistKind.SPLIT_AND_CONDITION,
+        '''
 main() {
   if (1 == 1) {
     if (2 == 2 && 3 == 3) {
@@ -2865,7 +3252,10 @@
   }
 }
 ''');
-    assertHasAssistAt('&& false', DartAssistKind.SPLIT_AND_CONDITION, '''
+    assertHasAssistAt(
+        '&& false',
+        DartAssistKind.SPLIT_AND_CONDITION,
+        '''
 main() {
   if (true) {
     if (false) {
@@ -2886,7 +3276,10 @@
     print(0);
 }
 ''');
-    assertHasAssistAt('&& false', DartAssistKind.SPLIT_AND_CONDITION, '''
+    assertHasAssistAt(
+        '&& false',
+        DartAssistKind.SPLIT_AND_CONDITION,
+        '''
 main() {
   if (true)
     if (false)
@@ -2967,7 +3360,10 @@
   var v = 1;
 }
 ''');
-    assertHasAssistAt('v =', DartAssistKind.SPLIT_VARIABLE_DECLARATION, '''
+    assertHasAssistAt(
+        'v =',
+        DartAssistKind.SPLIT_VARIABLE_DECLARATION,
+        '''
 main() {
   var v;
   v = 1;
@@ -2981,7 +3377,10 @@
   int v = 1;
 }
 ''');
-    assertHasAssistAt('int ', DartAssistKind.SPLIT_VARIABLE_DECLARATION, '''
+    assertHasAssistAt(
+        'int ',
+        DartAssistKind.SPLIT_VARIABLE_DECLARATION,
+        '''
 main() {
   int v;
   v = 1;
@@ -2995,7 +3394,10 @@
   var v = 1;
 }
 ''');
-    assertHasAssistAt('var ', DartAssistKind.SPLIT_VARIABLE_DECLARATION, '''
+    assertHasAssistAt(
+        'var ',
+        DartAssistKind.SPLIT_VARIABLE_DECLARATION,
+        '''
 main() {
   var v;
   v = 1;
@@ -3022,7 +3424,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_BLOCK, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_BLOCK,
+        '''
 main() {
 // start
   {
@@ -3044,7 +3448,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_DO_WHILE, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_DO_WHILE,
+        '''
 main() {
 // start
   do {
@@ -3066,7 +3472,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_FOR, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_FOR,
+        '''
 main() {
 // start
   for (var v = init; condition; increment) {
@@ -3088,7 +3496,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_FOR_IN, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_FOR_IN,
+        '''
 main() {
 // start
   for (var item in iterable) {
@@ -3110,7 +3520,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_IF, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_IF,
+        '''
 main() {
 // start
   if (condition) {
@@ -3132,7 +3544,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_TRY_CATCH, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_TRY_CATCH,
+        '''
 main() {
 // start
   try {
@@ -3156,7 +3570,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_TRY_FINALLY, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_TRY_FINALLY,
+        '''
 main() {
 // start
   try {
@@ -3180,7 +3596,9 @@
 }
 ''');
     _setStartEndSelection();
-    assertHasAssist(DartAssistKind.SURROUND_WITH_WHILE, '''
+    assertHasAssist(
+        DartAssistKind.SURROUND_WITH_WHILE,
+        '''
 main() {
 // start
   while (condition) {
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 4bbaeb1..f0692c6 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -47,7 +47,9 @@
   $lineWithTest
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   bool b = true;
   $lineWithTest
@@ -114,7 +116,9 @@
   Test(this.a);
 }
 ''');
-    assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
+    assertHasFix(
+        DartFixKind.ADD_FIELD_FORMAL_PARAMETERS,
+        '''
 class Test {
   final int a;
   final int b;
@@ -133,7 +137,9 @@
   Test();
 }
 ''');
-    assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
+    assertHasFix(
+        DartFixKind.ADD_FIELD_FORMAL_PARAMETERS,
+        '''
 class Test {
   final int a;
   final int b;
@@ -152,7 +158,9 @@
   Test([this.c]);
 }
 ''');
-    assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
+    assertHasFix(
+        DartFixKind.ADD_FIELD_FORMAL_PARAMETERS,
+        '''
 class Test {
   final int a;
   final int b;
@@ -169,7 +177,9 @@
   test(1);
 }
 ''');
-    assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, '''
+    assertHasFix(
+        DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL,
+        '''
 test([int i]) {}
 main() {
   test(1);
@@ -184,7 +194,9 @@
   test(1, 2.0);
 }
 ''');
-    assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
+    assertHasFix(
+        DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
+        '''
 test(int a, double d) {}
 main() {
   test(1, 2.0);
@@ -199,7 +211,9 @@
   test(1);
 }
 ''');
-    assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
+    assertHasFix(
+        DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
+        '''
 test(int i) {}
 main() {
   test(1);
@@ -216,7 +230,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL, '''
+    assertHasFix(
+        DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL,
+        '''
 class A {
   test(int a, [double d]) {}
   main() {
@@ -235,7 +251,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
+    assertHasFix(
+        DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
+        '''
 class A {
   test(int a, double d) {}
   main() {
@@ -254,7 +272,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_REQUIRED, '''
+    assertHasFix(
+        DartFixKind.ADD_MISSING_PARAMETER_REQUIRED,
+        '''
 class A {
   test(int i) {}
   main() {
@@ -285,7 +305,9 @@
     expect(fileEdits, hasLength(1));
     SourceFileEdit fileEdit = change.edits[0];
     expect(fileEdit.file, '/part.dart');
-    expect(SourceEdit.applySequence(partCode, fileEdit.edits), r'''
+    expect(
+        SourceEdit.applySequence(partCode, fileEdit.edits),
+        r'''
 // Comment first.
 // Comment second.
 
@@ -332,7 +354,9 @@
       expect(fileEdits, hasLength(1));
       resultCode = SourceEdit.applySequence(testCode, fileEdits[0].edits);
       // verify
-      expect(resultCode, '''
+      expect(
+          resultCode,
+          '''
 foo() {}
 main() async {
   await foo();
@@ -349,7 +373,9 @@
 foo() {}
 main() => await foo();
 ''');
-    assertHasFix(DartFixKind.ADD_ASYNC, '''
+    assertHasFix(
+        DartFixKind.ADD_ASYNC,
+        '''
 foo() {}
 main() async => await foo();
 ''');
@@ -361,7 +387,9 @@
   boolean v;
 }
 ''');
-    assertHasFix(DartFixKind.REPLACE_BOOLEAN_WITH_BOOL, '''
+    assertHasFix(
+        DartFixKind.REPLACE_BOOLEAN_WITH_BOOL,
+        '''
 main() {
   bool v;
 }
@@ -377,7 +405,9 @@
   a.foo();
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO_STATIC_ACCESS,
+        '''
 class A {
   static foo() {}
 }
@@ -388,13 +418,17 @@
   }
 
   void test_changeToStaticAccess_method_importType() {
-    addSource('/libA.dart', r'''
+    addSource(
+        '/libA.dart',
+        r'''
 library libA;
 class A {
   static foo() {}
 }
 ''');
-    addSource('/libB.dart', r'''
+    addSource(
+        '/libB.dart',
+        r'''
 library libB;
 import 'libA.dart';
 class B extends A {}
@@ -405,7 +439,9 @@
   b.foo();
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO_STATIC_ACCESS,
+        '''
 import 'libB.dart';
 import 'libA.dart';
 main(B b) {
@@ -421,7 +457,9 @@
   f.wait([]);
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO_STATIC_ACCESS,
+        '''
 import 'dart:async' as pref;
 main(pref.Future f) {
   pref.Future.wait([]);
@@ -438,7 +476,9 @@
   a.foo;
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO_STATIC_ACCESS,
+        '''
 class A {
   static get foo => 42;
 }
@@ -449,13 +489,17 @@
   }
 
   void test_changeToStaticAccess_property_importType() {
-    addSource('/libA.dart', r'''
+    addSource(
+        '/libA.dart',
+        r'''
 library libA;
 class A {
   static get foo => null;
 }
 ''');
-    addSource('/libB.dart', r'''
+    addSource(
+        '/libB.dart',
+        r'''
 library libB;
 import 'libA.dart';
 class B extends A {}
@@ -466,7 +510,9 @@
   b.foo;
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO_STATIC_ACCESS, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO_STATIC_ACCESS,
+        '''
 import 'libB.dart';
 import 'libA.dart';
 main(B b) {
@@ -481,7 +527,9 @@
   Test v = null;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CLASS, '''
+    assertHasFix(
+        DartFixKind.CREATE_CLASS,
+        '''
 main() {
   Test v = null;
 }
@@ -515,7 +563,9 @@
     expect(fileEdits, hasLength(1));
     SourceFileEdit fileEdit = change.edits[0];
     expect(fileEdit.file, '/lib.dart');
-    expect(SourceEdit.applySequence(libCode, fileEdit.edits), r'''
+    expect(
+        SourceEdit.applySequence(libCode, fileEdit.edits),
+        r'''
 library my.lib;
 
 class A {}
@@ -534,7 +584,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CLASS, '''
+    assertHasFix(
+        DartFixKind.CREATE_CLASS,
+        '''
 f() {
   g() {
     Test v = null;
@@ -547,6 +599,51 @@
     _assertLinkedGroup(change.linkedEditGroups[0], ['Test v =', 'Test {']);
   }
 
+  void test_createClass_itemOfList() {
+    resolveTestUnit('''
+main() {
+  var a = [Test];
+}
+''');
+    assertHasFix(
+        DartFixKind.CREATE_CLASS,
+        '''
+main() {
+  var a = [Test];
+}
+
+class Test {
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['Test];', 'Test {']);
+  }
+
+  void test_createClass_itemOfList_inAnnotation() {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+    };
+    resolveTestUnit('''
+class MyAnnotation {
+  const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+''');
+    assertHasFix(
+        DartFixKind.CREATE_CLASS,
+        '''
+class MyAnnotation {
+  const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Test])
+main() {}
+
+class Test {
+}
+''');
+    _assertLinkedGroup(change.linkedEditGroups[0], ['Test])', 'Test {']);
+  }
+
   void test_createConstructor_forFinalFields() {
     errorFilter = (AnalysisError error) {
       return error.message.contains("'a'");
@@ -558,7 +655,9 @@
   final int c;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS,
+        '''
 class Test {
   final int a;
   final int b = 2;
@@ -580,7 +679,9 @@
   new A(1, 2.0);
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR,
+        '''
 class A {
   int field;
 
@@ -604,7 +705,9 @@
   new A.named(1, 2.0);
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR,
+        '''
 class A {
   A.named(int i, double d) {
   }
@@ -643,7 +746,9 @@
   B() {}
 }
 ''');
-    assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
+    assertHasFix(
+        DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
+        '''
 class A {
   A(bool p1, int p2, double p3, String p4, {p5});
 }
@@ -663,7 +768,9 @@
   B() : field = 42 {}
 }
 ''');
-    assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
+    assertHasFix(
+        DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
+        '''
 class A {
   A(int p);
 }
@@ -683,7 +790,9 @@
   B() {}
 }
 ''');
-    assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
+    assertHasFix(
+        DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
+        '''
 class A {
   A.named(int p);
 }
@@ -714,7 +823,9 @@
   B();
 }
 ''');
-    assertHasFix(DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION, '''
+    assertHasFix(
+        DartFixKind.ADD_SUPER_CONSTRUCTOR_INVOCATION,
+        '''
 class A<T> {
   A(T p);
 }
@@ -735,7 +846,9 @@
   void existingMethod() {}
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR_SUPER,
+        '''
 class A {
   A(p1, int p2, List<String> p3, [int p4]);
 }
@@ -761,7 +874,9 @@
   void existingMethod() {}
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR_SUPER,
+        '''
 class A {
   int _field;
   A(this._field);
@@ -777,11 +892,15 @@
   }
 
   void test_createConstructorSuperImplicit_importType() {
-    addSource('/libA.dart', r'''
+    addSource(
+        '/libA.dart',
+        r'''
 library libA;
 class A {}
 ''');
-    addSource('/libB.dart', r'''
+    addSource(
+        '/libB.dart',
+        r'''
 library libB;
 import 'libA.dart';
 class B {
@@ -793,7 +912,9 @@
 class C extends B {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR_SUPER,
+        '''
 import 'libB.dart';
 import 'libA.dart';
 class C extends B {
@@ -813,7 +934,9 @@
   void existingMethod() {}
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR_SUPER,
+        '''
 class A {
   A.named(p1, int p2);
 }
@@ -846,7 +969,9 @@
 }
 class D extends C<int> {
 }''');
-    assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_SUPER, '''
+    assertHasFix(
+        DartFixKind.CREATE_CONSTRUCTOR_SUPER,
+        '''
 class C<T> {
   final T x;
   C(this.x);
@@ -891,7 +1016,9 @@
   int v = c.b.a.test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int test;
 }
@@ -915,7 +1042,9 @@
   int v = a.test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int test;
 }
@@ -936,7 +1065,9 @@
 class B {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   B b;
   void f(Object p) {
@@ -958,7 +1089,9 @@
 }
 f(String s) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   String test;
 
@@ -978,7 +1111,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int test;
 
@@ -997,7 +1132,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   var test;
 
@@ -1017,7 +1154,9 @@
   int v = x.test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int test;
 }
@@ -1037,7 +1176,9 @@
   x.test = 0;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int test;
 }
@@ -1049,11 +1190,15 @@
   }
 
   void test_createField_importType() {
-    addSource('/libA.dart', r'''
+    addSource(
+        '/libA.dart',
+        r'''
 library libA;
 class A {}
 ''');
-    addSource('/libB.dart', r'''
+    addSource(
+        '/libB.dart',
+        r'''
 library libB;
 import 'libA.dart';
 A getA() => null;
@@ -1066,7 +1211,9 @@
   c.test = getA();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 import 'libB.dart';
 import 'libA.dart';
 class C {
@@ -1089,7 +1236,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   List test;
 }
@@ -1112,7 +1261,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A<T> {
   List<T> items;
 
@@ -1137,7 +1288,9 @@
   a.test = 5;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int aaa;
   int zzz;
@@ -1161,7 +1314,9 @@
   a.test = 5;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int test;
 
@@ -1181,7 +1336,9 @@
   A.test = 5;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   static int test;
 }
@@ -1199,7 +1356,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   int test;
 
@@ -1218,7 +1377,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FIELD, '''
+    assertHasFix(
+        DartFixKind.CREATE_FIELD,
+        '''
 class A {
   static int test;
 
@@ -1244,7 +1405,48 @@
     expect(fileEdit.file, '/my/project/bin/my_file.dart');
     expect(fileEdit.fileStamp, -1);
     expect(fileEdit.edits, hasLength(1));
-    expect(fileEdit.edits[0].replacement, contains('library my.file;'));
+    expect(fileEdit.edits[0].replacement, contains('library my_file;'));
+  }
+
+  void test_createFile_forImport_inPackage_lib() {
+    provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
+    testFile = '/projects/my_package/lib/test.dart';
+    provider.newFolder('/projects/my_package/lib');
+    resolveTestUnit('''
+import 'a/bb/c_cc/my_lib.dart';
+''');
+    AnalysisError error = _findErrorToFix();
+    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    change = fix.change;
+    // validate change
+    List<SourceFileEdit> fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+    SourceFileEdit fileEdit = change.edits[0];
+    expect(fileEdit.file, '/projects/my_package/lib/a/bb/c_cc/my_lib.dart');
+    expect(fileEdit.fileStamp, -1);
+    expect(fileEdit.edits, hasLength(1));
+    expect(fileEdit.edits[0].replacement,
+        contains('library my_package.a.bb.c_cc.my_lib;'));
+  }
+
+  void test_createFile_forImport_inPackage_test() {
+    provider.newFile('/projects/my_package/pubspec.yaml', 'name: my_package');
+    testFile = '/projects/my_package/test/misc/test_all.dart';
+    resolveTestUnit('''
+import 'a/bb/my_lib.dart';
+''');
+    AnalysisError error = _findErrorToFix();
+    fix = _assertHasFix(DartFixKind.CREATE_FILE, error);
+    change = fix.change;
+    // validate change
+    List<SourceFileEdit> fileEdits = change.edits;
+    expect(fileEdits, hasLength(1));
+    SourceFileEdit fileEdit = change.edits[0];
+    expect(fileEdit.file, '/projects/my_package/test/misc/a/bb/my_lib.dart');
+    expect(fileEdit.fileStamp, -1);
+    expect(fileEdit.edits, hasLength(1));
+    expect(fileEdit.edits[0].replacement,
+        contains('library my_package.test.misc.a.bb.my_lib;'));
   }
 
   void test_createFile_forPart() {
@@ -1267,17 +1469,22 @@
   }
 
   void test_createFile_forPart_inPackageLib() {
-    provider.newFile('/my/pubspec.yaml', r'''
+    provider.newFile(
+        '/my/pubspec.yaml',
+        r'''
 name: my_test
 ''');
     testFile = '/my/lib/test.dart';
-    addTestSource('''
+    addTestSource(
+        '''
 library my.lib;
 part 'my_part.dart';
-''', Uri.parse('package:my/test.dart'));
+''',
+        Uri.parse('package:my/test.dart'));
     // configure SourceFactory
-    UriResolver pkgResolver = new PackageMapUriResolver(
-        provider, {'my': [provider.getResource('/my/lib')],});
+    UriResolver pkgResolver = new PackageMapUriResolver(provider, {
+      'my': [provider.getResource('/my/lib')],
+    });
     context.sourceFactory = new SourceFactory(
         [AbstractContextTest.SDK_RESOLVER, pkgResolver, resourceResolver]);
     // prepare fix
@@ -1313,7 +1520,9 @@
   int v = x.test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   int get test => null;
 }
@@ -1338,7 +1547,9 @@
   int v = c.b.a.test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   int get test => null;
 }
@@ -1362,7 +1573,9 @@
   int v = a.test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   int get test => null;
 }
@@ -1383,7 +1596,9 @@
 class B {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   B b;
   void f(Object p) {
@@ -1416,7 +1631,9 @@
 }
 f(String s) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   String get test => null;
 
@@ -1447,7 +1664,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   int get test => null;
 
@@ -1466,7 +1685,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   get test => null;
 
@@ -1485,7 +1706,9 @@
   foo(bar);
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
+    assertHasFix(
+        DartFixKind.CREATE_LOCAL_VARIABLE,
+        '''
 typedef MY_FUNCTION(int p);
 foo(MY_FUNCTION f) {}
 main() {
@@ -1511,7 +1734,9 @@
   int a = test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
+    assertHasFix(
+        DartFixKind.CREATE_LOCAL_VARIABLE,
+        '''
 main() {
   int test;
   int a = test;
@@ -1527,7 +1752,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
+    assertHasFix(
+        DartFixKind.CREATE_LOCAL_VARIABLE,
+        '''
 main() {
   bool test;
   if (!test) {
@@ -1544,7 +1771,9 @@
 }
 f(String p) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
+    assertHasFix(
+        DartFixKind.CREATE_LOCAL_VARIABLE,
+        '''
 main() {
   String test;
   f(test);
@@ -1561,7 +1790,9 @@
   test.add('hello');
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
+    assertHasFix(
+        DartFixKind.CREATE_LOCAL_VARIABLE,
+        '''
 main() {
   var test;
   test.add('hello');
@@ -1576,7 +1807,9 @@
   test = 42;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
+    assertHasFix(
+        DartFixKind.CREATE_LOCAL_VARIABLE,
+        '''
 main() {
   var test = 42;
 }
@@ -1589,7 +1822,9 @@
   test += 42;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_LOCAL_VARIABLE, '''
+    assertHasFix(
+        DartFixKind.CREATE_LOCAL_VARIABLE,
+        '''
 main() {
   int test;
   test += 42;
@@ -1608,7 +1843,9 @@
 class MyEmulator extends Emulator {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 typedef int Binary(int left, int right);
 
 abstract class Emulator {
@@ -1633,7 +1870,9 @@
 class B extends A {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 abstract class A {
   forEach(int f(double p1, String p2));
 }
@@ -1659,7 +1898,9 @@
 class Test extends IterableMixin<int> {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 class Iterator<T> {
 }
 
@@ -1684,7 +1925,9 @@
 class Test<V> extends ItemProvider<V> {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 abstract class ItemProvider<T> {
   List<T> getItems();
 }
@@ -1708,7 +1951,9 @@
 class B extends A {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 abstract class A {
   get g1;
   int get g2;
@@ -1736,7 +1981,9 @@
 class B extends A {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 import 'dart:async' as aaa;
 abstract class A {
   Map<aaa.Future, List<aaa.Future>> g(aaa.Future p);
@@ -1762,7 +2009,9 @@
 class B implements A {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 class A {
   int ma;
   void mb() {}
@@ -1865,7 +2114,9 @@
 class B extends A {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 abstract class A {
   int operator [](int index);
   void operator []=(int index, String value);
@@ -1896,7 +2147,9 @@
 class B extends A {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_MISSING_OVERRIDES, '''
+    assertHasFix(
+        DartFixKind.CREATE_MISSING_OVERRIDES,
+        '''
 abstract class A {
   set s1(x);
   set s2(int x);
@@ -1933,7 +2186,9 @@
   existing() {}
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_NO_SUCH_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_NO_SUCH_METHOD,
+        '''
 abstract class A {
   m1();
   int m2();
@@ -1960,7 +2215,9 @@
   int v = a.test;
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_GETTER, '''
+    assertHasFix(
+        DartFixKind.CREATE_GETTER,
+        '''
 class A {
   int existingField;
 
@@ -1990,7 +2247,9 @@
   a..ma().useFunction(test);
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 class A {
   B ma() => null;
 }
@@ -2015,7 +2274,9 @@
 }
 useFunction({Function g}) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   useFunction(g: test);
 }
@@ -2033,7 +2294,9 @@
 }
 useFunction(int g(a, b)) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   useFunction(test);
 }
@@ -2051,7 +2314,9 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   useFunction(test);
 }
@@ -2069,7 +2334,9 @@
 }
 useFunction({int g(double a, String b)}) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   useFunction(g: test);
 }
@@ -2081,11 +2348,15 @@
   }
 
   void test_creationFunction_forFunctionType_importType() {
-    addSource('/libA.dart', r'''
+    addSource(
+        '/libA.dart',
+        r'''
 library libA;
 class A {}
 ''');
-    addSource('/libB.dart', r'''
+    addSource(
+        '/libB.dart',
+        r'''
 library libB;
 import 'libA.dart';
 useFunction(int g(A a)) {}
@@ -2096,7 +2367,9 @@
   useFunction(test);
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 import 'libB.dart';
 import 'libA.dart';
 main() {
@@ -2117,7 +2390,9 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   static foo() {
     useFunction(test);
@@ -2138,7 +2413,9 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   var f;
   A() : f = useFunction(test);
@@ -2159,7 +2436,9 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 main(A a) {
   useFunction(a.test);
 }
@@ -2181,7 +2460,9 @@
 }
 useFunction(int g(double a, String b)) {}
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 main(A a) {
   useFunction(a.test);
 }
@@ -2225,7 +2506,9 @@
   print(0)
 }
 ''');
-    assertHasFix(DartFixKind.INSERT_SEMICOLON, '''
+    assertHasFix(
+        DartFixKind.INSERT_SEMICOLON,
+        '''
 main() {
   print(0);
 }
@@ -2241,7 +2524,9 @@
 int main() async {
 }
 ''');
-    assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+    assertHasFix(
+        DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
+        '''
 library main;
 import 'dart:async';
 Future<int> main() async {
@@ -2258,7 +2543,9 @@
 int main() async {
 }
 ''');
-    assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+    assertHasFix(
+        DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
+        '''
 import 'dart:async' as al;
 al.Future<int> main() async {
 }
@@ -2274,7 +2561,9 @@
 List<int> main() async {
 }
 ''');
-    assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+    assertHasFix(
+        DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
+        '''
 import 'dart:async';
 Future<List<int>> main() async {
 }
@@ -2290,7 +2579,9 @@
 void main() async {
 }
 ''');
-    assertHasFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, '''
+    assertHasFix(
+        DartFixKind.REPLACE_RETURN_TYPE_FUTURE,
+        '''
 import 'dart:async';
 Future main() async {
 }
@@ -2309,7 +2600,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import 'package:my_pkg/my_lib.dart';
 
 main() {
@@ -2326,7 +2619,9 @@
   Future f = null;
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PREFIX, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PREFIX,
+        '''
 import 'dart:async' as pref;
 main() {
   pref.Stream s = null;
@@ -2343,7 +2638,9 @@
   print(PI);
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PREFIX, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PREFIX,
+        '''
 import 'dart:math' as pref;
 main() {
   print(pref.E);
@@ -2353,7 +2650,9 @@
   }
 
   void test_importLibraryProject_withClass_annotation() {
-    addSource('/lib.dart', '''
+    addSource(
+        '/lib.dart',
+        '''
 library lib;
 class Test {
   const Test(int p);
@@ -2365,7 +2664,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import 'lib.dart';
 
 @Test(0)
@@ -2376,7 +2677,9 @@
 
   void test_importLibraryProject_withClass_inParentFolder() {
     testFile = '/project/bin/test.dart';
-    addSource('/project/lib.dart', '''
+    addSource(
+        '/project/lib.dart',
+        '''
 library lib;
 class Test {}
 ''');
@@ -2386,7 +2689,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import '../lib.dart';
 
 main() {
@@ -2397,7 +2702,9 @@
 
   void test_importLibraryProject_withClass_inRelativeFolder() {
     testFile = '/project/bin/test.dart';
-    addSource('/project/lib/sub/folder/lib.dart', '''
+    addSource(
+        '/project/lib/sub/folder/lib.dart',
+        '''
 library lib;
 class Test {}
 ''');
@@ -2407,7 +2714,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import '../lib/sub/folder/lib.dart';
 
 main() {
@@ -2418,7 +2727,9 @@
 
   void test_importLibraryProject_withClass_inSameFolder() {
     testFile = '/project/bin/test.dart';
-    addSource('/project/bin/lib.dart', '''
+    addSource(
+        '/project/bin/lib.dart',
+        '''
 library lib;
 class Test {}
 ''');
@@ -2428,7 +2739,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import 'lib.dart';
 
 main() {
@@ -2438,7 +2751,9 @@
   }
 
   void test_importLibraryProject_withFunction() {
-    addSource('/lib.dart', '''
+    addSource(
+        '/lib.dart',
+        '''
 library lib;
 myFunction() {}
 ''');
@@ -2448,7 +2763,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import 'lib.dart';
 
 main() {
@@ -2458,7 +2775,9 @@
   }
 
   void test_importLibraryProject_withFunction_unresolvedMethod() {
-    addSource('/lib.dart', '''
+    addSource(
+        '/lib.dart',
+        '''
 library lib;
 myFunction() {}
 ''');
@@ -2470,7 +2789,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import 'lib.dart';
 
 class A {
@@ -2483,7 +2804,9 @@
 
   void test_importLibraryProject_withFunctionTypeAlias() {
     testFile = '/project/bin/test.dart';
-    addSource('/project/bin/lib.dart', '''
+    addSource(
+        '/project/bin/lib.dart',
+        '''
 library lib;
 typedef MyFunction();
 ''');
@@ -2493,7 +2816,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import 'lib.dart';
 
 main() {
@@ -2503,7 +2828,9 @@
   }
 
   void test_importLibraryProject_withTopLevelVariable() {
-    addSource('/lib.dart', '''
+    addSource(
+        '/lib.dart',
+        '''
 library lib;
 int MY_VAR = 42;
 ''');
@@ -2513,7 +2840,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_PROJECT, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_PROJECT,
+        '''
 import 'lib.dart';
 
 main() {
@@ -2528,7 +2857,9 @@
   p as Future;
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:async';
 
 main(p) {
@@ -2543,7 +2874,9 @@
   Future.wait(null);
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:async';
 
 main() {
@@ -2558,7 +2891,9 @@
   p is Future;
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:async';
 
 main(p) {
@@ -2567,13 +2902,57 @@
 ''');
   }
 
+  void test_importLibrarySdk_withClass_itemOfList() {
+    resolveTestUnit('''
+main() {
+  var a = [Future];
+}
+''');
+    performAllAnalysisTasks();
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
+import 'dart:async';
+
+main() {
+  var a = [Future];
+}
+''');
+  }
+
+  void test_importLibrarySdk_withClass_itemOfList_inAnnotation() {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+    };
+    resolveTestUnit('''
+class MyAnnotation {
+  const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Future])
+main() {}
+''');
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
+import 'dart:async';
+
+class MyAnnotation {
+  const MyAnnotation(a, b);
+}
+@MyAnnotation(int, const [Future])
+main() {}
+''');
+  }
+
   void test_importLibrarySdk_withClass_typeAnnotation() {
     resolveTestUnit('''
 main() {
   Future f = null;
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:async';
 
 main() {
@@ -2588,7 +2967,9 @@
   Future.wait;
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:async';
 
 main() {
@@ -2603,7 +2984,9 @@
   List<Future> futures = [];
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:async';
 
 main() {
@@ -2619,7 +3002,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:math';
 
 main() {
@@ -2635,7 +3020,9 @@
 }
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SDK, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SDK,
+        '''
 import 'dart:math';
 
 @PI
@@ -2652,7 +3039,9 @@
   Future f = null;
 }
 ''');
-    assertHasFix(DartFixKind.IMPORT_LIBRARY_SHOW, '''
+    assertHasFix(
+        DartFixKind.IMPORT_LIBRARY_SHOW,
+        '''
 import 'dart:async' show Future, Stream;
 main() {
   Stream s = null;
@@ -2667,7 +3056,9 @@
   p is! Null;
 }
 ''');
-    assertHasFix(DartFixKind.USE_NOT_EQ_NULL, '''
+    assertHasFix(
+        DartFixKind.USE_NOT_EQ_NULL,
+        '''
 main(p) {
   p != null;
 }
@@ -2680,7 +3071,9 @@
   p is Null;
 }
 ''');
-    assertHasFix(DartFixKind.USE_EQ_EQ_NULL, '''
+    assertHasFix(
+        DartFixKind.USE_EQ_EQ_NULL,
+        '''
 main(p) {
   p == null;
 }
@@ -2693,7 +3086,9 @@
   m();
 }
 ''');
-    assertHasFix(DartFixKind.MAKE_CLASS_ABSTRACT, '''
+    assertHasFix(
+        DartFixKind.MAKE_CLASS_ABSTRACT,
+        '''
 abstract class A {
   m();
 }
@@ -2708,7 +3103,9 @@
 class B extends A {
 }
 ''');
-    assertHasFix(DartFixKind.MAKE_CLASS_ABSTRACT, '''
+    assertHasFix(
+        DartFixKind.MAKE_CLASS_ABSTRACT,
+        '''
 abstract class A {
   m();
 }
@@ -2736,7 +3133,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_DEAD_CODE, '''
+    assertHasFix(
+        DartFixKind.REMOVE_DEAD_CODE,
+        '''
 main(int p) {
   if (true) {
     print(1);
@@ -2753,7 +3152,9 @@
   print(1);
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_DEAD_CODE, '''
+    assertHasFix(
+        DartFixKind.REMOVE_DEAD_CODE,
+        '''
 int main() {
   print(0);
   return 42;
@@ -2770,7 +3171,9 @@
   print(2);
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_DEAD_CODE, '''
+    assertHasFix(
+        DartFixKind.REMOVE_DEAD_CODE,
+        '''
 int main() {
   print(0);
   return 42;
@@ -2784,7 +3187,9 @@
   int get foo() => 0;
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION, '''
+    assertHasFix(
+        DartFixKind.REMOVE_PARAMETERS_IN_GETTER_DECLARATION,
+        '''
 class A {
   int get foo => 0;
 }
@@ -2800,7 +3205,9 @@
   a.foo();
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION, '''
+    assertHasFix(
+        DartFixKind.REMOVE_PARENTHESIS_IN_GETTER_INVOCATION,
+        '''
 class A {
   int get foo => 0;
 }
@@ -2818,7 +3225,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_UNNECASSARY_CAST, '''
+    assertHasFix(
+        DartFixKind.REMOVE_UNNECASSARY_CAST,
+        '''
 main(Object p) {
   if (p is String) {
     String v = p;
@@ -2837,7 +3246,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE, '''
+    assertHasFix(
+        DartFixKind.REMOVE_UNUSED_CATCH_CLAUSE,
+        '''
 main() {
   try {
     throw 42;
@@ -2857,7 +3268,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_UNUSED_CATCH_STACK, '''
+    assertHasFix(
+        DartFixKind.REMOVE_UNUSED_CATCH_STACK,
+        '''
 main() {
   try {
     throw 42;
@@ -2873,7 +3286,9 @@
 main() {
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, '''
+    assertHasFix(
+        DartFixKind.REMOVE_UNUSED_IMPORT,
+        '''
 main() {
 }
 ''');
@@ -2887,7 +3302,9 @@
   Future f;
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, '''
+    assertHasFix(
+        DartFixKind.REMOVE_UNUSED_IMPORT,
+        '''
 import 'dart:async';
 
 main() {
@@ -2903,7 +3320,9 @@
 main() {
 }
 ''');
-    assertHasFix(DartFixKind.REMOVE_UNUSED_IMPORT, '''
+    assertHasFix(
+        DartFixKind.REMOVE_UNUSED_IMPORT,
+        '''
 main() {
 }
 ''');
@@ -2916,7 +3335,9 @@
 import 'no/matter/lib.dart';
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.REPLACE_IMPORT_URI, '''
+    assertHasFix(
+        DartFixKind.REPLACE_IMPORT_URI,
+        '''
 import '../foo/bar/lib.dart';
 ''');
   }
@@ -2927,7 +3348,9 @@
 import 'no/matter/my_lib.dart';
 ''');
     performAllAnalysisTasks();
-    assertHasFix(DartFixKind.REPLACE_IMPORT_URI, '''
+    assertHasFix(
+        DartFixKind.REPLACE_IMPORT_URI,
+        '''
 import 'package:my_pkg/my_lib.dart';
 ''');
   }
@@ -2941,7 +3364,9 @@
   Map<String, var> m;
 }
 ''');
-    assertHasFix(DartFixKind.REPLACE_VAR_WITH_DYNAMIC, '''
+    assertHasFix(
+        DartFixKind.REPLACE_VAR_WITH_DYNAMIC,
+        '''
 class A {
   Map<String, dynamic> m;
 }
@@ -2955,7 +3380,9 @@
 }
 const a = new A();
 ''');
-    assertHasFix(DartFixKind.USE_CONST, '''
+    assertHasFix(
+        DartFixKind.USE_CONST,
+        '''
 class A {
   const A();
 }
@@ -2969,7 +3396,9 @@
   Stirng s = 'abc';
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 main() {
   String s = 'abc';
 }
@@ -2983,7 +3412,9 @@
   MyCalss v = null;
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class MyClass {}
 main() {
   MyClass v = null;
@@ -2998,7 +3429,9 @@
   test(v);
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   dynamic v;
   test(v);
@@ -3015,7 +3448,9 @@
   dynamic v = test();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   dynamic v = test();
 }
@@ -3031,7 +3466,9 @@
   int v = myUndefinedFunction(1, 2.0, '3');
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   int v = myUndefinedFunction(1, 2.0, '3');
 }
@@ -3049,7 +3486,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 class A {
   main() {
     int v = myUndefinedFunction(1, 2.0, '3');
@@ -3070,7 +3509,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 class A<T> {
   Map<int, T> items;
   main() {
@@ -3092,7 +3533,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 class A {
   List<int> items;
   main() {
@@ -3106,7 +3549,9 @@
   }
 
   void test_undefinedFunction_create_importType() {
-    addSource('/lib.dart', r'''
+    addSource(
+        '/lib.dart',
+        r'''
 library lib;
 import 'dart:async';
 Future getFuture() => null;
@@ -3117,7 +3562,9 @@
   test(getFuture());
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 import 'lib.dart';
 import 'dart:async';
 main() {
@@ -3135,7 +3582,9 @@
   test(null);
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   test(null);
 }
@@ -3167,7 +3616,9 @@
   v = myUndefinedFunction();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   int v;
   v = myUndefinedFunction();
@@ -3185,7 +3636,9 @@
   v += myUndefinedFunction();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   int v;
   v += myUndefinedFunction();
@@ -3202,7 +3655,9 @@
   0 + myUndefinedFunction();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   0 + myUndefinedFunction();
 }
@@ -3218,7 +3673,9 @@
   int v = myUndefinedFunction();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   int v = myUndefinedFunction();
 }
@@ -3235,7 +3692,9 @@
   foo( myUndefinedFunction() );
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 foo(int p) {}
 main() {
   foo( myUndefinedFunction() );
@@ -3252,7 +3711,9 @@
   return myUndefinedFunction();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 int main() {
   return myUndefinedFunction();
 }
@@ -3268,7 +3729,9 @@
   myUndefinedFunction();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_FUNCTION, '''
+    assertHasFix(
+        DartFixKind.CREATE_FUNCTION,
+        '''
 main() {
   myUndefinedFunction();
 }
@@ -3284,7 +3747,9 @@
   pritn(0);
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 main() {
   print(0);
 }
@@ -3298,7 +3763,9 @@
   myFuntcion();
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 myFunction() {}
 main() {
   myFunction();
@@ -3316,7 +3783,9 @@
   print(x.myFild);
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   int myField;
 }
@@ -3336,7 +3805,9 @@
   print(a.myFild);
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   int myField;
 }
@@ -3355,7 +3826,9 @@
   A.MY_NAM;
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   static int MY_NAME = 1;
 }
@@ -3374,7 +3847,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   int myField;
   main() {
@@ -3406,7 +3881,9 @@
 class B {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A<T> {
   B b;
   Map<int, T> items;
@@ -3433,7 +3910,9 @@
 class B {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A<T> {
   main() {
     T t = new B().compute();
@@ -3460,7 +3939,9 @@
 class B {
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   B b;
   List<int> items;
@@ -3485,7 +3966,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A<T> {
   List<T> items;
   main() {
@@ -3506,7 +3989,9 @@
   A.myUndefinedMethod();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   static void myUndefinedMethod() {
   }
@@ -3526,7 +4011,9 @@
   A.myUndefinedMethod();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   foo() {}
 
@@ -3547,7 +4034,9 @@
   a.myUndefinedMethod();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   void myUndefinedMethod() {
   }
@@ -3585,7 +4074,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   main() {
     myUndefinedMethod(0, 1.0, '3');
@@ -3599,24 +4090,23 @@
     int index = 0;
     _assertLinkedGroup(
         change.linkedEditGroups[index++], ['void myUndefinedMethod(']);
-    _assertLinkedGroup(change.linkedEditGroups[index++], [
-      'myUndefinedMethod(0',
-      'myUndefinedMethod(int'
-    ]);
-    _assertLinkedGroup(change.linkedEditGroups[index++], [
-      'int i'
-    ], expectedSuggestions(
-        LinkedEditSuggestionKind.TYPE, ['int', 'num', 'Object', 'Comparable']));
+    _assertLinkedGroup(change.linkedEditGroups[index++],
+        ['myUndefinedMethod(0', 'myUndefinedMethod(int']);
+    _assertLinkedGroup(
+        change.linkedEditGroups[index++],
+        ['int i'],
+        expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+            ['int', 'num', 'Object', 'Comparable']));
     _assertLinkedGroup(change.linkedEditGroups[index++], ['i,']);
-    _assertLinkedGroup(change.linkedEditGroups[index++], ['double d'],
-        expectedSuggestions(LinkedEditSuggestionKind.TYPE, [
-      'double',
-      'num',
-      'Object',
-      'Comparable'
-    ]));
+    _assertLinkedGroup(
+        change.linkedEditGroups[index++],
+        ['double d'],
+        expectedSuggestions(LinkedEditSuggestionKind.TYPE,
+            ['double', 'num', 'Object', 'Comparable']));
     _assertLinkedGroup(change.linkedEditGroups[index++], ['d,']);
-    _assertLinkedGroup(change.linkedEditGroups[index++], ['String s'],
+    _assertLinkedGroup(
+        change.linkedEditGroups[index++],
+        ['String s'],
         expectedSuggestions(
             LinkedEditSuggestionKind.TYPE, ['String', 'Object', 'Comparable']));
     _assertLinkedGroup(change.linkedEditGroups[index++], ['s)']);
@@ -3630,7 +4120,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   main() {
     int v = myUndefinedMethod();
@@ -3642,10 +4134,8 @@
 ''');
     // linked positions
     _assertLinkedGroup(change.linkedEditGroups[0], ['int myUndefinedMethod(']);
-    _assertLinkedGroup(change.linkedEditGroups[1], [
-      'myUndefinedMethod();',
-      'myUndefinedMethod() {'
-    ]);
+    _assertLinkedGroup(change.linkedEditGroups[1],
+        ['myUndefinedMethod();', 'myUndefinedMethod() {']);
   }
 
   void test_undefinedMethod_createUnqualified_staticFromField() {
@@ -3654,7 +4144,9 @@
   static var f = myUndefinedMethod();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   static var f = myUndefinedMethod();
 
@@ -3672,7 +4164,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   static main() {
     myUndefinedMethod();
@@ -3693,7 +4187,9 @@
   a.myUndefinedMethod();
 }
 ''');
-    assertHasFix(DartFixKind.CREATE_METHOD, '''
+    assertHasFix(
+        DartFixKind.CREATE_METHOD,
+        '''
 class A {
   void myUndefinedMethod() {
   }
@@ -3724,7 +4220,9 @@
   a.myMehtod();
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   myMethod() {}
 }
@@ -3746,7 +4244,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   myMethod() {}
 }
@@ -3767,7 +4267,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   myMethod() {}
   main() {
@@ -3787,7 +4289,9 @@
   x.myFild = 42;
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   int myField;
 }
@@ -3807,7 +4311,9 @@
   a.myFild = 42;
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   int myField;
 }
@@ -3826,7 +4332,9 @@
   }
 }
 ''');
-    assertHasFix(DartFixKind.CHANGE_TO, '''
+    assertHasFix(
+        DartFixKind.CHANGE_TO,
+        '''
 class A {
   int myField;
   main() {
@@ -3844,7 +4352,9 @@
   print((a / b).toInt());
 }
 ''');
-    assertHasFix(DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION, '''
+    assertHasFix(
+        DartFixKind.USE_EFFECTIVE_INTEGER_DIVISION,
+        '''
 main() {
   var a = 5;
   var b = 2;
@@ -3879,7 +4389,7 @@
    * Computes fixes for the given [error] in [testUnit].
    */
   List<Fix> _computeFixes(AnalysisError error) {
-    FixProcessor processor = new FixProcessor(testUnit, error);
+    FixProcessor processor = new FixProcessor(provider, testUnit, error);
     return processor.compute();
   }
 
@@ -3891,8 +4401,9 @@
     provider.newFile('/packages/my_pkg/lib/my_lib.dart', myLibCode);
     // configure SourceFactory
     Folder myPkgFolder = provider.getResource('/packages/my_pkg/lib');
-    UriResolver pkgResolver =
-        new PackageMapUriResolver(provider, {'my_pkg': [myPkgFolder]});
+    UriResolver pkgResolver = new PackageMapUriResolver(provider, {
+      'my_pkg': [myPkgFolder]
+    });
     context.sourceFactory = new SourceFactory(
         [AbstractContextTest.SDK_RESOLVER, resourceResolver, pkgResolver]);
     // force 'my_pkg' resolution
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
new file mode 100644
index 0000000..d9423a4
--- /dev/null
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -0,0 +1,253 @@
+// 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.refactoring.organize_directives;
+
+import 'package:analysis_server/src/protocol.dart' hide AnalysisError;
+import 'package:analysis_server/src/services/correction/organize_directives.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../abstract_single_unit.dart';
+
+main() {
+  groupSep = ' | ';
+  defineReflectiveTests(OrganizeDirectivesTest);
+}
+
+@reflectiveTest
+class OrganizeDirectivesTest extends AbstractSingleUnitTest {
+  List<AnalysisError> testErrors;
+
+  void test_remove_unresolvedDirectives() {
+    addSource('/existing_part1.dart', 'part of lib;');
+    addSource('/existing_part2.dart', 'part of lib;');
+    _computeUnitAndErrors(r'''
+library lib;
+
+import 'dart:async';
+import 'dart:noSuchImportSdkLibrary';
+import 'dart:math';
+import 'package:noSuchImportPackage/andLib.dart';
+
+export 'dart:noSuchExportSdkLibrary';
+export 'dart:async';
+export 'package:noSuchExportPackage/andLib.dart';
+export 'dart:math';
+
+part 'existing_part1.dart';
+part 'no_such_part.dart';
+part 'existing_part2.dart';
+
+main() {
+}
+''');
+    // validate change
+    _assertOrganize(
+        r'''
+library lib;
+
+import 'dart:async';
+import 'dart:math';
+
+export 'dart:async';
+export 'dart:math';
+
+part 'existing_part1.dart';
+part 'existing_part2.dart';
+
+main() {
+}
+''',
+        removeUnresolved: true);
+  }
+
+  void test_remove_unusedImports() {
+    _computeUnitAndErrors(r'''
+library lib;
+
+import 'dart:async';
+import 'dart:math';
+import 'dart:convert';
+import 'dart:collection';
+
+main() {
+  print(PI);
+  new HashMap();
+}
+''');
+    // validate change
+    _assertOrganize(
+        r'''
+library lib;
+
+import 'dart:collection';
+import 'dart:math';
+
+main() {
+  print(PI);
+  new HashMap();
+}
+''',
+        removeUnused: true);
+  }
+
+  void test_remove_unusedImports2() {
+    _computeUnitAndErrors(r'''
+import 'dart:async';
+import 'dart:math';
+
+class A {}
+
+main() {
+  Future f;
+}''');
+    // validate change
+    _assertOrganize(
+        r'''
+import 'dart:async';
+
+class A {}
+
+main() {
+  Future f;
+}''',
+        removeUnresolved: true,
+        removeUnused: true);
+  }
+
+  void test_sort() {
+    _computeUnitAndErrors(r'''
+library lib;
+
+export 'dart:bbb';
+import 'dart:bbb';
+export 'package:bbb/bbb.dart';
+export 'http://bbb.com';
+import 'bbb/bbb.dart';
+export 'http://aaa.com';
+import 'http://bbb.com';
+export 'dart:aaa';
+export 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart';
+export 'aaa/aaa.dart';
+export 'bbb/bbb.dart';
+import 'dart:aaa';
+import 'package:aaa/aaa.dart';
+import 'aaa/aaa.dart';
+import 'http://aaa.com';
+part 'bbb/bbb.dart';
+part 'aaa/aaa.dart';
+
+main() {
+}
+''');
+    // validate change
+    _assertOrganize(r'''
+library lib;
+
+import 'dart:aaa';
+import 'dart:bbb';
+
+import 'package:aaa/aaa.dart';
+import 'package:bbb/bbb.dart';
+
+import 'http://aaa.com';
+import 'http://bbb.com';
+
+import 'aaa/aaa.dart';
+import 'bbb/bbb.dart';
+
+export 'dart:aaa';
+export 'dart:bbb';
+
+export 'package:aaa/aaa.dart';
+export 'package:bbb/bbb.dart';
+
+export 'http://aaa.com';
+export 'http://bbb.com';
+
+export 'aaa/aaa.dart';
+export 'bbb/bbb.dart';
+
+part 'aaa/aaa.dart';
+part 'bbb/bbb.dart';
+
+main() {
+}
+''');
+  }
+
+  void test_sort_hasComments() {
+    _computeUnitAndErrors(r'''
+// header
+library lib;
+
+import 'c.dart';// c
+import 'a.dart';// aa
+import 'b.dart';// bbb
+
+/** doc */
+main() {
+}
+''');
+    // validate change
+    _assertOrganize(r'''
+// header
+library lib;
+
+import 'a.dart';
+import 'b.dart';
+import 'c.dart';
+// c
+// aa
+// bbb
+
+/** doc */
+main() {
+}
+''');
+  }
+
+  void test_sort_imports_packageAndPath() {
+    _computeUnitAndErrors(r'''
+library lib;
+
+import 'package:product.ui.api.bbb/manager1.dart';
+import 'package:product.ui.api/entity2.dart';
+import 'package:product.ui/entity.dart';
+import 'package:product.ui.api.aaa/manager2.dart';
+import 'package:product.ui.api/entity1.dart';
+import 'package:product2.client/entity.dart';
+''');
+    // validate change
+    _assertOrganize(r'''
+library lib;
+
+import 'package:product.ui/entity.dart';
+import 'package:product.ui.api/entity1.dart';
+import 'package:product.ui.api/entity2.dart';
+import 'package:product.ui.api.aaa/manager2.dart';
+import 'package:product.ui.api.bbb/manager1.dart';
+import 'package:product2.client/entity.dart';
+''');
+  }
+
+  void _assertOrganize(String expectedCode,
+      {bool removeUnresolved: false, bool removeUnused: false}) {
+    DirectiveOrganizer organizer = new DirectiveOrganizer(
+        testCode, testUnit, testErrors,
+        removeUnresolved: removeUnresolved, removeUnused: removeUnused);
+    List<SourceEdit> edits = organizer.organize();
+    String result = SourceEdit.applySequence(testCode, edits);
+    expect(result, expectedCode);
+  }
+
+  void _computeUnitAndErrors(String code) {
+    addTestSource(code);
+    testUnit = context.resolveCompilationUnit2(testSource, testSource);
+    testErrors = context.computeErrors(testSource);
+  }
+}
diff --git a/pkg/analysis_server/test/services/correction/test_all.dart b/pkg/analysis_server/test/services/correction/test_all.dart
index 3f3b03e..418fa67 100644
--- a/pkg/analysis_server/test/services/correction/test_all.dart
+++ b/pkg/analysis_server/test/services/correction/test_all.dart
@@ -11,6 +11,7 @@
 import 'fix_test.dart' as fix_test;
 import 'levenshtein_test.dart' as levenshtein_test;
 import 'name_suggestion_test.dart' as name_suggestion_test;
+import 'organize_directives_test.dart' as organize_directives_test;
 import 'sort_members_test.dart' as sort_members_test;
 import 'source_range_test.dart' as source_range_test;
 import 'status_test.dart' as status_test;
@@ -25,6 +26,7 @@
     fix_test.main();
     levenshtein_test.main();
     name_suggestion_test.main();
+    organize_directives_test.main();
     sort_members_test.main();
     source_range_test.main();
     status_test.main();
diff --git a/pkg/analysis_server/test/source/optimizing_pub_package_map_provider_test.dart b/pkg/analysis_server/test/source/optimizing_pub_package_map_provider_test.dart
deleted file mode 100644
index 4f68485..0000000
--- a/pkg/analysis_server/test/source/optimizing_pub_package_map_provider_test.dart
+++ /dev/null
@@ -1,244 +0,0 @@
-// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library test.source.optimizing_pub_package_map_provider;
-
-import 'dart:convert';
-import 'dart:io' as io;
-
-import 'package:analysis_server/src/source/optimizing_pub_package_map_provider.dart';
-import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:path/path.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-main() {
-  groupSep = ' | ';
-  defineReflectiveTests(OptimizingPubPackageMapProviderTest);
-  defineReflectiveTests(OptimizingPubPackageMapInfoTest);
-}
-
-@reflectiveTest
-class OptimizingPubPackageMapInfoTest {
-  MemoryResourceProvider resourceProvider;
-
-  int createFile(String path) {
-    return resourceProvider.newFile(path, 'contents').modificationStamp;
-  }
-
-  void createFolder(String path) {
-    resourceProvider.newFolder(path);
-  }
-
-  void modifyFile(String path) {
-    resourceProvider.modifyFile(path, 'contents');
-  }
-
-  void setUp() {
-    resourceProvider = new MemoryResourceProvider();
-  }
-
-  test_isChangedDependency_fileNotPresent() {
-    String path = '/dep';
-    int timestamp = 1;
-    OptimizingPubPackageMapInfo info =
-        new OptimizingPubPackageMapInfo({}, [path].toSet(), {path: timestamp});
-    expect(info.isChangedDependency(path, resourceProvider), isTrue);
-  }
-
-  test_isChangedDependency_matchingTimestamp() {
-    String path = '/dep';
-    int timestamp = createFile(path);
-    OptimizingPubPackageMapInfo info =
-        new OptimizingPubPackageMapInfo({}, [path].toSet(), {path: timestamp});
-    expect(info.isChangedDependency(path, resourceProvider), isFalse);
-  }
-
-  test_isChangedDependency_mismatchedTimestamp() {
-    String path = '/dep';
-    int timestamp = createFile(path);
-    OptimizingPubPackageMapInfo info =
-        new OptimizingPubPackageMapInfo({}, [path].toSet(), {path: timestamp});
-    modifyFile(path);
-    expect(info.isChangedDependency(path, resourceProvider), isTrue);
-  }
-
-  test_isChangedDependency_nonDependency() {
-    OptimizingPubPackageMapInfo info =
-        new OptimizingPubPackageMapInfo({}, ['/dep1'].toSet(), {});
-    expect(info.isChangedDependency('/dep2', resourceProvider), isFalse);
-  }
-
-  test_isChangedDependency_nonFile() {
-    String path = '/dep';
-    int timestamp = 1;
-    createFolder(path);
-    OptimizingPubPackageMapInfo info =
-        new OptimizingPubPackageMapInfo({}, [path].toSet(), {path: timestamp});
-    expect(info.isChangedDependency(path, resourceProvider), isTrue);
-  }
-
-  test_isChangedDependency_noTimestampInfo() {
-    String path = '/dep';
-    OptimizingPubPackageMapInfo info =
-        new OptimizingPubPackageMapInfo({}, [path].toSet(), {});
-    expect(info.isChangedDependency(path, resourceProvider), isTrue);
-  }
-}
-
-@reflectiveTest
-class OptimizingPubPackageMapProviderTest {
-  MemoryResourceProvider resourceProvider;
-  OptimizingPubPackageMapProvider provider;
-  Folder projectFolder;
-  io.ProcessResult pubListResult;
-
-  void setPubListError() {
-    pubListResult = new _MockProcessResult(0, 1, '', 'ERROR');
-  }
-
-  void setPubListResult({Map<String, String> packages: const {},
-      List<String> input_files: const []}) {
-    pubListResult = new _MockProcessResult(0, 0,
-        JSON.encode({'packages': packages, 'input_files': input_files}), '');
-  }
-
-  void setUp() {
-    resourceProvider = new MemoryResourceProvider();
-    provider = new OptimizingPubPackageMapProvider(
-        resourceProvider, null, _runPubList);
-    projectFolder = resourceProvider.newFolder('/my/proj');
-  }
-
-  test_computePackageMap_noPreviousInfo() {
-    String dep = posix.join(projectFolder.path, 'dep');
-    String pkgName = 'foo';
-    String pkgPath = '/pkg/foo';
-    setPubListResult(packages: {pkgName: pkgPath}, input_files: [dep]);
-    OptimizingPubPackageMapInfo info =
-        provider.computePackageMap(projectFolder);
-    expect(info.dependencies, hasLength(1));
-    expect(info.dependencies, contains(dep));
-    expect(info.packageMap, hasLength(1));
-    expect(info.packageMap, contains(pkgName));
-    expect(info.packageMap[pkgName], hasLength(1));
-    expect(info.packageMap[pkgName][0].path, pkgPath);
-    expect(info.modificationTimes, isEmpty);
-  }
-
-  test_computePackageMap_noPreviousInfo_pubListError() {
-    String pubspecLock = posix.join(projectFolder.path, 'pubspec.lock');
-    setPubListError();
-    OptimizingPubPackageMapInfo info =
-        provider.computePackageMap(projectFolder);
-    expect(info.dependencies, hasLength(1));
-    expect(info.dependencies, contains(pubspecLock));
-    expect(info.packageMap, isNull);
-    expect(info.modificationTimes, isEmpty);
-  }
-
-  test_computePackageMap_withPreviousInfo() {
-    String dep = posix.join(projectFolder.path, 'dep');
-    int timestamp = resourceProvider.newFile(dep, 'contents').modificationStamp;
-    setPubListResult(input_files: [dep]);
-    OptimizingPubPackageMapInfo info1 =
-        provider.computePackageMap(projectFolder);
-    OptimizingPubPackageMapInfo info2 =
-        provider.computePackageMap(projectFolder, info1);
-    expect(info2.dependencies, hasLength(1));
-    expect(info2.dependencies, contains(dep));
-    expect(info2.modificationTimes, hasLength(1));
-    expect(info2.modificationTimes, contains(dep));
-    expect(info2.modificationTimes[dep], timestamp);
-  }
-
-  test_computePackageMap_withPreviousInfo_newDependency() {
-    String dep = posix.join(projectFolder.path, 'dep');
-    resourceProvider.newFile(dep, 'contents').modificationStamp;
-    setPubListResult(input_files: []);
-    OptimizingPubPackageMapInfo info1 =
-        provider.computePackageMap(projectFolder);
-    setPubListResult(input_files: [dep]);
-    OptimizingPubPackageMapInfo info2 =
-        provider.computePackageMap(projectFolder, info1);
-    expect(info2.modificationTimes, isEmpty);
-  }
-
-  test_computePackageMap_withPreviousInfo_oldDependencyNoLongerAFile() {
-    String dep = posix.join(projectFolder.path, 'dep');
-    resourceProvider.newFile(dep, 'contents').modificationStamp;
-    setPubListResult(input_files: [dep]);
-    OptimizingPubPackageMapInfo info1 =
-        provider.computePackageMap(projectFolder);
-    resourceProvider.deleteFile(dep);
-    resourceProvider.newFolder(dep);
-    OptimizingPubPackageMapInfo info2 =
-        provider.computePackageMap(projectFolder, info1);
-    expect(info2.modificationTimes, isEmpty);
-  }
-
-  test_computePackageMap_withPreviousInfo_oldDependencyNoLongerPresent() {
-    String dep = posix.join(projectFolder.path, 'dep');
-    resourceProvider.newFile(dep, 'contents').modificationStamp;
-    setPubListResult(input_files: [dep]);
-    OptimizingPubPackageMapInfo info1 =
-        provider.computePackageMap(projectFolder);
-    resourceProvider.deleteFile(dep);
-    OptimizingPubPackageMapInfo info2 =
-        provider.computePackageMap(projectFolder, info1);
-    expect(info2.modificationTimes, isEmpty);
-  }
-
-  test_computePackageMap_withPreviousInfo_oldDependencyNoLongerRelevant() {
-    String dep = posix.join(projectFolder.path, 'dep');
-    resourceProvider.newFile(dep, 'contents').modificationStamp;
-    setPubListResult(input_files: [dep]);
-    OptimizingPubPackageMapInfo info1 =
-        provider.computePackageMap(projectFolder);
-    setPubListResult(input_files: []);
-    OptimizingPubPackageMapInfo info2 =
-        provider.computePackageMap(projectFolder, info1);
-    expect(info2.modificationTimes, isEmpty);
-  }
-
-  test_computePackageMap_withPreviousInfo_pubListError() {
-    String dep = posix.join(projectFolder.path, 'dep');
-    String pubspecLock = posix.join(projectFolder.path, 'pubspec.lock');
-    int timestamp = resourceProvider.newFile(dep, 'contents').modificationStamp;
-    setPubListResult(input_files: [dep]);
-    OptimizingPubPackageMapInfo info1 =
-        provider.computePackageMap(projectFolder);
-    setPubListError();
-    OptimizingPubPackageMapInfo info2 =
-        provider.computePackageMap(projectFolder, info1);
-    expect(info2.dependencies, hasLength(2));
-    expect(info2.dependencies, contains(dep));
-    expect(info2.dependencies, contains(pubspecLock));
-    expect(info2.modificationTimes, hasLength(1));
-    expect(info2.modificationTimes, contains(dep));
-    expect(info2.modificationTimes[dep], timestamp);
-  }
-
-  io.ProcessResult _runPubList(Folder folder) {
-    expect(folder, projectFolder);
-    return pubListResult;
-  }
-}
-
-class _MockProcessResult implements io.ProcessResult {
-  @override
-  final int pid;
-
-  @override
-  final int exitCode;
-
-  @override
-  final stdout;
-
-  @override
-  final stderr;
-
-  _MockProcessResult(this.pid, this.exitCode, this.stdout, this.stderr);
-}
diff --git a/pkg/analysis_server/test/source/test_all.dart b/pkg/analysis_server/test/source/test_all.dart
index 34a617f..3a3e709 100644
--- a/pkg/analysis_server/test/source/test_all.dart
+++ b/pkg/analysis_server/test/source/test_all.dart
@@ -5,13 +5,10 @@
 library test.source;
 
 import 'caching_put_package_map_provider_test.dart' as caching_provider_test;
-import 'optimizing_pub_package_map_provider_test.dart'
-    as optimizing_provider_test;
 import 'package:unittest/unittest.dart';
 
 /// Utility for manually running all tests.
 main() {
   groupSep = ' | ';
   caching_provider_test.main();
-  optimizing_provider_test.main();
 }
diff --git a/pkg/analysis_server/test/src/watch_manager_test.dart b/pkg/analysis_server/test/src/watch_manager_test.dart
index 8d1c4e2..a8d885d 100644
--- a/pkg/analysis_server/test/src/watch_manager_test.dart
+++ b/pkg/analysis_server/test/src/watch_manager_test.dart
@@ -96,7 +96,7 @@
     await _expectEvent(ChangeType.ADD, newFile1.path, [topToken]);
 
     File newFile2 = provider.newFile('/a/b/c/d/lib.dart', '');
-    _expectEvent(ChangeType.ADD, newFile2.path, [topToken, childToken]);
+    return _expectEvent(ChangeType.ADD, newFile2.path, [topToken, childToken]);
   }
 
   Future test_addFolder_singleFolder_multipleTokens() {
@@ -119,7 +119,7 @@
     await _expectEvent(ChangeType.ADD, newFolder.path, [token]);
 
     File newFile = provider.newFile('/a/b/c/lib.dart', '');
-    _expectEvent(ChangeType.ADD, newFile.path, [token]);
+    return _expectEvent(ChangeType.ADD, newFile.path, [token]);
   }
 
   Future test_addFolder_unrelatedFolders() async {
@@ -134,7 +134,7 @@
     await _expectEvent(ChangeType.ADD, newFile1.path, [token1]);
 
     File newFile2 = provider.newFile('/c/d/lib.dart', '');
-    _expectEvent(ChangeType.ADD, newFile2.path, [token2]);
+    return _expectEvent(ChangeType.ADD, newFile2.path, [token2]);
   }
 
   void test_creation() {
@@ -153,15 +153,6 @@
     return _expectEvent(ChangeType.ADD, newFile.path, [token1]);
   }
 
-  Future test_removeFolder_unadded() {
-    Folder folder = provider.getFolder('/a/b');
-    Token token = new Token('token');
-    expect(() => manager.removeFolder(folder, token), throws);
-
-    provider.newFile('/a/b/lib.dart', '');
-    return _expectNoEvent();
-  }
-
   Future test_removeFolder_withChildren() async {
     Folder topFolder = provider.getFolder('/a/b');
     Folder childFolder = provider.getFolder('/a/b/c/d');
@@ -175,7 +166,7 @@
     await _expectEvent(ChangeType.ADD, newFile.path, [childToken]);
 
     provider.newFile('/a/b/lib.dart', '');
-    _expectNoEvent();
+    return _expectNoEvent();
   }
 
   Future test_removeFolder_withNoChildren() {
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index 9307059..77faa63 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -18,6 +18,7 @@
 import 'protocol_test.dart' as protocol_test;
 import 'search/test_all.dart' as search_all;
 import 'services/test_all.dart' as services_all;
+import 'server_options_test.dart' as server_options;
 import 'socket_server_test.dart' as socket_server_test;
 import 'source/test_all.dart' as source_all;
 import 'src/test_all.dart' as src_all;
@@ -41,6 +42,7 @@
     protocol_server_test.main();
     protocol_test.main();
     search_all.main();
+    server_options.main();
     services_all.main();
     socket_server_test.main();
     source_all.main();
diff --git a/pkg/analysis_server/tool/spec/codegen_tools.dart b/pkg/analysis_server/tool/spec/codegen_tools.dart
index f388379..078f809 100644
--- a/pkg/analysis_server/tool/spec/codegen_tools.dart
+++ b/pkg/analysis_server/tool/spec/codegen_tools.dart
@@ -102,9 +102,12 @@
   }
 
   /**
-   * Execute [callback], indenting any code it outputs by two spaces.
+   * Execute [callback], indenting any code it outputs.
    */
-  void indent(void callback()) => indentSpecial('  ', '  ', callback);
+  void indent(void callback()) {
+    indentSpecial(codeGeneratorSettings.indent, codeGeneratorSettings.indent,
+      callback);
+  }
 
   /**
    * Execute [callback], using [additionalIndent] to indent any code it outputs.
@@ -237,10 +240,15 @@
    */
   int commentLineLength;
 
+  /**
+   * String used for indenting code.
+   */
+  String indent;
+
   CodeGeneratorSettings({this.languageName: 'java',
       this.lineCommentLineLeader: '// ', this.docCommentStartMarker: '/**',
       this.docCommentLineLeader: ' * ', this.docCommentEndMarker: ' */',
-      this.commentLineLength: 99});
+      this.commentLineLength: 99, this.indent: '  '});
 }
 
 abstract class GeneratedContent {
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index c398e4d..c183dac 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -351,6 +351,23 @@
   public void edit_getRefactoring(String kind, String file, int offset, int length, boolean validateOnly, RefactoringOptions options, GetRefactoringConsumer consumer);
 
   /**
+   * {@code edit.organizeDirectives}
+   *
+   * Organizes all of the directives - removes unused imports and sorts directives of the given Dart
+   * file according to the Dart Style Guide.
+   *
+   * If a request is made for a file that does not exist, does not belong to an analysis root or is
+   * not a Dart file, FILE_NOT_ANALYZED will be generated.
+   *
+   * If directives of the Dart file cannot be organized, for example because it has scan or parse
+   * errors, or by other reasons, ORGANIZE_DIRECTIVES_ERROR will be generated. The message will
+   * provide datails about the reason.
+   *
+   * @param file The Dart file to organize directives in.
+   */
+  public void edit_organizeDirectives(String file, OrganizeDirectivesConsumer consumer);
+
+  /**
    * {@code edit.sortMembers}
    *
    * Sort all of the directives, unit and class members of the given Dart file.
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
index e46c4813..fa91052 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/AnalysisOptions.java
@@ -45,27 +45,29 @@
   public static final List<AnalysisOptions> EMPTY_LIST = Lists.newArrayList();
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed async feature.
    */
   private final Boolean enableAsync;
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed deferred loading feature.
    */
   private final Boolean enableDeferredLoading;
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed enum feature.
    */
   private final Boolean enableEnums;
 
   /**
+   * Deprecated: this feature is always enabled.
+   *
    * True if the client wants to enable support for the proposed "null aware operators" feature.
    */
   private final Boolean enableNullAwareOperators;
@@ -139,7 +141,7 @@
   }
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed async feature.
    */
@@ -148,7 +150,7 @@
   }
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed deferred loading feature.
    */
@@ -157,7 +159,7 @@
   }
 
   /**
-   * Deprecated
+   * Deprecated: this feature is always enabled.
    *
    * True if the client wants to enable support for the proposed enum feature.
    */
@@ -166,6 +168,8 @@
   }
 
   /**
+   * Deprecated: this feature is always enabled.
+   *
    * True if the client wants to enable support for the proposed "null aware operators" feature.
    */
   public Boolean getEnableNullAwareOperators() {
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
index 8e39aff..a8615d2 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RequestErrorCode.java
@@ -30,6 +30,12 @@
   public static final String CONTENT_MODIFIED = "CONTENT_MODIFIED";
 
   /**
+   * A request specified a FilePath which does not match a file in an analysis root, or the requested
+   * operation is not available for the file.
+   */
+  public static final String FILE_NOT_ANALYZED = "FILE_NOT_ANALYZED";
+
+  /**
    * An "edit.format" request specified a FilePath which does not match a Dart file in an analysis
    * root.
    */
@@ -47,7 +53,7 @@
   public static final String GET_ERRORS_INVALID_FILE = "GET_ERRORS_INVALID_FILE";
 
   /**
-   * An "analysis.getErrors" request specified a FilePath which does not match a file currently
+   * An "analysis.getNavigation" request specified a FilePath which does not match a file currently
    * subject to analysis.
    */
   public static final String GET_NAVIGATION_INVALID_FILE = "GET_NAVIGATION_INVALID_FILE";
@@ -86,6 +92,12 @@
   public static final String NO_INDEX_GENERATED = "NO_INDEX_GENERATED";
 
   /**
+   * An "edit.organizeDirectives" request specified a Dart file that cannot be analyzed. The reason
+   * is described in the message.
+   */
+  public static final String ORGANIZE_DIRECTIVES_ERROR = "ORGANIZE_DIRECTIVES_ERROR";
+
+  /**
    * Another refactoring request was received during processing of this one.
    */
   public static final String REFACTORING_REQUEST_CANCELLED = "REFACTORING_REQUEST_CANCELLED";
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 1d61cb1..6bd7e09 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -1697,6 +1697,41 @@
           </field>
         </result>
       </request>
+      <request method="organizeDirectives">
+        <p>
+          Organizes all of the directives - removes unused imports and sorts
+          directives of the given Dart file according to the
+          <a href="https://www.dartlang.org/articles/style-guide/">Dart Style Guide</a>.
+        </p>
+        <p>
+          If a request is made for a file that does not exist, does not belong
+          to an analysis root or is not a Dart file,
+          <tt>FILE_NOT_ANALYZED</tt> will be generated.
+        </p>
+        <p>
+          If directives of the Dart file cannot be organized, for example
+          because it has scan or parse errors, or by other reasons,
+          <tt>ORGANIZE_DIRECTIVES_ERROR</tt> will be generated. The message
+          will provide datails about the reason.
+        </p>
+        <params>
+          <field name="file">
+            <ref>FilePath</ref>
+            <p>
+              The Dart file to organize directives in.
+            </p>
+          </field>
+        </params>
+        <result>
+          <field name="edit">
+            <ref>SourceFileEdit</ref>
+            <p>
+              The file edit that is to be applied to the given file to effect
+              the organizing.
+            </p>
+          </field>
+        </result>
+      </request>
     </domain>
     <domain name="execution">
       <p>
@@ -1988,7 +2023,7 @@
         <object>
           <field name="enableAsync" optional="true">
             <ref>bool</ref>
-            <p><b><i>Deprecated</i></b></p>
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed async feature.
@@ -1996,7 +2031,7 @@
           </field>
           <field name="enableDeferredLoading" optional="true">
             <ref>bool</ref>
-            <p><b><i>Deprecated</i></b></p>
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed deferred loading feature.
@@ -2004,7 +2039,7 @@
           </field>
           <field name="enableEnums" optional="true">
             <ref>bool</ref>
-            <p><b><i>Deprecated</i></b></p>
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed enum feature.
@@ -2012,6 +2047,7 @@
           </field>
           <field name="enableNullAwareOperators" optional="true">
             <ref>bool</ref>
+            <p><b><i>Deprecated</i></b>: this feature is always enabled.</p>
             <p>
               True if the client wants to enable support for the
               proposed "null aware operators" feature.
@@ -3383,6 +3419,14 @@
             </p>
           </value>
           <value>
+            <code>FILE_NOT_ANALYZED</code>
+            <p>
+              A request specified a FilePath which does not match a file in
+              an analysis root, or the requested operation is not available
+              for the file.
+            </p>
+          </value>
+          <value>
             <code>FORMAT_INVALID_FILE</code>
             <p>
               An "edit.format" request specified a FilePath
@@ -3407,7 +3451,7 @@
           <value>
             <code>GET_NAVIGATION_INVALID_FILE</code>
             <p>
-              An "analysis.getErrors" request specified a FilePath
+              An "analysis.getNavigation" request specified a FilePath
               which does not match a file currently subject to
               analysis.
             </p>
@@ -3455,6 +3499,13 @@
             </p>
           </value>
           <value>
+            <code>ORGANIZE_DIRECTIVES_ERROR</code>
+            <p>
+              An "edit.organizeDirectives" request specified a Dart file that
+              cannot be analyzed. The reason is described in the message.
+            </p>
+          </value>
+          <value>
             <code>REFACTORING_REQUEST_CANCELLED</code>
             <p>
               Another refactoring request was received during processing of
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 59a9606..7c67e09 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,23 @@
+## 0.26.0
+
+* No changes from 0.26.0-alpha.2.
+
+## 0.26.0-alpha.2
+
+* Fix highlight range for missing enum constant in switch (issue 23904).
+* Fix analyzer's treatment of `ClassName?.staticMember` to match spec.
+* Implement DEP 34 (less restricted mixins).
+* Fix some implementations of `UriResolver.resolveUri(..)` that did not
+  properly handle the new `actualUri` argument.
+
+## 0.26.0-alpha.1
+
+* Change `ResolutionCopier.visitAwaitExpression` to copy *Type fields.
+
+## 0.26.0-alpha.0
+
+* API change: `UriResolver.resolveUri(..)` now takes an optional `actualUri`.
+
 ## 0.25.3-alpha.0
 
 * Add hook for listening to implicitly analyzed files
@@ -7,6 +27,7 @@
 
 ## 0.25.2
 
+* Requires Dart SDK 1.12-dev or greater
 * Enable null-aware operators (DEP 9) by default.
 * Generic method support in the element model.
 
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 899d6c5..788600b 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -181,14 +181,14 @@
   ResourceUriResolver(this._provider);
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     if (!_isFileUri(uri)) {
       return null;
     }
     Resource resource =
         _provider.getResource(_provider.pathContext.fromUri(uri));
     if (resource is File) {
-      return resource.createSource(uri);
+      return resource.createSource(actualUri != null ? actualUri : uri);
     }
     return null;
   }
diff --git a/pkg/analyzer/lib/source/package_map_resolver.dart b/pkg/analyzer/lib/source/package_map_resolver.dart
index 82000b9..0fa12ae 100644
--- a/pkg/analyzer/lib/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/source/package_map_resolver.dart
@@ -44,7 +44,7 @@
   }
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     if (!isPackageUri(uri)) {
       return null;
     }
diff --git a/pkg/analyzer/lib/source/path_filter.dart b/pkg/analyzer/lib/source/path_filter.dart
index 9ee0070..f4123f8 100644
--- a/pkg/analyzer/lib/source/path_filter.dart
+++ b/pkg/analyzer/lib/source/path_filter.dart
@@ -5,16 +5,33 @@
 library source.path_filter;
 
 import 'package:glob/glob.dart' as glob;
-import 'package:path/path.dart' as pos;
+import 'package:path/path.dart';
 
 /// Filter paths against a set of [ignorePatterns] relative to a [root]
 /// directory. Paths outside of [root] are also ignored.
 class PathFilter {
+  /// The path context to use when manipulating paths.
+  final Context pathContext;
+
+  /// Path that all ignore patterns are relative to.
+  final String root;
+
+  /// List of ignore patterns that paths are tested against.
+  final List<glob.Glob> _ignorePatterns = new List<glob.Glob>();
+
   /// Construct a new path filter rooted at [root] with [ignorePatterns].
-  PathFilter(this.root, List<String> ignorePatterns) {
+  PathFilter(this.pathContext, this.root, List<String> ignorePatterns) {
     setIgnorePatterns(ignorePatterns);
   }
 
+  /// Returns true if [path] should be ignored. A path is ignored if it is not
+  /// contained in [root] or matches one of the ignore patterns.
+  /// [path] is absolute or relative to [root].
+  bool ignored(String path) {
+    path = _canonicalize(path);
+    return !_contained(path) || _match(path);
+  }
+
   /// Set the ignore patterns.
   void setIgnorePatterns(List<String> ignorePatterns) {
     _ignorePatterns.clear();
@@ -25,19 +42,9 @@
     }
   }
 
-  /// Returns true if [path] should be ignored. A path is ignored if it is not
-  /// contained in [root] or matches one of the ignore patterns.
-  /// [path] is absolute or relative to [root].
-  bool ignored(String path) {
-    path = _canonicalize(path);
-    return !_contained(path) || _match(path);
-  }
-
   /// Returns the absolute path of [path], relative to [root].
-  String _canonicalize(String path) => pos.normalize(pos.join(root, path));
-
-  /// Returns the relative portion of [path] from [root].
-  String _relative(String path) => pos.relative(path, from:root);
+  String _canonicalize(String path) =>
+      pathContext.normalize(pathContext.join(root, path));
 
   /// Returns true when [path] is contained inside [root].
   bool _contained(String path) => path.startsWith(root);
@@ -53,9 +60,15 @@
     return false;
   }
 
-  /// Path that all ignore patterns are relative to.
-  final String root;
+  /// Returns the relative portion of [path] from [root].
+  String _relative(String path) => pathContext.relative(path, from: root);
 
-  /// List of ignore patterns that paths are tested against.
-  final List<glob.Glob> _ignorePatterns = new List<glob.Glob>();
+  String toString() {
+    StringBuffer sb = new StringBuffer();
+    for (var pattern in _ignorePatterns) {
+      sb.write('$pattern ');
+    }
+    sb.writeln('');
+    return sb.toString();
+  }
 }
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index 696e181..7caad43 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -51,7 +51,7 @@
   }
 
   @override
-  Source resolveAbsolute(Uri importUri) {
+  Source resolveAbsolute(Uri importUri, [Uri actualUri]) {
     String libraryName = _libraryName(importUri);
     String partPath = _partPath(importUri);
     // Lookup library name in mappings.
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 1be6dfb..e48a5cc 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -247,7 +247,9 @@
         (this._options.hint && !options.hint) ||
         (this._options.lint && !options.lint) ||
         this._options.preserveComments != options.preserveComments ||
-        this._options.enableStrictCallChecks != options.enableStrictCallChecks;
+        this._options.enableStrictCallChecks !=
+            options.enableStrictCallChecks ||
+        this._options.enableSuperMixins != options.enableSuperMixins;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
       this._options.cacheSize = cacheSize;
@@ -258,6 +260,7 @@
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
+    this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
     this._options.incrementalApi = options.incrementalApi;
diff --git a/pkg/analyzer/lib/src/generated/ast.dart b/pkg/analyzer/lib/src/generated/ast.dart
index c386c83..f4a8ff3 100644
--- a/pkg/analyzer/lib/src/generated/ast.dart
+++ b/pkg/analyzer/lib/src/generated/ast.dart
@@ -1617,9 +1617,10 @@
 
   @override
   VariableDeclarationList visitVariableDeclarationList(
-      VariableDeclarationList node) => new VariableDeclarationList(null,
-      cloneNodeList(node.metadata), cloneToken(node.keyword),
-      cloneNode(node.type), cloneNodeList(node.variables));
+      VariableDeclarationList node) => new VariableDeclarationList(
+      cloneNode(node.documentationComment), cloneNodeList(node.metadata),
+      cloneToken(node.keyword), cloneNode(node.type),
+      cloneNodeList(node.variables));
 
   @override
   VariableDeclarationStatement visitVariableDeclarationStatement(
@@ -10841,15 +10842,13 @@
   /**
    * The value of the literal.
    */
-  String _value;
+  String value;
 
   /**
    * Initialize a newly created string of characters that are part of a string
    * interpolation.
    */
-  InterpolationString(this.contents, String value) {
-    _value = value;
-  }
+  InterpolationString(this.contents, this.value);
 
   @override
   Token get beginToken => contents;
@@ -10877,18 +10876,6 @@
   @override
   Token get endToken => contents;
 
-  /**
-   * Return the value of the literal.
-   */
-  String get value => _value;
-
-  /**
-   * Set the value of the literal to the given [string].
-   */
-  void set value(String string) {
-    _value = string;
-  }
-
   @override
   accept(AstVisitor visitor) => visitor.visitInterpolationString(this);
 
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index 572caab..742f64d 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -3526,9 +3526,7 @@
   }
 
   @deprecated // Use new EvaluationResultImpl(value, errors)
-  EvaluationResultImpl.con2(this.value, List<AnalysisError> errors) {
-    this._errors = errors;
-  }
+  EvaluationResultImpl.con2(this.value, List<AnalysisError> this._errors);
 
   List<AnalysisError> get errors => _errors;
 
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index 395dc27..69beffe 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -85,7 +85,8 @@
 
   @override
   bool isMoreSpecificThan(DartType type,
-      [bool withDynamic = false, Set<Element> visitedElements]) => true;
+          [bool withDynamic = false, Set<Element> visitedElements]) =>
+      true;
 
   @override
   bool isSubtypeOf(DartType type) => true;
@@ -98,8 +99,9 @@
 
   @override
   BottomTypeImpl substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) => this;
+          List<DartType> argumentTypes, List<DartType> parameterTypes,
+          [List<FunctionTypeAliasElement> prune]) =>
+      this;
 }
 
 /**
@@ -1154,8 +1156,8 @@
       if (definingClass is! ClassElementImpl) {
         return null;
       }
-      getter = (definingClass as ClassElementImpl)._internalLookUpGetter(
-          getterName, library, false);
+      getter = (definingClass as ClassElementImpl)
+          ._internalLookUpGetter(getterName, library, false);
     }
     return getter;
   }
@@ -1183,8 +1185,8 @@
       if (definingClass is! ClassElementImpl) {
         return null;
       }
-      setter = (definingClass as ClassElementImpl)._internalLookUpSetter(
-          setterName, library, false);
+      setter = (definingClass as ClassElementImpl)
+          ._internalLookUpSetter(setterName, library, false);
     }
     return setter;
   }
@@ -2538,6 +2540,8 @@
   int get nameOffset;
 
   /**
+   * **DEPRECATED** Use `computeNode()` instead.
+   *
    * Return the resolved [AstNode] node that declares this element, or `null` if
    * this element is synthetic or isn't contained in a compilation unit, such as
    * a [LibraryElement].
@@ -4087,7 +4091,8 @@
  * A concrete implementation of a [FieldElement].
  */
 class FieldElementImpl extends PropertyInducingElementImpl
-    with PotentiallyConstVariableElement implements FieldElement {
+    with PotentiallyConstVariableElement
+    implements FieldElement {
   /**
    * An empty list of field elements.
    */
@@ -4961,8 +4966,8 @@
         DartType type = parameter.type;
         if (typeArguments.length != 0 &&
             typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl).substitute2(
-              typeArguments, typeParameters, newPrune);
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
         } else {
           type = (type as TypeImpl).pruned(newPrune);
         }
@@ -5007,8 +5012,8 @@
         DartType type = parameter.type;
         if (typeArguments.length != 0 &&
             typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl).substitute2(
-              typeArguments, typeParameters, newPrune);
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
         } else {
           type = (type as TypeImpl).pruned(newPrune);
         }
@@ -5032,8 +5037,8 @@
         DartType type = parameter.type;
         if (typeArguments.length != 0 &&
             typeArguments.length == typeParameters.length) {
-          type = (type as TypeImpl).substitute2(
-              typeArguments, typeParameters, newPrune);
+          type = (type as TypeImpl)
+              .substitute2(typeArguments, typeParameters, newPrune);
         } else {
           type = (type as TypeImpl).pruned(newPrune);
         }
@@ -5215,8 +5220,8 @@
         return false;
       } else if (t.normalParameterTypes.length > 0) {
         for (int i = 0; i < tTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl).isMoreSpecificThan(
-              sTypes[i], withDynamic)) {
+          if (!(tTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sTypes[i], withDynamic)) {
             return false;
           }
         }
@@ -5236,8 +5241,8 @@
         if (typeT == null) {
           return false;
         }
-        if (!(typeT as TypeImpl).isMoreSpecificThan(
-            namedTypesS[keyS], withDynamic)) {
+        if (!(typeT as TypeImpl)
+            .isMoreSpecificThan(namedTypesS[keyS], withDynamic)) {
           return false;
         }
       }
@@ -5257,8 +5262,8 @@
       if (tOpTypes.length == 0 && sOpTypes.length == 0) {
         // No positional arguments, don't copy contents to new array
         for (int i = 0; i < sTypes.length; i++) {
-          if (!(tTypes[i] as TypeImpl).isMoreSpecificThan(
-              sTypes[i], withDynamic)) {
+          if (!(tTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sTypes[i], withDynamic)) {
             return false;
           }
         }
@@ -5280,8 +5285,8 @@
           sAllTypes[i] = sOpTypes[j];
         }
         for (int i = 0; i < sAllTypes.length; i++) {
-          if (!(tAllTypes[i] as TypeImpl).isMoreSpecificThan(
-              sAllTypes[i], withDynamic)) {
+          if (!(tAllTypes[i] as TypeImpl)
+              .isMoreSpecificThan(sAllTypes[i], withDynamic)) {
             return false;
           }
         }
@@ -6633,8 +6638,8 @@
           return false;
         }
         for (int i = 0; i < tArguments.length; i++) {
-          if (!(tArguments[i] as TypeImpl).isMoreSpecificThan(
-              sArguments[i], withDynamic)) {
+          if (!(tArguments[i] as TypeImpl)
+              .isMoreSpecificThan(sArguments[i], withDynamic)) {
             return false;
           }
         }
@@ -6664,14 +6669,14 @@
         return true;
       }
       for (InterfaceType interfaceType in interfaces) {
-        if ((interfaceType as InterfaceTypeImpl).isMoreSpecificThan(
-            type, withDynamic, visitedElements)) {
+        if ((interfaceType as InterfaceTypeImpl)
+            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
           return true;
         }
       }
       for (InterfaceType mixinType in mixins) {
-        if ((mixinType as InterfaceTypeImpl).isMoreSpecificThan(
-            type, withDynamic, visitedElements)) {
+        if ((mixinType as InterfaceTypeImpl)
+            .isMoreSpecificThan(type, withDynamic, visitedElements)) {
           return true;
         }
       }
@@ -7645,8 +7650,8 @@
     for (ImportElement importElement in _imports) {
       LibraryElement importedLibrary = importElement.importedLibrary;
       if (importedLibrary != null) {
-        (importedLibrary as LibraryElementImpl)._addVisibleLibraries(
-            visibleLibraries, true);
+        (importedLibrary as LibraryElementImpl)
+            ._addVisibleLibraries(visibleLibraries, true);
       }
     }
     // add exported libraries
@@ -7654,8 +7659,8 @@
       for (ExportElement exportElement in _exports) {
         LibraryElement exportedLibrary = exportElement.exportedLibrary;
         if (exportedLibrary != null) {
-          (exportedLibrary as LibraryElementImpl)._addVisibleLibraries(
-              visibleLibraries, true);
+          (exportedLibrary as LibraryElementImpl)
+              ._addVisibleLibraries(visibleLibraries, true);
         }
       }
     }
@@ -7749,7 +7754,8 @@
  * A concrete implementation of a [LocalVariableElement].
  */
 class LocalVariableElementImpl extends VariableElementImpl
-    with PotentiallyConstVariableElement implements LocalVariableElement {
+    with PotentiallyConstVariableElement
+    implements LocalVariableElement {
   /**
    * An empty list of field elements.
    */
@@ -8659,7 +8665,8 @@
  * A concrete implementation of a [ParameterElement].
  */
 class ParameterElementImpl extends VariableElementImpl
-    with PotentiallyConstVariableElement implements ParameterElement {
+    with PotentiallyConstVariableElement
+    implements ParameterElement {
   /**
    * An empty list of parameter elements.
    */
@@ -9848,7 +9855,8 @@
  * A concrete implementation of a [TopLevelVariableElement].
  */
 class TopLevelVariableElementImpl extends PropertyInducingElementImpl
-    with PotentiallyConstVariableElement implements TopLevelVariableElement {
+    with PotentiallyConstVariableElement
+    implements TopLevelVariableElement {
   /**
    * An empty list of top-level variable elements.
    */
@@ -10091,8 +10099,8 @@
     }
     List<DartType> newTypes = new List<DartType>(length);
     for (int i = 0; i < length; i++) {
-      newTypes[i] = (types[i] as TypeImpl).substitute2(
-          argumentTypes, parameterTypes, prune);
+      newTypes[i] = (types[i] as TypeImpl)
+          .substitute2(argumentTypes, parameterTypes, prune);
     }
     return newTypes;
   }
@@ -10101,7 +10109,7 @@
 /**
  * A type parameter.
  */
-abstract class TypeParameterElement implements Element {
+abstract class TypeParameterElement implements TypeDefiningElement {
   /**
    * An empty list of type parameter elements.
    */
@@ -10695,8 +10703,9 @@
 
   @override
   VoidTypeImpl substitute2(
-      List<DartType> argumentTypes, List<DartType> parameterTypes,
-      [List<FunctionTypeAliasElement> prune]) => this;
+          List<DartType> argumentTypes, List<DartType> parameterTypes,
+          [List<FunctionTypeAliasElement> prune]) =>
+      this;
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index b93931f..1e5794a 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -608,7 +608,7 @@
       // does not apply to conditional method invocation (i.e. 'C?.m(...)').
       //
       bool isConditional = node.operator.type == sc.TokenType.QUESTION_PERIOD;
-      ClassElementImpl typeReference = getTypeReference(target, isConditional);
+      ClassElementImpl typeReference = getTypeReference(target);
       if (typeReference != null) {
         staticElement =
             propagatedElement = _resolveElement(typeReference, methodName);
@@ -856,7 +856,7 @@
     // Otherwise, the prefix is really an expression that happens to be a simple
     // identifier and this is really equivalent to a property access node.
     //
-    _resolvePropertyAccess(prefix, identifier, false);
+    _resolvePropertyAccess(prefix, identifier);
     return null;
   }
 
@@ -912,8 +912,7 @@
       return null;
     }
     SimpleIdentifier propertyName = node.propertyName;
-    _resolvePropertyAccess(target, propertyName,
-        node.operator.type == sc.TokenType.QUESTION_PERIOD);
+    _resolvePropertyAccess(target, propertyName);
     return null;
   }
 
@@ -2416,7 +2415,7 @@
   }
 
   void _resolvePropertyAccess(
-      Expression target, SimpleIdentifier propertyName, bool isConditional) {
+      Expression target, SimpleIdentifier propertyName) {
     DartType staticType = _getStaticType(target);
     DartType propagatedType = _getPropagatedType(target);
     Element staticElement = null;
@@ -2427,7 +2426,7 @@
     // hierarchy, instead we just look for the member in the type only.  This
     // does not apply to conditional property accesses (i.e. 'C?.m').
     //
-    ClassElementImpl typeReference = getTypeReference(target, isConditional);
+    ClassElementImpl typeReference = getTypeReference(target);
     if (typeReference != null) {
       // TODO(brianwilkerson) Why are we setting the propagated element here?
       // It looks wrong.
@@ -2640,12 +2639,10 @@
   /**
    * Checks whether the given [expression] is a reference to a class. If it is
    * then the element representing the class is returned, otherwise `null` is
-   * returned.  [isConditional] indicates whether [expression] is to the left
-   * of a '?.' opertator.
+   * returned.
    */
-  static ClassElementImpl getTypeReference(
-      Expression expression, bool isConditional) {
-    if (!isConditional && expression is Identifier) {
+  static ClassElementImpl getTypeReference(Expression expression) {
+    if (expression is Identifier) {
       Element staticElement = expression.staticElement;
       if (staticElement is ClassElementImpl) {
         return staticElement;
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 649c2be..5086437 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1118,7 +1118,9 @@
         this._options.dart2jsHint != options.dart2jsHint ||
         (this._options.hint && !options.hint) ||
         this._options.preserveComments != options.preserveComments ||
-        this._options.enableStrictCallChecks != options.enableStrictCallChecks;
+        this._options.enableStrictCallChecks !=
+            options.enableStrictCallChecks ||
+        this._options.enableSuperMixins != options.enableSuperMixins;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
       this._options.cacheSize = cacheSize;
@@ -1144,6 +1146,7 @@
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
+    this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
     this._options.incrementalApi = options.incrementalApi;
@@ -6149,6 +6152,12 @@
   bool get enableStrictCallChecks;
 
   /**
+   * Return `true` if mixins are allowed to inherit from types other than
+   * Object, and are allowed to reference `super`.
+   */
+  bool get enableSuperMixins;
+
+  /**
    * Return `true` if errors, warnings and hints should be generated for sources
    * that are implicitly being analyzed. The default value is `true`.
    */
@@ -6252,6 +6261,12 @@
   bool enableStrictCallChecks = false;
 
   /**
+   * A flag indicating whether mixins are allowed to inherit from types other
+   * than Object, and are allowed to reference `super`.
+   */
+  bool enableSuperMixins = false;
+
+  /**
    * A flag indicating whether errors, warnings and hints should be generated
    * for sources that are implicitly being analyzed.
    */
@@ -6317,6 +6332,7 @@
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
     enableStrictCallChecks = options.enableStrictCallChecks;
+    enableSuperMixins = options.enableSuperMixins;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
     hint = options.hint;
@@ -6337,6 +6353,7 @@
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
     enableStrictCallChecks = options.enableStrictCallChecks;
+    enableSuperMixins = options.enableSuperMixins;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
     hint = options.hint;
@@ -6712,8 +6729,7 @@
    * [retentionPolicy] will be used to determine which pieces of data to remove
    * from the cache.
    */
-  CachePartition(this.context, int maxCacheSize, this._retentionPolicy) {
-    this._maxCacheSize = maxCacheSize;
+  CachePartition(this.context, this._maxCacheSize, this._retentionPolicy) {
     _recentlyUsed = new List<Source>();
   }
 
@@ -7370,11 +7386,7 @@
   /**
    * Initialize a newly created pair from the given [library] and [entryPairs].
    */
-  CycleBuilder_LibraryPair(ResolvableLibrary library,
-      List<CycleBuilder_SourceEntryPair> entryPairs) {
-    this.library = library;
-    this.entryPairs = entryPairs;
-  }
+  CycleBuilder_LibraryPair(this.library, this.entryPairs);
 }
 
 /**
@@ -7396,10 +7408,7 @@
   /**
    * Initialize a newly created pair from the given [source] and [entry].
    */
-  CycleBuilder_SourceEntryPair(Source source, DartEntry entry) {
-    this.source = source;
-    this.entry = entry;
-  }
+  CycleBuilder_SourceEntryPair(this.source, this.entry);
 }
 
 /**
@@ -8397,7 +8406,8 @@
       // Use the ErrorVerifier to compute the rest of the errors.
       //
       ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter,
-          libraryElement, typeProvider, new InheritanceManager(libraryElement));
+          libraryElement, typeProvider, new InheritanceManager(libraryElement),
+          context.analysisOptions.enableSuperMixins);
       _unit.accept(errorVerifier);
       _errors = errorListener.getErrorsForSource(source);
     });
@@ -8956,13 +8966,8 @@
   int _newLength = 0;
 
   IncrementalAnalysisCache(this.librarySource, this.source, this.resolvedUnit,
-      this.oldContents, String newContents, int offset, int oldLength,
-      int newLength) {
-    this._newContents = newContents;
-    this._offset = offset;
-    this._oldLength = oldLength;
-    this._newLength = newLength;
-  }
+      this.oldContents, this._newContents, this._offset, this._oldLength,
+      this._newLength);
 
   /**
    * Determine if the cache contains source changes that need to be analyzed
@@ -10832,8 +10837,9 @@
     //
     PerformanceStatistics.errors.makeCurrentWhile(() {
       ErrorReporter errorReporter = new ErrorReporter(errorListener, source);
-      ErrorVerifier errorVerifier = new ErrorVerifier(
-          errorReporter, _libraryElement, typeProvider, inheritanceManager);
+      ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter,
+          _libraryElement, typeProvider, inheritanceManager,
+          context.analysisOptions.enableSuperMixins);
       unit.accept(errorVerifier);
       // TODO(paulberry): as a temporary workaround for issue 21572,
       // ConstantVerifier is being run right after ConstantValueComputer, so we
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index c667af7..0964a8c 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -40,9 +40,9 @@
     ErrorCode errorCode2 = o2.errorCode;
     ErrorSeverity errorSeverity1 = errorCode1.errorSeverity;
     ErrorSeverity errorSeverity2 = errorCode2.errorSeverity;
-    ErrorType errorType1 = errorCode1.type;
-    ErrorType errorType2 = errorCode2.type;
     if (errorSeverity1 == errorSeverity2) {
+      ErrorType errorType1 = errorCode1.type;
+      ErrorType errorType2 = errorCode2.type;
       return errorType1.compareTo(errorType2);
     } else {
       return errorSeverity2.compareTo(errorSeverity1);
@@ -80,7 +80,7 @@
    * The number of characters from the offset to the end of the source which
    * encompasses the compilation error.
    */
-  int _length = 0;
+  int length = 0;
 
   /**
    * A flag indicating whether this error can be shown to be a non-issue because
@@ -94,9 +94,8 @@
    * [length]. The error will have the given [errorCode] and the list of
    * [arguments] will be used to complete the message.
    */
-  AnalysisError(this.source, this.offset, int length, this.errorCode,
+  AnalysisError(this.source, this.offset, this.length, this.errorCode,
       [List<Object> arguments]) {
-    this._length = length;
     this._message = formatList(errorCode.message, arguments);
     String correctionTemplate = errorCode.correction;
     if (correctionTemplate != null) {
@@ -141,13 +140,6 @@
   }
 
   /**
-   * Return the length of the error location, that is, the number of characters
-   * from the offset to the end of the source which encompasses the compilation
-   * error.
-   */
-  int get length => _length;
-
-  /**
    * Return the message to be displayed for this error. The message should
    * indicate what is wrong and why it is wrong.
    */
@@ -167,7 +159,7 @@
     if (!identical(errorCode, other.errorCode)) {
       return false;
     }
-    if (offset != other.offset || _length != other._length) {
+    if (offset != other.offset || length != other.length) {
       return false;
     }
     if (isStaticOnly != other.isStaticOnly) {
@@ -197,7 +189,7 @@
     buffer.write("(");
     buffer.write(offset);
     buffer.write("..");
-    buffer.write(offset + _length - 1);
+    buffer.write(offset + length - 1);
     buffer.write("): ");
     //buffer.write("(" + lineNumber + ":" + columnNumber + "): ");
     buffer.write(_message);
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index e80e02a..9e25a85 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -255,10 +255,16 @@
   List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
 
   /**
+   * If `true`, mixins are allowed to inherit from types other than Object, and
+   * are allowed to reference `super`.
+   */
+  final bool enableSuperMixins;
+
+  /**
    * Initialize a newly created error verifier.
    */
   ErrorVerifier(this._errorReporter, this._currentLibrary, this._typeProvider,
-      this._inheritanceManager) {
+      this._inheritanceManager, this.enableSuperMixins) {
     this._isInSystemLibrary = _currentLibrary.source.isInSystemLibrary;
     this._hasExtUri = _currentLibrary.hasExtUri;
     _isEnclosingConstructorConst = false;
@@ -859,9 +865,7 @@
     Expression target = node.realTarget;
     SimpleIdentifier methodName = node.methodName;
     if (target != null) {
-      bool isConditional = node.operator.type == sc.TokenType.QUESTION_PERIOD;
-      ClassElement typeReference =
-          ElementResolver.getTypeReference(target, isConditional);
+      ClassElement typeReference = ElementResolver.getTypeReference(target);
       _checkForStaticAccessToInstanceMember(typeReference, methodName);
       _checkForInstanceAccessToStaticMember(typeReference, methodName);
     } else {
@@ -898,7 +902,7 @@
   Object visitPrefixedIdentifier(PrefixedIdentifier node) {
     if (node.parent is! Annotation) {
       ClassElement typeReference =
-          ElementResolver.getTypeReference(node.prefix, false);
+          ElementResolver.getTypeReference(node.prefix);
       SimpleIdentifier name = node.identifier;
       _checkForStaticAccessToInstanceMember(typeReference, name);
       _checkForInstanceAccessToStaticMember(typeReference, name);
@@ -923,7 +927,7 @@
   Object visitPropertyAccess(PropertyAccess node) {
     bool isConditional = node.operator.type == sc.TokenType.QUESTION_PERIOD;
     ClassElement typeReference =
-        ElementResolver.getTypeReference(node.realTarget, isConditional);
+        ElementResolver.getTypeReference(node.realTarget);
     SimpleIdentifier propertyName = node.propertyName;
     _checkForStaticAccessToInstanceMember(typeReference, propertyName);
     _checkForInstanceAccessToStaticMember(typeReference, propertyName);
@@ -1653,7 +1657,8 @@
         if (_checkForMixinDeclaresConstructor(mixinName, mixinElement)) {
           problemReported = true;
         }
-        if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
+        if (!enableSuperMixins &&
+            _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
           problemReported = true;
         }
         if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
@@ -4113,9 +4118,11 @@
       return false;
     }
     for (int i = 0; i < nameCount; i++) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, statement,
-          [constantNames[i]]);
+      int offset = statement.offset;
+      int end = statement.rightParenthesis.end;
+      _errorReporter.reportErrorForOffset(
+          CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH, offset,
+          end - offset, [constantNames[i]]);
     }
     return true;
   }
@@ -4209,7 +4216,7 @@
    */
   bool _checkForMixinReferencesSuper(
       TypeName mixinName, ClassElement mixinElement) {
-    if (mixinElement.hasReferenceToSuper) {
+    if (!enableSuperMixins && mixinElement.hasReferenceToSuper) {
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, mixinName,
           [mixinElement.name]);
diff --git a/pkg/analyzer/lib/src/generated/html.dart b/pkg/analyzer/lib/src/generated/html.dart
index 99b0d51..3bccaab 100644
--- a/pkg/analyzer/lib/src/generated/html.dart
+++ b/pkg/analyzer/lib/src/generated/html.dart
@@ -1160,11 +1160,7 @@
 
   int length = 0;
 
-  XmlExpression_Reference(Element element, int offset, int length) {
-    this.element = element;
-    this.offset = offset;
-    this.length = length;
-  }
+  XmlExpression_Reference(this.element, this.offset, this.length);
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 78481ce..2fcef7b 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -23,7 +23,7 @@
         VERIFY_ERRORS;
 import 'package:analyzer/task/dart.dart'
     show DART_ERRORS, LibrarySpecificUnit, PARSED_UNIT, TOKEN_STREAM;
-import 'package:analyzer/task/general.dart' show CONTENT;
+import 'package:analyzer/task/general.dart' show CONTENT, LINE_INFO;
 import 'package:analyzer/task/model.dart' show ResultDescriptor;
 
 import 'ast.dart';
@@ -1233,7 +1233,8 @@
       ErrorReporter errorReporter = new ErrorReporter(errorListener, _source);
       ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter,
           _definingLibrary, _typeProvider,
-          new InheritanceManager(_definingLibrary));
+          new InheritanceManager(_definingLibrary),
+          _context.analysisOptions.enableSuperMixins);
       if (_resolutionContext.enclosingClassDeclaration != null) {
         errorVerifier.visitClassDeclarationIncrementally(
             _resolutionContext.enclosingClassDeclaration);
@@ -1274,6 +1275,7 @@
   int _updateEndOld;
   int _updateEndNew;
 
+  LineInfo _newLineInfo;
   List<AnalysisError> _newScanErrors = <AnalysisError>[];
   List<AnalysisError> _newParseErrors = <AnalysisError>[];
 
@@ -1508,6 +1510,7 @@
     CharSequenceReader reader = new CharSequenceReader(code);
     Scanner scanner = new Scanner(_unitSource, reader, errorListener);
     Token token = scanner.tokenize();
+    _newLineInfo = new LineInfo(scanner.lineStarts);
     _newScanErrors = errorListener.errors;
     return token;
   }
@@ -1564,6 +1567,7 @@
     _newSourceEntry.setState(SCAN_ERRORS, CacheState.INVALID);
     List<TargetedResult> scanDeps =
         <TargetedResult>[new TargetedResult(_unitSource, CONTENT)];
+    _newSourceEntry.setValue(LINE_INFO, _newLineInfo, scanDeps);
     _newSourceEntry.setValue(SCAN_ERRORS, _newScanErrors, scanDeps);
     // parse results
     List<TargetedResult> parseDeps =
@@ -1574,6 +1578,7 @@
   }
 
   void _updateEntry_OLD() {
+    _oldEntry.setValue(SourceEntry.LINE_INFO, _newLineInfo);
     _oldEntry.setValue(DartEntry.SCAN_ERRORS, _newScanErrors);
     _oldEntry.setValue(DartEntry.PARSE_ERRORS, _newParseErrors);
   }
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 8581fa4..df3187b 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -9428,8 +9428,13 @@
   @override
   bool visitAwaitExpression(AwaitExpression node) {
     AwaitExpression toNode = this._toNode as AwaitExpression;
-    return _and(_isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
-        _isEqualNodes(node.expression, toNode.expression));
+    if (_and(_isEqualTokens(node.awaitKeyword, toNode.awaitKeyword),
+        _isEqualNodes(node.expression, toNode.expression))) {
+      toNode.propagatedType = node.propagatedType;
+      toNode.staticType = node.staticType;
+      return true;
+    }
+    return false;
   }
 
   @override
@@ -10033,12 +10038,16 @@
   @override
   bool visitLibraryDirective(LibraryDirective node) {
     LibraryDirective toNode = this._toNode as LibraryDirective;
-    return _and(
+    if (_and(
         _isEqualNodes(node.documentationComment, toNode.documentationComment),
         _isEqualNodeLists(node.metadata, toNode.metadata),
         _isEqualTokens(node.libraryKeyword, toNode.libraryKeyword),
         _isEqualNodes(node.name, toNode.name),
-        _isEqualTokens(node.semicolon, toNode.semicolon));
+        _isEqualTokens(node.semicolon, toNode.semicolon))) {
+      toNode.element = node.element;
+      return true;
+    }
+    return false;
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 49fc6c7..8110c8c 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -293,9 +293,12 @@
    * @return `true` if and only if an hint code is generated on the passed node
    * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
    */
-  bool _checkForArgumentTypeNotAssignable(Expression expression,
-      DartType expectedStaticType, DartType actualStaticType,
-      DartType expectedPropagatedType, DartType actualPropagatedType,
+  bool _checkForArgumentTypeNotAssignable(
+      Expression expression,
+      DartType expectedStaticType,
+      DartType actualStaticType,
+      DartType expectedPropagatedType,
+      DartType actualPropagatedType,
       ErrorCode hintCode) {
     //
     // Warning case: test static type information
@@ -347,8 +350,10 @@
     DartType propagatedParameterType = propagatedParameterElement == null
         ? null
         : propagatedParameterElement.type;
-    return _checkForArgumentTypeNotAssignableWithExpectedTypes(argument,
-        staticParameterType, propagatedParameterType,
+    return _checkForArgumentTypeNotAssignableWithExpectedTypes(
+        argument,
+        staticParameterType,
+        propagatedParameterType,
         HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE);
   }
 
@@ -364,11 +369,17 @@
    * See [HintCode.ARGUMENT_TYPE_NOT_ASSIGNABLE].
    */
   bool _checkForArgumentTypeNotAssignableWithExpectedTypes(
-          Expression expression, DartType expectedStaticType,
-          DartType expectedPropagatedType, ErrorCode errorCode) =>
-      _checkForArgumentTypeNotAssignable(expression, expectedStaticType,
-          expression.staticType, expectedPropagatedType,
-          expression.propagatedType, errorCode);
+          Expression expression,
+          DartType expectedStaticType,
+          DartType expectedPropagatedType,
+          ErrorCode errorCode) =>
+      _checkForArgumentTypeNotAssignable(
+          expression,
+          expectedStaticType,
+          expression.staticType,
+          expectedPropagatedType,
+          expression.propagatedType,
+          errorCode);
 
   /**
    * This verifies that the passed arguments can be assigned to their corresponding parameters.
@@ -541,7 +552,8 @@
     }
     if (importedLibrary.hasLoadLibraryFunction) {
       _errorReporter.reportErrorForNode(
-          HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION, node,
+          HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION,
+          node,
           [importedLibrary.name]);
       return true;
     }
@@ -740,12 +752,16 @@
   AnalysisError getErrorForDuplicate(Element existing, Element duplicate) {
     if (existing is PropertyAccessorElement && duplicate is MethodElement) {
       if (existing.nameOffset < duplicate.nameOffset) {
-        return new AnalysisError(duplicate.source, duplicate.nameOffset,
+        return new AnalysisError(
+            duplicate.source,
+            duplicate.nameOffset,
             duplicate.displayName.length,
             CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
             [existing.displayName]);
       } else {
-        return new AnalysisError(existing.source, existing.nameOffset,
+        return new AnalysisError(
+            existing.source,
+            existing.nameOffset,
             existing.displayName.length,
             CompileTimeErrorCode.GETTER_AND_METHOD_WITH_SAME_NAME,
             [existing.displayName]);
@@ -919,8 +935,11 @@
             new ConstantEvaluationEngine(_typeProvider, declaredVariables);
         ConstantVisitor constantVisitor =
             new ConstantVisitor(evaluationEngine, _errorReporter);
-        evaluationEngine.evaluateConstructorCall(node,
-            node.argumentList.arguments, constructor, constantVisitor,
+        evaluationEngine.evaluateConstructorCall(
+            node,
+            node.argumentList.arguments,
+            constructor,
+            constantVisitor,
             _errorReporter);
       }
     }
@@ -976,7 +995,8 @@
           if (_implementsEqualsWhenNotAllowed(type)) {
             _errorReporter.reportErrorForNode(
                 CompileTimeErrorCode.CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
-                key, [type.displayName]);
+                key,
+                [type.displayName]);
           }
         }
       } else {
@@ -1040,7 +1060,8 @@
             if (firstType != nType) {
               _errorReporter.reportErrorForNode(
                   CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
-                  expression, [expression.toSource(), firstType.displayName]);
+                  expression,
+                  [expression.toSource(), firstType.displayName]);
               foundError = true;
             }
           }
@@ -1093,7 +1114,8 @@
     // report error
     _errorReporter.reportErrorForToken(
         CompileTimeErrorCode.CASE_EXPRESSION_TYPE_IMPLEMENTS_EQUALS,
-        node.switchKeyword, [type.displayName]);
+        node.switchKeyword,
+        [type.displayName]);
     return true;
   }
 
@@ -1299,11 +1321,13 @@
                   new ErrorReporter(errorListener, _errorReporter.source);
               DartObjectImpl result = initializer.accept(new ConstantVisitor(
                   new ConstantEvaluationEngine(
-                      _typeProvider, declaredVariables), subErrorReporter));
+                      _typeProvider, declaredVariables),
+                  subErrorReporter));
               if (result == null) {
                 _errorReporter.reportErrorForNode(
                     CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
-                    errorSite, [variableDeclaration.name.name]);
+                    errorSite,
+                    [variableDeclaration.name.name]);
               }
             }
           }
@@ -1625,10 +1649,10 @@
               int offset = catchClause.offset;
               int length = lastCatchClause.end - offset;
               _errorReporter.reportErrorForOffset(
-                  HintCode.DEAD_CODE_ON_CATCH_SUBTYPE, offset, length, [
-                currentType.displayName,
-                type.displayName
-              ]);
+                  HintCode.DEAD_CODE_ON_CATCH_SUBTYPE,
+                  offset,
+                  length,
+                  [currentType.displayName, type.displayName]);
               return null;
             }
           }
@@ -1925,9 +1949,10 @@
     String uri = _getStringValue(node.uri);
     if (uri != null) {
       LibraryElement library = _enclosingUnit.library;
-      ExportElement exportElement = _findExport(library.exports,
-          _enclosingUnit.context.sourceFactory.resolveUri(
-              _enclosingUnit.source, uri));
+      ExportElement exportElement = _findExport(
+          library.exports,
+          _enclosingUnit.context.sourceFactory
+              .resolveUri(_enclosingUnit.source, uri));
       node.element = exportElement;
     }
     return super.visitExportDirective(node);
@@ -2031,9 +2056,11 @@
     String uri = _getStringValue(node.uri);
     if (uri != null) {
       LibraryElement library = _enclosingUnit.library;
-      ImportElement importElement = _findImport(library.imports,
-          _enclosingUnit.context.sourceFactory.resolveUri(
-              _enclosingUnit.source, uri), node.prefix);
+      ImportElement importElement = _findImport(
+          library.imports,
+          _enclosingUnit.context.sourceFactory
+              .resolveUri(_enclosingUnit.source, uri),
+          node.prefix);
       node.element = importElement;
     }
     return super.visitImportDirective(node);
@@ -2084,8 +2111,8 @@
   Object visitPartDirective(PartDirective node) {
     String uri = _getStringValue(node.uri);
     if (uri != null) {
-      Source partSource = _enclosingUnit.context.sourceFactory.resolveUri(
-          _enclosingUnit.source, uri);
+      Source partSource = _enclosingUnit.context.sourceFactory
+          .resolveUri(_enclosingUnit.source, uri);
       node.element = _findPart(_enclosingUnit.library.parts, partSource);
     }
     return super.visitPartDirective(node);
@@ -3012,8 +3039,8 @@
       } else {
         String message =
             "Exception caught in ElementBuilder.visitMethodDeclaration()";
-        AnalysisEngine.instance.logger.logError(
-            message, new CaughtException(exception, stackTrace));
+        AnalysisEngine.instance.logger
+            .logError(message, new CaughtException(exception, stackTrace));
       }
     } finally {
       if (node.name.staticElement == null) {
@@ -3025,7 +3052,8 @@
         buffer.write(" in ");
         buffer.write(classNode.name);
         buffer.write(" was not set while trying to resolve types.");
-        AnalysisEngine.instance.logger.logError(buffer.toString(),
+        AnalysisEngine.instance.logger.logError(
+            buffer.toString(),
             new CaughtException(
                 new AnalysisException(buffer.toString()), null));
       }
@@ -3726,8 +3754,10 @@
     if (_hasHiddenName) {
       Element hiddenElement = _hiddenElements[name];
       if (hiddenElement != null) {
-        errorListener.onError(new AnalysisError(getSource(identifier),
-            identifier.offset, identifier.length,
+        errorListener.onError(new AnalysisError(
+            getSource(identifier),
+            identifier.offset,
+            identifier.length,
             CompileTimeErrorCode.REFERENCED_BEFORE_DECLARATION, []));
         return hiddenElement;
       }
@@ -4758,12 +4788,7 @@
    * @param classToTagsMap a table mapping the classes defined in the HTML file to an array
    *          containing the names of tags with that class
    */
-  HtmlTagInfo(List<String> allTags, HashMap<String, String> idToTagMap,
-      HashMap<String, List<String>> classToTagsMap) {
-    this.allTags = allTags;
-    this.idToTagMap = idToTagMap;
-    this.classToTagsMap = classToTagsMap;
-  }
+  HtmlTagInfo(this.allTags, this.idToTagMap, this.classToTagsMap);
 
   /**
    * Return an array containing the tags that have the given class, or {@code null} if there are no
@@ -5678,7 +5703,8 @@
    * @return the passed function type with any parameterized types substituted
    */
   FunctionType substituteTypeArgumentsInMemberFromInheritance(
-      FunctionType baseFunctionType, String memberName,
+      FunctionType baseFunctionType,
+      String memberName,
       InterfaceType definingType) {
     // if the baseFunctionType is null, or does not have any parameters,
     // return it.
@@ -6235,12 +6261,12 @@
               if (!classHasMember) {
                 String firstTwoFuntionTypesStr =
                     "${executableElementTypes[0]}, ${executableElementTypes[1]}";
-                _reportError(classElt, classElt.nameOffset,
+                _reportError(
+                    classElt,
+                    classElt.nameOffset,
                     classElt.displayName.length,
-                    StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE, [
-                  key,
-                  firstTwoFuntionTypesStr
-                ]);
+                    StaticTypeWarningCode.INCONSISTENT_METHOD_INHERITANCE,
+                    [key, firstTwoFuntionTypesStr]);
               }
             } else {
               //
@@ -6252,9 +6278,8 @@
               // Tests: test_getMapOfMembersInheritedFromInterfaces_
               // union_multipleSubtypes_*
               //
-              List<ExecutableElement> elementArrayToMerge =
-                  new List<ExecutableElement>(
-                      subtypesOfAllOtherTypesIndexes.length);
+              List<ExecutableElement> elementArrayToMerge = new List<
+                  ExecutableElement>(subtypesOfAllOtherTypesIndexes.length);
               for (int i = 0; i < elementArrayToMerge.length; i++) {
                 elementArrayToMerge[i] =
                     elements[subtypesOfAllOtherTypesIndexes[i]];
@@ -6265,7 +6290,9 @@
             }
           }
         } else {
-          _reportError(classElt, classElt.nameOffset,
+          _reportError(
+              classElt,
+              classElt.nameOffset,
               classElt.displayName.length,
               StaticWarningCode.INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD,
               [key]);
@@ -6388,8 +6415,11 @@
       }
       namedParametersList.addAll(_getNamedParameterNames(element));
     }
-    return _createSyntheticExecutableElement(elementArrayToMerge,
-        elementArrayToMerge[0].displayName, r, h - r,
+    return _createSyntheticExecutableElement(
+        elementArrayToMerge,
+        elementArrayToMerge[0].displayName,
+        r,
+        h - r,
         new List.from(namedParametersList));
   }
 
@@ -6405,8 +6435,10 @@
    * @return the created synthetic element
    */
   static ExecutableElement _createSyntheticExecutableElement(
-      List<ExecutableElement> elementArrayToMerge, String name,
-      int numOfRequiredParameters, int numOfPositionalParameters,
+      List<ExecutableElement> elementArrayToMerge,
+      String name,
+      int numOfRequiredParameters,
+      int numOfPositionalParameters,
       List<String> namedParameters) {
     DynamicTypeImpl dynamicType = DynamicTypeImpl.instance;
     SimpleIdentifier nameIdentifier = new SimpleIdentifier(
@@ -6788,8 +6820,8 @@
   LibraryElementImpl get libraryElement {
     if (_libraryElement == null) {
       try {
-        _libraryElement = _analysisContext
-            .computeLibraryElement(librarySource) as LibraryElementImpl;
+        _libraryElement = _analysisContext.computeLibraryElement(librarySource)
+            as LibraryElementImpl;
       } on AnalysisException catch (exception, stackTrace) {
         AnalysisEngine.instance.logger.logError(
             "Could not compute library element for ${librarySource.fullName}",
@@ -6866,9 +6898,12 @@
       Source source =
           _analysisContext.sourceFactory.resolveUri(librarySource, uriContent);
       if (!_analysisContext.exists(source)) {
-        errorListener.onError(new AnalysisError(librarySource,
-            uriLiteral.offset, uriLiteral.length,
-            CompileTimeErrorCode.URI_DOES_NOT_EXIST, [uriContent]));
+        errorListener.onError(new AnalysisError(
+            librarySource,
+            uriLiteral.offset,
+            uriLiteral.length,
+            CompileTimeErrorCode.URI_DOES_NOT_EXIST,
+            [uriContent]));
       }
       return source;
     } on URISyntaxException {
@@ -6973,21 +7008,24 @@
           String partLibraryName =
               _getPartLibraryName(partSource, partUnit, directivesToResolve);
           if (partLibraryName == null) {
-            _errorListener.onError(new AnalysisError(librarySource,
-                partUri.offset, partUri.length,
-                CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()]));
+            _errorListener.onError(new AnalysisError(
+                librarySource,
+                partUri.offset,
+                partUri.length,
+                CompileTimeErrorCode.PART_OF_NON_PART,
+                [partUri.toSource()]));
           } else if (libraryNameNode == null) {
             // TODO(brianwilkerson) Collect the names declared by the part.
             // If they are all the same then we can use that name as the
             // inferred name of the library and present it in a quick-fix.
             // partLibraryNames.add(partLibraryName);
           } else if (libraryNameNode.name != partLibraryName) {
-            _errorListener.onError(new AnalysisError(librarySource,
-                partUri.offset, partUri.length,
-                StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [
-              libraryNameNode.name,
-              partLibraryName
-            ]));
+            _errorListener.onError(new AnalysisError(
+                librarySource,
+                partUri.offset,
+                partUri.length,
+                StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+                [libraryNameNode.name, partLibraryName]));
           }
           if (entryPoint == null) {
             entryPoint = _findEntryPoint(part);
@@ -7077,21 +7115,24 @@
             String partLibraryName =
                 _getPartLibraryName(partSource, partUnit, directivesToResolve);
             if (partLibraryName == null) {
-              _errorListener.onError(new AnalysisError(librarySource,
-                  partUri.offset, partUri.length,
-                  CompileTimeErrorCode.PART_OF_NON_PART, [partUri.toSource()]));
+              _errorListener.onError(new AnalysisError(
+                  librarySource,
+                  partUri.offset,
+                  partUri.length,
+                  CompileTimeErrorCode.PART_OF_NON_PART,
+                  [partUri.toSource()]));
             } else if (libraryNameNode == null) {
               // TODO(brianwilkerson) Collect the names declared by the part.
               // If they are all the same then we can use that name as the
               // inferred name of the library and present it in a quick-fix.
               // partLibraryNames.add(partLibraryName);
             } else if (libraryNameNode.name != partLibraryName) {
-              _errorListener.onError(new AnalysisError(librarySource,
-                  partUri.offset, partUri.length,
-                  StaticWarningCode.PART_OF_DIFFERENT_LIBRARY, [
-                libraryNameNode.name,
-                partLibraryName
-              ]));
+              _errorListener.onError(new AnalysisError(
+                  librarySource,
+                  partUri.offset,
+                  partUri.length,
+                  StaticWarningCode.PART_OF_DIFFERENT_LIBRARY,
+                  [libraryNameNode.name, partLibraryName]));
             }
             if (entryPoint == null) {
               entryPoint = _findEntryPoint(part);
@@ -7296,8 +7337,10 @@
         libraryNames[i] = _getLibraryName(conflictingMembers[i]);
       }
       libraryNames.sort();
-      errorListener.onError(new AnalysisError(getSource(identifier),
-          identifier.offset, identifier.length,
+      errorListener.onError(new AnalysisError(
+          getSource(identifier),
+          identifier.offset,
+          identifier.length,
           StaticWarningCode.AMBIGUOUS_IMPORT, [
         foundEltName,
         StringUtilities.printListOfQuotedNames(libraryNames)
@@ -7398,13 +7441,12 @@
     if (sdkElement != null && nonSdkElements.length > 0) {
       String sdkLibName = _getLibraryName(sdkElement);
       String otherLibName = _getLibraryName(nonSdkElements[0]);
-      errorListener.onError(new AnalysisError(getSource(identifier),
-          identifier.offset, identifier.length,
-          StaticWarningCode.CONFLICTING_DART_IMPORT, [
-        name,
-        sdkLibName,
-        otherLibName
-      ]));
+      errorListener.onError(new AnalysisError(
+          getSource(identifier),
+          identifier.offset,
+          identifier.length,
+          StaticWarningCode.CONFLICTING_DART_IMPORT,
+          [name, sdkLibName, otherLibName]));
     }
     if (nonSdkElements.length == conflictingElements.length) {
       // None of the members were removed
@@ -7753,7 +7795,8 @@
    * @param visitedLibraries the libraries that have already been visited, used to prevent infinite
    *          recursion
    */
-  void _addToDependencyMap(Library library,
+  void _addToDependencyMap(
+      Library library,
       HashMap<Library, List<Library>> dependencyMap,
       Set<Library> visitedLibraries) {
     if (visitedLibraries.add(library)) {
@@ -7858,8 +7901,11 @@
                 ErrorCode errorCode = (importElement.isDeferred
                     ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
                     : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-                _errorListener.onError(new AnalysisError(library.librarySource,
-                    uriLiteral.offset, uriLiteral.length, errorCode,
+                _errorListener.onError(new AnalysisError(
+                    library.librarySource,
+                    uriLiteral.offset,
+                    uriLiteral.length,
+                    errorCode,
                     [uriLiteral.toSource()]));
               }
             }
@@ -7888,8 +7934,10 @@
               exports.add(exportElement);
               if (analysisContext.computeKindOf(exportedSource) !=
                   SourceKind.LIBRARY) {
-                _errorListener.onError(new AnalysisError(library.librarySource,
-                    uriLiteral.offset, uriLiteral.length,
+                _errorListener.onError(new AnalysisError(
+                    library.librarySource,
+                    uriLiteral.offset,
+                    uriLiteral.length,
                     CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
                     [uriLiteral.toSource()]));
               }
@@ -8046,7 +8094,8 @@
    */
   void _computeLibraryDependencies(Library library) {
     Source librarySource = library.librarySource;
-    _computeLibraryDependenciesFromDirectives(library,
+    _computeLibraryDependenciesFromDirectives(
+        library,
         analysisContext.computeImportedLibraries(librarySource),
         analysisContext.computeExportedLibraries(librarySource));
   }
@@ -8200,7 +8249,9 @@
             ErrorReporter errorReporter =
                 new ErrorReporter(_errorListener, source);
             ConstantVerifier constantVerifier = new ConstantVerifier(
-                errorReporter, library.libraryElement, _typeProvider,
+                errorReporter,
+                library.libraryElement,
+                _typeProvider,
                 analysisContext.declaredVariables);
             unit.accept(constantVerifier);
           } on AnalysisException catch (exception, stackTrace) {
@@ -8503,8 +8554,11 @@
                 ErrorCode errorCode = (importElement.isDeferred
                     ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
                     : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-                _errorListener.onError(new AnalysisError(library.librarySource,
-                    uriLiteral.offset, uriLiteral.length, errorCode,
+                _errorListener.onError(new AnalysisError(
+                    library.librarySource,
+                    uriLiteral.offset,
+                    uriLiteral.length,
+                    errorCode,
                     [uriLiteral.toSource()]));
               }
             }
@@ -8536,8 +8590,10 @@
               exports.add(exportElement);
               if (analysisContext.computeKindOf(exportedSource) !=
                   SourceKind.LIBRARY) {
-                _errorListener.onError(new AnalysisError(library.librarySource,
-                    uriLiteral.offset, uriLiteral.length,
+                _errorListener.onError(new AnalysisError(
+                    library.librarySource,
+                    uriLiteral.offset,
+                    uriLiteral.length,
                     CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
                     [uriLiteral.toSource()]));
               }
@@ -8631,7 +8687,9 @@
           Source source = unit.source;
           CompilationUnit ast = unit.compilationUnit;
           TypeResolverVisitor visitor = new TypeResolverVisitor(
-              library.libraryElement, source, _typeProvider,
+              library.libraryElement,
+              source,
+              _typeProvider,
               library.libraryScope.errorListener,
               nameScope: library.libraryScope);
           ast.accept(visitor);
@@ -8681,7 +8739,9 @@
           ErrorReporter errorReporter =
               new ErrorReporter(_errorListener, unit.source);
           ConstantVerifier constantVerifier = new ConstantVerifier(
-              errorReporter, library.libraryElement, _typeProvider,
+              errorReporter,
+              library.libraryElement,
+              _typeProvider,
               analysisContext.declaredVariables);
           ast.accept(constantVerifier);
         }
@@ -8819,7 +8879,9 @@
           offset = accessor.variable.nameOffset;
         }
       }
-      return new AnalysisError(duplicate.source, offset,
+      return new AnalysisError(
+          duplicate.source,
+          offset,
           duplicate.displayName.length,
           CompileTimeErrorCode.PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER,
           [existing.displayName]);
@@ -9301,7 +9363,8 @@
           definedNames.addAll(exportedNames);
         }
       }
-      _addAllFromNamespace(definedNames,
+      _addAllFromNamespace(
+          definedNames,
           (library.context as InternalAnalysisContext)
               .getPublicNamespace(library));
       return definedNames;
@@ -10025,10 +10088,11 @@
    */
   ResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
-      {Scope nameScope, InheritanceManager inheritanceManager,
+      {Scope nameScope,
+      InheritanceManager inheritanceManager,
       StaticTypeAnalyzerFactory typeAnalyzerFactory})
       : super(definingLibrary, source, typeProvider, errorListener,
-          nameScope: nameScope) {
+            nameScope: nameScope) {
     if (inheritanceManager == null) {
       this._inheritanceManager = new InheritanceManager(definingLibrary);
     } else {
@@ -10056,10 +10120,10 @@
       Library library, Source source, TypeProvider typeProvider,
       {StaticTypeAnalyzerFactory typeAnalyzerFactory})
       : this(
-          library.libraryElement, source, typeProvider, library.errorListener,
-          nameScope: library.libraryScope,
-          inheritanceManager: library.inheritanceManager,
-          typeAnalyzerFactory: typeAnalyzerFactory);
+            library.libraryElement, source, typeProvider, library.errorListener,
+            nameScope: library.libraryScope,
+            inheritanceManager: library.inheritanceManager,
+            typeAnalyzerFactory: typeAnalyzerFactory);
 
   /**
    * Return the element representing the function containing the current node, or `null` if
@@ -10715,9 +10779,16 @@
         if (loopVariable != null && iterable != null) {
           LocalVariableElement loopElement = loopVariable.element;
           if (loopElement != null) {
-            DartType iteratorElementType = _getIteratorElementType(iterable);
-            overrideVariable(loopElement, iteratorElementType, true);
-            _recordPropagatedType(loopVariable.identifier, iteratorElementType);
+            DartType propagatedType = null;
+            if (node.awaitKeyword == null) {
+              propagatedType = _getIteratorElementType(iterable);
+            } else {
+              propagatedType = _getStreamElementType(iterable);
+            }
+            if (propagatedType != null) {
+              overrideVariable(loopElement, propagatedType, true);
+              _recordPropagatedType(loopVariable.identifier, propagatedType);
+            }
           }
         } else if (identifier != null && iterable != null) {
           Element identifierElement = identifier.staticElement;
@@ -11099,12 +11170,11 @@
   }
 
   /**
-   * The given expression is the expression used to compute the iterator for a for-each statement.
-   * Attempt to compute the type of objects that will be assigned to the loop variable and return
-   * that type. Return `null` if the type could not be determined.
-   *
-   * @param iterator the iterator for a for-each statement
-   * @return the type of objects that will be assigned to the loop variable
+   * The given expression is the expression used to compute the iterator for a
+   * for-each statement. Attempt to compute the type of objects that will be
+   * assigned to the loop variable and return that type. Return `null` if the
+   * type could not be determined. The [iteratorExpression] is the expression
+   * that will return the Iterable being iterated over.
    */
   DartType _getIteratorElementType(Expression iteratorExpression) {
     DartType expressionType = iteratorExpression.bestType;
@@ -11132,6 +11202,40 @@
   }
 
   /**
+   * The given expression is the expression used to compute the stream for an
+   * asyncronous for-each statement. Attempt to compute the type of objects that
+   * will be assigned to the loop variable and return that type. Return `null`
+   * if the type could not be determined. The [streamExpression] is the
+   * expression that will return the stream being iterated over.
+   */
+  DartType _getStreamElementType(Expression streamExpression) {
+    DartType streamType = streamExpression.bestType;
+    if (streamType is InterfaceType) {
+      FunctionType listenFunction =
+          _inheritanceManager.lookupMemberType(streamType, "listen");
+      if (listenFunction == null) {
+        return null;
+      }
+      List<ParameterElement> listenParameters = listenFunction.parameters;
+      if (listenParameters == null || listenParameters.length < 1) {
+        return null;
+      }
+      DartType onDataType = listenParameters[0].type;
+      if (onDataType is FunctionType) {
+        List<ParameterElement> onDataParameters = onDataType.parameters;
+        if (onDataParameters == null || onDataParameters.length < 1) {
+          return null;
+        }
+        DartType eventType = onDataParameters[0].type;
+        if (eventType.element == streamType.typeParameters[0]) {
+          return streamType.typeArguments[0];
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
    * If given "mayBeClosure" is [FunctionExpression] without explicit parameters types and its
    * required type is [FunctionType], then infer parameters types from [FunctionType].
    */
@@ -11150,7 +11254,7 @@
     // If the expectedClosureType is not more specific than the static type,
     // return.
     DartType staticClosureType =
-        (closure.element != null ? closure.element.type : null) as DartType;
+        closure.element != null ? closure.element.type : null;
     if (staticClosureType != null &&
         !expectedClosureType.isMoreSpecificThan(staticClosureType)) {
       return;
@@ -11540,8 +11644,11 @@
     // TODO(jwren) There are 4 error codes for duplicate, but only 1 is being
     // generated.
     Source source = duplicate.source;
-    return new AnalysisError(source, duplicate.nameOffset,
-        duplicate.displayName.length, CompileTimeErrorCode.DUPLICATE_DEFINITION,
+    return new AnalysisError(
+        source,
+        duplicate.nameOffset,
+        duplicate.displayName.length,
+        CompileTimeErrorCode.DUPLICATE_DEFINITION,
         [existing.displayName]);
   }
 
@@ -11640,7 +11747,7 @@
   /**
    * The element for the library containing the compilation unit being visited.
    */
-  LibraryElement _definingLibrary;
+  final LibraryElement definingLibrary;
 
   /**
    * The source representing the compilation unit being visited.
@@ -11650,7 +11757,7 @@
   /**
    * The error listener that will be informed of any errors that are found during resolution.
    */
-  AnalysisErrorListener _errorListener;
+  final AnalysisErrorListener errorListener;
 
   /**
    * The scope used to resolve identifiers.
@@ -11694,10 +11801,9 @@
    * first be visited.  If `null` or unspecified, a new [LibraryScope] will be
    * created based on [definingLibrary] and [typeProvider].
    */
-  ScopedVisitor(LibraryElement definingLibrary, this.source, this.typeProvider,
-      AnalysisErrorListener errorListener, {Scope nameScope}) {
-    this._definingLibrary = definingLibrary;
-    this._errorListener = errorListener;
+  ScopedVisitor(
+      this.definingLibrary, this.source, this.typeProvider, this.errorListener,
+      {Scope nameScope}) {
     if (nameScope == null) {
       this.nameScope = new LibraryScope(definingLibrary, errorListener);
     } else {
@@ -11706,13 +11812,6 @@
   }
 
   /**
-   * Return the library element for the library containing the compilation unit being resolved.
-   *
-   * @return the library element for the library containing the compilation unit being resolved
-   */
-  LibraryElement get definingLibrary => _definingLibrary;
-
-  /**
    * Return the implicit label scope in which the current node is being
    * resolved.
    */
@@ -11748,7 +11847,7 @@
    */
   void reportErrorForNode(ErrorCode errorCode, AstNode node,
       [List<Object> arguments]) {
-    _errorListener.onError(new AnalysisError(
+    errorListener.onError(new AnalysisError(
         source, node.offset, node.length, errorCode, arguments));
   }
 
@@ -11762,7 +11861,7 @@
    */
   void reportErrorForOffset(ErrorCode errorCode, int offset, int length,
       [List<Object> arguments]) {
-    _errorListener.onError(
+    errorListener.onError(
         new AnalysisError(source, offset, length, errorCode, arguments));
   }
 
@@ -11775,7 +11874,7 @@
    */
   void reportErrorForToken(ErrorCode errorCode, sc.Token token,
       [List<Object> arguments]) {
-    _errorListener.onError(new AnalysisError(
+    errorListener.onError(new AnalysisError(
         source, token.offset, token.length, errorCode, arguments));
   }
 
@@ -13243,13 +13342,13 @@
 
   @override
   List<InterfaceType> get nonSubtypableTypes => <InterfaceType>[
-    nullType,
-    numType,
-    intType,
-    doubleType,
-    boolType,
-    stringType
-  ];
+        nullType,
+        numType,
+        intType,
+        doubleType,
+        boolType,
+        stringType
+      ];
 
   @override
   DartObjectImpl get nullObject {
@@ -13380,7 +13479,7 @@
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
       {Scope nameScope})
       : super(definingLibrary, source, typeProvider, errorListener,
-          nameScope: nameScope) {
+            nameScope: nameScope) {
     _dynamicType = typeProvider.dynamicType;
     _undefinedType = typeProvider.undefinedType;
   }
@@ -13776,13 +13875,15 @@
                 (parent.parent as InstanceCreationExpression).isConst) {
               // If, if this is a const expression, then generate a
               // CompileTimeErrorCode.CONST_WITH_NON_TYPE error.
-              reportErrorForNode(CompileTimeErrorCode.CONST_WITH_NON_TYPE,
+              reportErrorForNode(
+                  CompileTimeErrorCode.CONST_WITH_NON_TYPE,
                   prefixedIdentifier.identifier,
                   [prefixedIdentifier.identifier.name]);
             } else {
               // Else, if this expression is a new expression, report a
               // NEW_WITH_NON_TYPE warning.
-              reportErrorForNode(StaticWarningCode.NEW_WITH_NON_TYPE,
+              reportErrorForNode(
+                  StaticWarningCode.NEW_WITH_NON_TYPE,
                   prefixedIdentifier.identifier,
                   [prefixedIdentifier.identifier.name]);
             }
@@ -13960,11 +14061,8 @@
           typeArguments[i] = argumentType;
         }
       } else {
-        reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node, [
-          typeName.name,
-          parameterCount,
-          argumentCount
-        ]);
+        reportErrorForNode(_getInvalidTypeParametersErrorCode(node), node,
+            [typeName.name, parameterCount, argumentCount]);
         for (int i = 0; i < parameterCount; i++) {
           typeArguments[i] = _dynamicType;
         }
@@ -14328,7 +14426,8 @@
   void _resolve(ClassElementImpl classElement, WithClause withClause,
       ImplementsClause implementsClause) {
     if (withClause != null) {
-      List<InterfaceType> mixinTypes = _resolveTypes(withClause.mixinTypes,
+      List<InterfaceType> mixinTypes = _resolveTypes(
+          withClause.mixinTypes,
           CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
           CompileTimeErrorCode.MIXIN_OF_ENUM,
           CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
@@ -14340,7 +14439,8 @@
     }
     if (implementsClause != null) {
       NodeList<TypeName> interfaces = implementsClause.interfaces;
-      List<InterfaceType> interfaceTypes = _resolveTypes(interfaces,
+      List<InterfaceType> interfaceTypes = _resolveTypes(
+          interfaces,
           CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
           CompileTimeErrorCode.IMPLEMENTS_ENUM,
           CompileTimeErrorCode.IMPLEMENTS_DYNAMIC);
@@ -14415,8 +14515,10 @@
    * @param dynamicTypeError the error to produce if the type name is "dynamic"
    * @return an array containing all of the types that were resolved.
    */
-  List<InterfaceType> _resolveTypes(NodeList<TypeName> typeNames,
-      ErrorCode nonTypeError, ErrorCode enumTypeError,
+  List<InterfaceType> _resolveTypes(
+      NodeList<TypeName> typeNames,
+      ErrorCode nonTypeError,
+      ErrorCode enumTypeError,
       ErrorCode dynamicTypeError) {
     List<InterfaceType> types = new List<InterfaceType>();
     for (TypeName typeName in typeNames) {
@@ -14648,10 +14750,8 @@
   @override
   visitClassElement(ClassElement element) {
     if (!_isUsedElement(element)) {
-      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
-        element.kind.displayName,
-        element.displayName
-      ]);
+      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+          [element.kind.displayName, element.displayName]);
     }
     super.visitClassElement(element);
   }
@@ -14668,10 +14768,8 @@
   @override
   visitFunctionElement(FunctionElement element) {
     if (!_isUsedElement(element)) {
-      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
-        element.kind.displayName,
-        element.displayName
-      ]);
+      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+          [element.kind.displayName, element.displayName]);
     }
     super.visitFunctionElement(element);
   }
@@ -14679,10 +14777,8 @@
   @override
   visitFunctionTypeAliasElement(FunctionTypeAliasElement element) {
     if (!_isUsedElement(element)) {
-      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
-        element.kind.displayName,
-        element.displayName
-      ]);
+      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+          [element.kind.displayName, element.displayName]);
     }
     super.visitFunctionTypeAliasElement(element);
   }
@@ -14705,10 +14801,8 @@
   @override
   visitMethodElement(MethodElement element) {
     if (!_isUsedMember(element)) {
-      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
-        element.kind.displayName,
-        element.displayName
-      ]);
+      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+          [element.kind.displayName, element.displayName]);
     }
     super.visitMethodElement(element);
   }
@@ -14716,10 +14810,8 @@
   @override
   visitPropertyAccessorElement(PropertyAccessorElement element) {
     if (!_isUsedMember(element)) {
-      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element, [
-        element.kind.displayName,
-        element.displayName
-      ]);
+      _reportErrorForElement(HintCode.UNUSED_ELEMENT, element,
+          [element.kind.displayName, element.displayName]);
     }
     super.visitPropertyAccessorElement(element);
   }
@@ -14779,8 +14871,11 @@
   void _reportErrorForElement(
       ErrorCode errorCode, Element element, List<Object> arguments) {
     if (element != null) {
-      _errorListener.onError(new AnalysisError(element.source,
-          element.nameOffset, element.displayName.length, errorCode,
+      _errorListener.onError(new AnalysisError(
+          element.source,
+          element.nameOffset,
+          element.displayName.length,
+          errorCode,
           arguments));
     }
   }
@@ -14908,7 +15003,7 @@
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
       {Scope nameScope})
       : super(definingLibrary, source, typeProvider, errorListener,
-          nameScope: nameScope);
+            nameScope: nameScope);
 
   /**
    * Initialize a newly created visitor to resolve the nodes in a compilation unit.
@@ -14923,8 +15018,8 @@
   VariableResolverVisitor.con1(
       Library library, Source source, TypeProvider typeProvider)
       : this(
-          library.libraryElement, source, typeProvider, library.errorListener,
-          nameScope: library.libraryScope);
+            library.libraryElement, source, typeProvider, library.errorListener,
+            nameScope: library.libraryScope);
 
   @override
   Object visitExportDirective(ExportDirective node) => null;
@@ -15033,11 +15128,14 @@
 
   List<ParameterElement> parameterElements;
 
-  _ConstantVerifier_validateInitializerExpression(TypeProvider typeProvider,
-      ErrorReporter errorReporter, this.verifier, this.parameterElements,
+  _ConstantVerifier_validateInitializerExpression(
+      TypeProvider typeProvider,
+      ErrorReporter errorReporter,
+      this.verifier,
+      this.parameterElements,
       DeclaredVariables declaredVariables)
       : super(new ConstantEvaluationEngine(typeProvider, declaredVariables),
-          errorReporter);
+            errorReporter);
 
   @override
   DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 9e028ca..0a9fa2a 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -1501,8 +1501,8 @@
         }
         recordStartOfLine();
       } else if (next == 0xA) {
-        recordStartOfLine();
         next = _reader.advance();
+        recordStartOfLine();
       } else {
         next = _reader.advance();
       }
@@ -2010,9 +2010,7 @@
   /**
    * Initialize a newly created token to have the given [type] and [offset].
    */
-  Token(this.type, int offset) {
-    this.offset = offset;
-  }
+  Token(this.type, this.offset);
 
   /**
    * Return the offset from the beginning of the file to the character after the
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 81c8a88..2b4fc6e 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -303,7 +303,7 @@
    * The short name of the library. This is the name used after 'dart:' in a
    * URI.
    */
-  String _shortName = null;
+  final String shortName;
 
   /**
    * The path to the file defining the library. The path is relative to the
@@ -337,9 +337,7 @@
    * Initialize a newly created library to represent the library with the given
    * [name].
    */
-  SdkLibraryImpl(String name) {
-    this._shortName = name;
-  }
+  SdkLibraryImpl(this.shortName);
 
   /**
    * Set whether the library is documented.
@@ -373,9 +371,6 @@
   @override
   bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0;
 
-  @override
-  String get shortName => _shortName;
-
   /**
    * Record that this library can be compiled to JavaScript by dart2js.
    */
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 5b96dbd..7db8cbe 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -109,7 +109,7 @@
   CustomUriResolver(this._urlMappings);
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     String mapping = _urlMappings[uri.toString()];
     if (mapping == null) return null;
 
@@ -117,7 +117,7 @@
     if (!fileUri.isAbsolute) return null;
 
     JavaFile javaFile = new JavaFile.fromUri(fileUri);
-    return new FileBasedSource(javaFile);
+    return new FileBasedSource(javaFile, actualUri != null ? actualUri : uri);
   }
 }
 
@@ -156,7 +156,7 @@
   DartSdk get dartSdk => _sdk;
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     if (!isDartUri(uri)) {
       return null;
     }
@@ -814,22 +814,30 @@
       }
       containedUri = containingSource.resolveRelativeUri(containedUri);
     }
-    // Now check .packages.
+
+    Uri actualUri = containedUri;
+
+    // Check .packages and update target and actual URIs as appropriate.
     if (_packages != null && containedUri.scheme == 'package') {
       Uri packageUri =
           _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
-      // Ensure scheme is set.
-      if (packageUri != null && packageUri.scheme == '') {
-        packageUri = packageUri.replace(scheme: 'file');
+
+      if (packageUri != null) {
+        // Ensure scheme is set.
+        if (packageUri.scheme == '') {
+          packageUri = packageUri.replace(scheme: 'file');
+        }
+        containedUri = packageUri;
       }
-      containedUri = packageUri;
     }
+
     for (UriResolver resolver in _resolvers) {
-      Source result = resolver.resolveAbsolute(containedUri);
+      Source result = resolver.resolveAbsolute(containedUri, actualUri);
       if (result != null) {
         return result;
       }
     }
+
     return null;
   }
 }
@@ -1062,9 +1070,10 @@
    * resolved because the URI is invalid.
    *
    * @param uri the URI to be resolved
+   * @param actualUri the actual uri for this source -- if `null`, the value of [uri] will be used
    * @return a [Source] representing the file to which given URI was resolved
    */
-  Source resolveAbsolute(Uri uri);
+  Source resolveAbsolute(Uri uri, [Uri actualUri]);
 
   /**
    * Return an absolute URI that represents the given source, or `null` if a valid URI cannot
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 9c40d74..fa32b4b 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -276,11 +276,12 @@
   static String FILE_SCHEME = "file";
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     if (!isFileUri(uri)) {
       return null;
     }
-    return new FileBasedSource(new JavaFile.fromUri(uri), uri);
+    return new FileBasedSource(
+        new JavaFile.fromUri(uri), actualUri != null ? actualUri : uri);
   }
 
   @override
@@ -290,7 +291,7 @@
     }
     return null;
   }
-  
+
   /**
    * Return `true` if the given URI is a `file` URI.
    *
@@ -425,7 +426,7 @@
   }
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     if (!isPackageUri(uri)) {
       return null;
     }
@@ -459,11 +460,13 @@
         if (_isSelfReference(packagesDirectory, canonicalFile)) {
           uri = canonicalFile.toURI();
         }
-        return new FileBasedSource(canonicalFile, uri);
+        return new FileBasedSource(
+            canonicalFile, actualUri != null ? actualUri : uri);
       }
     }
     return new FileBasedSource(
-        getCanonicalFile(_packagesDirectories[0], pkgName, relPath), uri);
+        getCanonicalFile(_packagesDirectories[0], pkgName, relPath),
+        actualUri != null ? actualUri : uri);
   }
 
   @override
@@ -537,7 +540,7 @@
       : super();
 
   @override
-  Source resolveAbsolute(Uri uri) {
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
     String rootPath = _rootDirectory.toURI().path;
     String uriPath = uri.path;
     if (uriPath != null && uriPath.startsWith(rootPath)) {
@@ -545,7 +548,7 @@
       for (JavaFile dir in _relativeDirectories) {
         JavaFile file = new JavaFile.relative(dir, filePath);
         if (file.exists()) {
-          return new FileBasedSource(file, uri);
+          return new FileBasedSource(file, actualUri != null ? actualUri : uri);
         }
       }
     }
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 4c2a537..d6a4c78 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -197,7 +197,8 @@
   }
 
   static ExportElementImpl exportFor(LibraryElement exportedLibrary,
-      [List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST]) {
+      [List<NamespaceCombinator> combinators =
+          NamespaceCombinator.EMPTY_LIST]) {
     ExportElementImpl spec = new ExportElementImpl(-1);
     spec.exportedLibrary = exportedLibrary;
     spec.combinators = combinators;
@@ -226,8 +227,9 @@
       setter.setter = true;
       setter.synthetic = true;
       setter.variable = field;
-      setter.parameters =
-          <ParameterElement>[requiredParameter2("_$name", type)];
+      setter.parameters = <ParameterElement>[
+        requiredParameter2("_$name", type)
+      ];
       setter.returnType = VoidTypeImpl.instance;
       setter.type = new FunctionTypeImpl(setter);
       field.setter = setter;
@@ -236,7 +238,8 @@
   }
 
   static FieldFormalParameterElementImpl fieldFormalParameter(
-      Identifier name) => new FieldFormalParameterElementImpl(name);
+          Identifier name) =>
+      new FieldFormalParameterElementImpl(name);
 
   static FunctionElementImpl functionElement(String functionName) =>
       functionElement4(functionName, null, null, null, null);
@@ -245,9 +248,11 @@
           String functionName, ClassElement returnElement) =>
       functionElement3(functionName, returnElement, null, null);
 
-  static FunctionElementImpl functionElement3(String functionName,
-      ClassElement returnElement, List<ClassElement> normalParameters,
-      List<ClassElement> optionalParameters) {
+  static FunctionElementImpl functionElement3(
+      String functionName,
+      ClassElement returnElement,
+      List<TypeDefiningElement> normalParameters,
+      List<TypeDefiningElement> optionalParameters) {
     // We don't create parameter elements because we don't have parameter names
     FunctionElementImpl functionElement =
         new FunctionElementImpl(functionName, 0);
@@ -281,9 +286,12 @@
     return functionElement;
   }
 
-  static FunctionElementImpl functionElement4(String functionName,
-      ClassElement returnElement, List<ClassElement> normalParameters,
-      List<String> names, List<ClassElement> namedParameters) {
+  static FunctionElementImpl functionElement4(
+      String functionName,
+      ClassElement returnElement,
+      List<ClassElement> normalParameters,
+      List<String> names,
+      List<ClassElement> namedParameters) {
     FunctionElementImpl functionElement =
         new FunctionElementImpl(functionName, 0);
     FunctionTypeImpl functionType = new FunctionTypeImpl(functionElement);
@@ -326,14 +334,19 @@
           String functionName, List<ClassElement> normalParameters) =>
       functionElement3(functionName, null, normalParameters, null);
 
-  static FunctionElementImpl functionElement6(String functionName,
-      List<ClassElement> normalParameters,
-      List<ClassElement> optionalParameters) => functionElement3(
+  static FunctionElementImpl functionElement6(
+          String functionName,
+          List<ClassElement> normalParameters,
+          List<ClassElement> optionalParameters) =>
+      functionElement3(
           functionName, null, normalParameters, optionalParameters);
 
-  static FunctionElementImpl functionElement7(String functionName,
-      List<ClassElement> normalParameters, List<String> names,
-      List<ClassElement> namedParameters) => functionElement4(
+  static FunctionElementImpl functionElement7(
+          String functionName,
+          List<ClassElement> normalParameters,
+          List<String> names,
+          List<ClassElement> namedParameters) =>
+      functionElement4(
           functionName, null, normalParameters, names, namedParameters);
 
   static FunctionElementImpl functionElementWithParameters(String functionName,
@@ -384,7 +397,8 @@
 
   static ImportElementImpl importFor(
       LibraryElement importedLibrary, PrefixElement prefix,
-      [List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST]) {
+      [List<NamespaceCombinator> combinators =
+          NamespaceCombinator.EMPTY_LIST]) {
     ImportElementImpl spec = new ImportElementImpl(0);
     spec.importedLibrary = importedLibrary;
     spec.prefix = prefix;
@@ -430,8 +444,10 @@
     return method;
   }
 
-  static MethodElementImpl methodElementWithParameters(String methodName,
-      List<DartType> typeArguments, DartType returnType,
+  static MethodElementImpl methodElementWithParameters(
+      String methodName,
+      List<DartType> typeArguments,
+      DartType returnType,
       List<ParameterElement> parameters) {
     MethodElementImpl method = new MethodElementImpl(methodName, 0);
     method.parameters = parameters;
@@ -548,8 +564,9 @@
       setter.static = true;
       setter.synthetic = true;
       setter.variable = variable;
-      setter.parameters =
-          <ParameterElement>[requiredParameter2("_$name", type)];
+      setter.parameters = <ParameterElement>[
+        requiredParameter2("_$name", type)
+      ];
       setter.returnType = VoidTypeImpl.instance;
       setter.type = new FunctionTypeImpl(setter);
       variable.setter = setter;
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index fa8daec..6e3f7a4 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -3219,7 +3219,8 @@
     // Use the ErrorVerifier to compute errors.
     //
     ErrorVerifier errorVerifier = new ErrorVerifier(errorReporter,
-        libraryElement, typeProvider, new InheritanceManager(libraryElement));
+        libraryElement, typeProvider, new InheritanceManager(libraryElement),
+        context.analysisOptions.enableSuperMixins);
     unit.accept(errorVerifier);
     //
     // Record outputs.
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 32c8bf7..77b064e 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.25.3-alpha.1
+version: 0.26.0
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index d941fcf..29e0b67 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -4,7 +4,6 @@
 
 library engine.compile_time_error_code_test;
 
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index af6dac3..13c0b66 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -2263,6 +2263,7 @@
       options.cacheSize = i;
       options.dart2jsHint = booleanValue;
       options.enableStrictCallChecks = booleanValue;
+      options.enableSuperMixins = booleanValue;
       options.generateImplicitErrors = booleanValue;
       options.generateSdkErrors = booleanValue;
       options.hint = booleanValue;
@@ -2274,6 +2275,7 @@
       expect(copy.cacheSize, options.cacheSize);
       expect(copy.dart2jsHint, options.dart2jsHint);
       expect(copy.enableStrictCallChecks, options.enableStrictCallChecks);
+      expect(copy.enableSuperMixins, options.enableSuperMixins);
       expect(copy.generateImplicitErrors, options.generateImplicitErrors);
       expect(copy.generateSdkErrors, options.generateSdkErrors);
       expect(copy.hint, options.hint);
@@ -2305,