Version 1.9.0-dev.2.0

svn merge -r 42237:42449 https://dart.googlecode.com/svn/branches/bleeding_edge trunk

git-svn-id: http://dart.googlecode.com/svn/trunk@42450 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 0d6ae79..fb5deb1 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -295,6 +295,7 @@
   "event": "server.status"
   "params": {
     "<b>analysis</b>": <span style="color:#999999">optional</span> <a href="#type_AnalysisStatus">AnalysisStatus</a>
+    "<b>pub</b>": <span style="color:#999999">optional</span> <a href="#type_PubStatus">PubStatus</a>
   }
 }</pre></div>
         <p>
@@ -316,6 +317,12 @@
               analysis is being performed and if so what is being
               analyzed.
             </p>
+          </dd><dt class="field"><b><i>pub ( <span style="color:#999999">optional</span> <a href="#type_PubStatus">PubStatus</a> )</i></b></dt><dd>
+            
+            <p>
+              The current status of pub execution, indicating whether we are
+              currently running pub.
+            </p>
           </dd></dl></dd></dl>
     <h2 class="domain"><a name="domain_analysis">Domain: analysis</a></h2>
       <p>
@@ -1934,6 +1941,7 @@
       
       
       
+      
     <dl><dt class="typeDefinition"><a name="type_AddContentOverlay">AddContentOverlay: object</a></dt><dd>
         <p>
           A directive to begin overlaying the contents of a file.  The
@@ -2753,6 +2761,17 @@
             <p>
               The offset of the position.
             </p>
+          </dd></dl></dd><dt class="typeDefinition"><a name="type_PubStatus">PubStatus: object</a></dt><dd>
+        <p>
+          An indication of the current state of pub execution.
+        </p>
+        
+      <dl><dt class="field"><b><i>isListingPackageDirs ( bool )</i></b></dt><dd>
+            
+            <p>
+              True if the server is currently running pub to produce a list of
+              package directories.
+            </p>
           </dd></dl></dd><dt class="typeDefinition"><a name="type_RefactoringKind">RefactoringKind: String</a></dt><dd>
         <p>
           An enumeration of the kinds of refactorings that can be
diff --git a/pkg/analysis_server/lib/driver.dart b/pkg/analysis_server/lib/driver.dart
index 08d7bfa..55616e9 100644
--- a/pkg/analysis_server/lib/driver.dart
+++ b/pkg/analysis_server/lib/driver.dart
@@ -12,6 +12,7 @@
 import 'package:analysis_server/src/socket_server.dart';
 import 'package:analysis_server/stdio_server.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/incremental_logger.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -57,10 +58,9 @@
   static const BINARY_NAME = "server";
 
   /**
-   * The name of the option used to enable incremental resolution.
+   * The name of the option used to set the identifier for the client.
    */
-  static const String ENABLE_INCREMENTAL_RESOLUTION =
-      "enable-incremental-resolution";
+  static const String CLIENT_ID = "client-id";
 
   /**
    * The name of the option used to enable incremental resolution of API
@@ -85,13 +85,6 @@
   static const String HELP_OPTION = "help";
 
   /**
-   * The name of the option used to specify the log file to which
-   * instrumentation data is to be written.
-   */
-  static const String INSTRUMENTATION_LOG_FILE_OPTION =
-      "instrumentation-log-file";
-
-  /**
    * The name of the option used to specify if [print] should print to the
    * console instead of being intercepted.
    */
@@ -132,11 +125,9 @@
    */
   void start(List<String> args) {
     ArgParser parser = new ArgParser();
-    parser.addFlag(
-        ENABLE_INCREMENTAL_RESOLUTION,
-        help: "enable using incremental resolution",
-        defaultsTo: false,
-        negatable: false);
+    parser.addOption(
+        CLIENT_ID,
+        help: "an identifier used to identify the client");
     parser.addFlag(
         ENABLE_INCREMENTAL_RESOLUTION_API,
         help: "enable using incremental resolution for API changes",
@@ -155,9 +146,6 @@
     parser.addOption(
         INCREMENTAL_RESOLUTION_LOG,
         help: "the description of the incremental resolotion log");
-    parser.addOption(
-        INSTRUMENTATION_LOG_FILE_OPTION,
-        help: "[path] the file to which instrumentation data will be logged");
     parser.addFlag(
         INTERNAL_PRINT_TO_CONSOLE,
         help: "enable sending `print` output to the console",
@@ -183,13 +171,6 @@
     // TODO(brianwilkerson) Enable this after it is possible for an
     // instrumentation server to be provided.
 //    if (results[ENABLE_INSTRUMENTATION_OPTION]) {
-////      if (results[INSTRUMENTATION_LOG_FILE_OPTION] != null) {
-////        // TODO(brianwilkerson) Initialize the instrumentation server with
-////        // logging.
-////      } else {
-////        // TODO(brianwilkerson) Initialize the instrumentation server without
-////        // logging.
-////      }
 //      if (instrumentationServer == null) {
 //        print('Exiting server: enabled instrumentation without providing an instrumentation server');
 //        print('');
@@ -221,8 +202,6 @@
     }
 
     AnalysisServerOptions analysisServerOptions = new AnalysisServerOptions();
-    analysisServerOptions.enableIncrementalResolution =
-        results[ENABLE_INCREMENTAL_RESOLUTION];
     analysisServerOptions.enableIncrementalResolutionApi =
         results[ENABLE_INCREMENTAL_RESOLUTION_API];
 
@@ -237,12 +216,12 @@
       defaultSdk = DirectoryBasedDartSdk.defaultSdk;
     }
 
-    socketServer = new SocketServer(
-        analysisServerOptions,
-        defaultSdk,
-        instrumentationServer == null ?
-            new NullInstrumentationServer() :
-            instrumentationServer);
+    InstrumentationService service =
+        new InstrumentationService(instrumentationServer);
+//    service.logVersion(results[CLIENT_ID], defaultSdk.sdkVersion);
+    AnalysisEngine.instance.instrumentationService = service;
+
+    socketServer = new SocketServer(analysisServerOptions, defaultSdk, service);
     httpServer = new HttpAnalysisServer(socketServer);
     stdioServer = new StdioAnalysisServer(socketServer);
 
@@ -255,6 +234,7 @@
         if (serve_http) {
           httpServer.close();
         }
+        service.shutdown();
         exit(0);
       });
     } else {
@@ -263,6 +243,7 @@
           if (serve_http) {
             httpServer.close();
           }
+          service.shutdown();
           exit(0);
         });
       }, httpServer.recordPrint);
diff --git a/pkg/analysis_server/lib/http_server.dart b/pkg/analysis_server/lib/http_server.dart
index 4d8780f..da5ba35 100644
--- a/pkg/analysis_server/lib/http_server.dart
+++ b/pkg/analysis_server/lib/http_server.dart
@@ -107,7 +107,8 @@
    * running an analysis server on a [WebSocket]-based communication channel.
    */
   void _handleWebSocket(WebSocket socket) {
-    socketServer.createAnalysisServer(new WebSocketServerChannel(socket));
+    socketServer.createAnalysisServer(
+        new WebSocketServerChannel(socket, socketServer.instrumentationService));
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 4e79eba..d9eb295 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -114,9 +114,9 @@
   final DartSdk defaultSdk;
 
   /**
-   * The instrumentation server that is to be used by this analysis server.
+   * The instrumentation service that is to be used by this analysis server.
    */
-  final InstrumentationServer instrumentationServer;
+  final InstrumentationService instrumentationService;
 
   /**
    * A table mapping [Folder]s to the [AnalysisContext]s associated with them.
@@ -191,13 +191,12 @@
   AnalysisServer(this.channel, this.resourceProvider,
       PackageMapProvider packageMapProvider, this.index,
       AnalysisServerOptions analysisServerOptions, this.defaultSdk,
-      this.instrumentationServer, {this.rethrowExceptions: true}) {
+      this.instrumentationService, {this.rethrowExceptions: true}) {
     searchEngine = createSearchEngine(index);
     operationQueue = new ServerOperationQueue(this);
     contextDirectoryManager =
         new ServerContextManager(this, resourceProvider, packageMapProvider);
-    contextDirectoryManager.defaultOptions.incremental =
-        analysisServerOptions.enableIncrementalResolution;
+    contextDirectoryManager.defaultOptions.incremental = true;
     contextDirectoryManager.defaultOptions.incrementalApi =
         analysisServerOptions.enableIncrementalResolutionApi;
     AnalysisEngine.instance.logger = new AnalysisLogger();
@@ -298,7 +297,7 @@
   AnalysisContext getAnalysisContextForSource(Source source) {
     for (AnalysisContext context in folderMap.values) {
       SourceKind kind = context.getKindOf(source);
-      if (kind != null) {
+      if (kind != SourceKind.UNKNOWN) {
         return context;
       }
     }
@@ -820,8 +819,12 @@
       index.clear();
       index.stop();
     }
-    // Defer closing the channel so that the shutdown response can be sent.
-    new Future(channel.close);
+    // Defer closing the channel and shutting down the instrumentation server so
+    // that the shutdown response can be sent and logged.
+    new Future(() {
+      instrumentationService.shutdown();
+      channel.close();
+    });
   }
 
   /**
@@ -932,7 +935,6 @@
 
 
 class AnalysisServerOptions {
-  bool enableIncrementalResolution = false;
   bool enableIncrementalResolutionApi = false;
 }
 
@@ -1020,6 +1022,16 @@
   }
 
   @override
+  void beginComputePackageMap() {
+    _computingPackageMap(true);
+  }
+
+  @override
+  void endComputePackageMap() {
+    _computingPackageMap(false);
+  }
+
+  @override
   void removeContext(Folder folder) {
     AnalysisContext context = analysisServer.folderMap.remove(folder);
     if (analysisServer.index != null) {
@@ -1030,6 +1042,7 @@
     analysisServer.sendContextAnalysisDoneNotifications(
         context,
         AnalysisDoneReason.CONTEXT_REMOVED);
+    context.dispose();
   }
 
   @override
@@ -1042,6 +1055,14 @@
     analysisServer.schedulePerformAnalysisOperation(context);
   }
 
+  void _computingPackageMap(bool computing) {
+    if (analysisServer.serverServices.contains(ServerService.STATUS)) {
+      PubStatus pubStatus = new PubStatus(computing);
+      ServerStatusParams params = new ServerStatusParams(pub: pubStatus);
+      analysisServer.sendNotification(params.toNotification());
+    }
+  }
+
   /**
    * Set up a [SourceFactory] that resolves packages using the given
    * [packageUriResolver].
diff --git a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
index 2953701..bcb86cc 100644
--- a/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/byte_stream_channel.dart
@@ -10,6 +10,7 @@
 
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/protocol.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
 
 /**
  * Instances of the class [ByteStreamClientChannel] implement a
@@ -87,6 +88,11 @@
   final IOSink _output;
 
   /**
+   * The instrumentation service that is to be used by this analysis server.
+   */
+  final InstrumentationService instrumentationService;
+
+  /**
    * Completer that will be signalled when the input stream is closed.
    */
   final Completer _closed = new Completer();
@@ -107,7 +113,8 @@
    */
   bool _closeRequested = false;
 
-  ByteStreamServerChannel(this.input, this._output);
+  ByteStreamServerChannel(this.input, this._output,
+      this.instrumentationService);
 
   /**
    * Future that will be completed when the input stream is closed.
@@ -155,6 +162,7 @@
     String jsonEncoding = JSON.encode(notification.toJson());
     ServerCommunicationChannel.ToJson.stop();
     _outputLine(jsonEncoding);
+    instrumentationService.logNotification(jsonEncoding);
   }
 
   @override
@@ -168,6 +176,7 @@
     String jsonEncoding = JSON.encode(response.toJson());
     ServerCommunicationChannel.ToJson.stop();
     _outputLine(jsonEncoding);
+    instrumentationService.logResponse(jsonEncoding);
   }
 
   /**
@@ -225,6 +234,7 @@
     if (_closed.isCompleted) {
       return;
     }
+    instrumentationService.logRequest(data);
     // Parse the string as a JSON descriptor and process the resulting
     // structure as a request.
     ServerCommunicationChannel.FromJson.start();
diff --git a/pkg/analysis_server/lib/src/channel/channel.dart b/pkg/analysis_server/lib/src/channel/channel.dart
index 71ee75e..046a7c3 100644
--- a/pkg/analysis_server/lib/src/channel/channel.dart
+++ b/pkg/analysis_server/lib/src/channel/channel.dart
@@ -8,6 +8,7 @@
 import 'dart:convert';
 
 import 'package:analysis_server/src/protocol.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/util/utilities_timing.dart';
 
 /**
diff --git a/pkg/analysis_server/lib/src/channel/web_socket_channel.dart b/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
index 8dfcb5c..b8ddf6d 100644
--- a/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
+++ b/pkg/analysis_server/lib/src/channel/web_socket_channel.dart
@@ -10,6 +10,7 @@
 
 import 'package:analysis_server/src/channel/channel.dart';
 import 'package:analysis_server/src/protocol.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
 
 
 /**
@@ -72,9 +73,14 @@
   final WebSocket socket;
 
   /**
+   * The instrumentation service that is to be used by this analysis server.
+   */
+  final InstrumentationService instrumentationService;
+
+  /**
    * Initialize a newly create [WebSocket] wrapper to wrap the given [socket].
    */
-  WebSocketServerChannel(this.socket);
+  WebSocketServerChannel(this.socket, this.instrumentationService);
 
   @override
   void close() {
@@ -96,6 +102,7 @@
    */
   void readRequest(Object data, void onRequest(Request request)) {
     if (data is String) {
+      instrumentationService.logRequest(data);
       // Parse the string as a JSON descriptor and process the resulting
       // structure as a request.
       ServerCommunicationChannel.FromJson.start();
@@ -120,6 +127,7 @@
     String jsonEncoding = JSON.encode(notification.toJson());
     ServerCommunicationChannel.ToJson.stop();
     socket.add(jsonEncoding);
+    instrumentationService.logNotification(jsonEncoding);
   }
 
   @override
@@ -128,5 +136,6 @@
     String jsonEncoding = JSON.encode(response.toJson());
     ServerCommunicationChannel.ToJson.stop();
     socket.add(jsonEncoding);
+    instrumentationService.logResponse(jsonEncoding);
   }
 }
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 02ac219..38c3c2d 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -97,6 +97,20 @@
   void applyChangesToContext(Folder contextFolder, ChangeSet changeSet);
 
   /**
+   * We are about to start computing the package map.
+   */
+  void beginComputePackageMap() {
+    // Do nothing.
+  }
+
+  /**
+   * We have finished computing the package map.
+   */
+  void endComputePackageMap() {
+    // Do nothing.
+  }
+
+  /**
    * Returns `true` if the given absolute [path] is in one of the current
    * root folders and is not excluded.
    */
@@ -306,8 +320,10 @@
       packageUriResolver =
           new PackageUriResolver([new JavaFile(info.packageRoot)]);
     } else {
+      beginComputePackageMap();
       PackageMapInfo packageMapInfo =
           _packageMapProvider.computePackageMap(folder);
+      endComputePackageMap();
       info.packageMapDependencies = packageMapInfo.dependencies;
       packageUriResolver =
           new PackageMapUriResolver(resourceProvider, packageMapInfo.packageMap);
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index 1c8ece0..06c5188 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -49,6 +49,24 @@
   CompletionPerformance performance;
 
   /**
+   * A list of code completion peformance measurements for the latest
+   * completion operation up to [performanceListMaxLength] measurements.
+   */
+  final List<CompletionPerformance> performanceList =
+      new List<CompletionPerformance>();
+
+  /**
+   * The maximum number of performance measurements to keep.
+   * This defaults to zero for efficiency, but clients may change this.
+   */
+  int performanceListMaxLength = 0;
+
+  /**
+   * Performance for the last priority change event.
+   */
+  CompletionPerformance priorityChangedPerformance;
+
+  /**
    * Initialize a new request handler for the given [server].
    */
   CompletionDomainHandler(this.server) {
@@ -119,14 +137,23 @@
    */
   void priorityChanged(PriorityChangeEvent event) {
     Source source = event.firstSource;
-    if (source == null) {
-      return;
+    priorityChangedPerformance = new CompletionPerformance();
+    priorityChangedPerformance.source = source;
+    if (source != null) {
+      AnalysisContext context = server.getAnalysisContextForSource(source);
+      if (context != null) {
+        String computeTag = 'computeCache';
+        priorityChangedPerformance.logStartTime(computeTag);
+        CompletionManager manager = completionManagerFor(context, source);
+        manager.computeCache().then((bool success) {
+          priorityChangedPerformance.logElapseTime(computeTag);
+          priorityChangedPerformance.complete(
+              'priorityChanged caching: $success');
+        });
+        return;
+      }
     }
-    AnalysisContext context = server.getAnalysisContextForSource(source);
-    if (context == null) {
-      return;
-    }
-    completionManagerFor(context, source).computeCache();
+    priorityChangedPerformance.complete();
   }
 
   /**
@@ -139,19 +166,26 @@
         new CompletionGetSuggestionsParams.fromRequest(request);
     // schedule completion analysis
     String completionId = (_nextCompletionId++).toString();
-    CompletionManager manager = completionManagerFor(
-        server.getAnalysisContext(params.file),
-        server.getSource(params.file));
+    AnalysisContext context = server.getAnalysisContext(params.file);
+    Source source = server.getSource(params.file);
+    recordRequest(performance, context, source, params.offset);
+    CompletionManager manager = completionManagerFor(context, source);
     CompletionRequest completionRequest =
         new CompletionRequest(params.offset, performance);
+    int notificationCount = 0;
     manager.results(completionRequest).listen((CompletionResult result) {
-      sendCompletionNotification(
-          completionId,
-          result.replacementOffset,
-          result.replacementLength,
-          result.suggestions,
-          result.last);
+      ++notificationCount;
+      performance.logElapseTime("notification $notificationCount", () {
+        sendCompletionNotification(
+            completionId,
+            result.replacementOffset,
+            result.replacementLength,
+            result.suggestions,
+            result.last);
+      });
       if (result.last) {
+        performance.notificationCount = notificationCount;
+        performance.suggestionCount = result.suggestions.length;
         performance.complete();
       }
     });
@@ -161,6 +195,32 @@
   }
 
   /**
+   * If tracking code completion performance over time, then
+   * record addition information about the request in the performance record.
+   */
+  void recordRequest(CompletionPerformance performance, AnalysisContext context,
+      Source source, int offset) {
+    performance.source = source;
+    performance.offset = offset;
+    if (priorityChangedPerformance != null &&
+        priorityChangedPerformance.source != source) {
+      priorityChangedPerformance = null;
+    }
+    if (performanceListMaxLength == 0 || context == null || source == null) {
+      return;
+    }
+    TimestampedData<String> data = context.getContents(source);
+    if (data == null) {
+      return;
+    }
+    performance.contents = data.data;
+    while (performanceList.length >= performanceListMaxLength) {
+      performanceList.removeAt(0);
+    }
+    performanceList.add(performance);
+  }
+
+  /**
    * Send completion notification results.
    */
   void sendCompletionNotification(String completionId, int replacementOffset,
@@ -205,6 +265,9 @@
       _sourcesChangedSubscription.cancel();
       _sourcesChangedSubscription = null;
     }
-    _manager = null;
+    if (_manager != null) {
+      _manager.dispose();
+      _manager = null;
+    }
   }
 }
diff --git a/pkg/analysis_server/lib/src/domain_server.dart b/pkg/analysis_server/lib/src/domain_server.dart
index bdd2266..607fb3d 100644
--- a/pkg/analysis_server/lib/src/domain_server.dart
+++ b/pkg/analysis_server/lib/src/domain_server.dart
@@ -58,59 +58,6 @@
     return new ServerSetSubscriptionsResult().toResponse(request.id);
   }
 
-  // TODO(scheglov) remove or move to the 'analysis' domain
-//  /**
-//   * Create a new context in which analysis can be performed. The context that
-//   * is created will persist until server.deleteContext is used to delete it.
-//   * Clients, therefore, are responsible for managing the lifetime of contexts.
-//   */
-//  Response createContext(Request request) {
-//    String sdkDirectory = request.getRequiredParameter(SDK_DIRECTORY_PARAM).asString();
-//    Map<String, String> packageMap = request.getParameter(PACKAGE_MAP_PARAM, {}).asStringMap();
-//
-//    String contextId = request.getRequiredParameter(AnalysisServer.CONTEXT_ID_PARAM).asString();
-//    if (server.contextMap.containsKey(contextId)) {
-//      return new Response.contextAlreadyExists(request);
-//    }
-//    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
-//    // TODO(brianwilkerson) Use the information from the request to set the
-//    // source factory in the context.
-//    DirectoryBasedDartSdk sdk;
-//    try {
-//      sdk = new DirectoryBasedDartSdk(new JavaFile(sdkDirectory));
-//    } on Exception catch (e) {
-//      // TODO what error code should be returned here?
-//      return new Response(request.id, new RequestError(
-//          RequestError.CODE_SDK_ERROR, 'Failed to access sdk: $e'));
-//    }
-//    context.sourceFactory = new SourceFactory([
-//      new DartUriResolver(sdk),
-//      new FileUriResolver(),
-//      // new PackageUriResolver(),
-//    ]);
-//    server.contextMap[contextId] = context;
-//    server.contextIdMap[context] = contextId;
-//
-//    Response response = new Response(request.id);
-//    return response;
-//  }
-//
-//  /**
-//   * Delete the context with the given id. Future attempts to use the context id
-//   * will result in an error being returned.
-//   */
-//  Response deleteContext(Request request) {
-//    String contextId = request.getRequiredParameter(AnalysisServer.CONTEXT_ID_PARAM).asString();
-//
-//    AnalysisContext removedContext = server.contextMap.remove(contextId);
-//    if (removedContext == null) {
-//      return new Response.contextDoesNotExist(request);
-//    }
-//    server.contextIdMap.remove(removedContext);
-//    Response response = new Response(request.id);
-//    return response;
-//  }
-
   /**
    * Cleanly shutdown the analysis server.
    */
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index ad08575..eb4bbf4 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -254,6 +254,7 @@
     var params = new EditGetRefactoringParams.fromRequest(request);
     _init(params.kind, params.file, params.offset, params.length).then((_) {
       if (initStatus.hasFatalError) {
+        feedback = null;
         return _sendResultResponse();
       }
       // set options
@@ -453,9 +454,7 @@
   }
 
   void _sendResultResponse() {
-    if (feedback != null) {
-      result.feedback = feedback;
-    }
+    result.feedback = feedback;
     // set problems
     result.initialProblems = initStatus.problems;
     result.optionsProblems = optionsStatus.problems;
diff --git a/pkg/analysis_server/lib/src/generated_protocol.dart b/pkg/analysis_server/lib/src/generated_protocol.dart
index fcbabc5..1ed8d63 100644
--- a/pkg/analysis_server/lib/src/generated_protocol.dart
+++ b/pkg/analysis_server/lib/src/generated_protocol.dart
@@ -348,6 +348,7 @@
  *
  * {
  *   "analysis": optional AnalysisStatus
+ *   "pub": optional PubStatus
  * }
  */
 class ServerStatusParams implements HasToJson {
@@ -357,7 +358,13 @@
    */
   AnalysisStatus analysis;
 
-  ServerStatusParams({this.analysis});
+  /**
+   * The current status of pub execution, indicating whether we are currently
+   * running pub.
+   */
+  PubStatus pub;
+
+  ServerStatusParams({this.analysis, this.pub});
 
   factory ServerStatusParams.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
     if (json == null) {
@@ -368,7 +375,11 @@
       if (json.containsKey("analysis")) {
         analysis = new AnalysisStatus.fromJson(jsonDecoder, jsonPath + ".analysis", json["analysis"]);
       }
-      return new ServerStatusParams(analysis: analysis);
+      PubStatus pub;
+      if (json.containsKey("pub")) {
+        pub = new PubStatus.fromJson(jsonDecoder, jsonPath + ".pub", json["pub"]);
+      }
+      return new ServerStatusParams(analysis: analysis, pub: pub);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "server.status params");
     }
@@ -384,6 +395,9 @@
     if (analysis != null) {
       result["analysis"] = analysis.toJson();
     }
+    if (pub != null) {
+      result["pub"] = pub.toJson();
+    }
     return result;
   }
 
@@ -397,7 +411,8 @@
   @override
   bool operator==(other) {
     if (other is ServerStatusParams) {
-      return analysis == other.analysis;
+      return analysis == other.analysis &&
+          pub == other.pub;
     }
     return false;
   }
@@ -406,6 +421,7 @@
   int get hashCode {
     int hash = 0;
     hash = _JenkinsSmiHash.combine(hash, analysis.hashCode);
+    hash = _JenkinsSmiHash.combine(hash, pub.hashCode);
     return _JenkinsSmiHash.finish(hash);
   }
 }
@@ -8155,6 +8171,64 @@
 }
 
 /**
+ * PubStatus
+ *
+ * {
+ *   "isListingPackageDirs": bool
+ * }
+ */
+class PubStatus implements HasToJson {
+  /**
+   * True if the server is currently running pub to produce a list of package
+   * directories.
+   */
+  bool isListingPackageDirs;
+
+  PubStatus(this.isListingPackageDirs);
+
+  factory PubStatus.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
+    if (json == null) {
+      json = {};
+    }
+    if (json is Map) {
+      bool isListingPackageDirs;
+      if (json.containsKey("isListingPackageDirs")) {
+        isListingPackageDirs = jsonDecoder._decodeBool(jsonPath + ".isListingPackageDirs", json["isListingPackageDirs"]);
+      } else {
+        throw jsonDecoder.missingKey(jsonPath, "isListingPackageDirs");
+      }
+      return new PubStatus(isListingPackageDirs);
+    } else {
+      throw jsonDecoder.mismatch(jsonPath, "PubStatus");
+    }
+  }
+
+  Map<String, dynamic> toJson() {
+    Map<String, dynamic> result = {};
+    result["isListingPackageDirs"] = isListingPackageDirs;
+    return result;
+  }
+
+  @override
+  String toString() => JSON.encode(toJson());
+
+  @override
+  bool operator==(other) {
+    if (other is PubStatus) {
+      return isListingPackageDirs == other.isListingPackageDirs;
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    int hash = 0;
+    hash = _JenkinsSmiHash.combine(hash, isListingPackageDirs.hashCode);
+    return _JenkinsSmiHash.finish(hash);
+  }
+}
+
+/**
  * RefactoringKind
  *
  * enum {
diff --git a/pkg/analysis_server/lib/src/get_handler.dart b/pkg/analysis_server/lib/src/get_handler.dart
index 96a000b..ebdac828f 100644
--- a/pkg/analysis_server/lib/src/get_handler.dart
+++ b/pkg/analysis_server/lib/src/get_handler.dart
@@ -327,6 +327,7 @@
    */
   void _returnCompletionInfo(HttpRequest request) {
     var refresh = request.requestedUri.queryParameters['refresh'];
+    var maxCount = request.requestedUri.queryParameters['maxCount'];
     HttpResponse response = request.response;
     response.statusCode = HttpStatus.OK;
     response.headers.add(HttpHeaders.CONTENT_TYPE, "text/html");
@@ -342,12 +343,14 @@
     }
     response.write('</head>');
     response.write('<body>');
-    _writeCompletionInfo(response);
-    response.write('<form>');
-    response.write(
-        '<input type="button" onClick="history.go(0)" value="Refresh">');
-    response.write('</form>');
-    response.write('<p>Append "?refresh=5" to refresh every 5 seconds</p>');
+    _writeCompletionInfo(response, maxCount);
+    response.write('<p>&nbsp</p>');
+    response.write('<p>Try ');
+    response.write('<a href="?refresh=5">?refresh=5</a>');
+    response.write(' to refresh every 5 seconds</p>');
+    response.write('<p>and ');
+    response.write('<a href="?maxCount=50">?maxCount=50</a>');
+    response.write(' to keep the last 50 performance measurements</p>');
     response.write('</body>');
     response.write('</html>');
     response.close();
@@ -491,7 +494,7 @@
   /**
    * Append code completion information.
    */
-  void _writeCompletionInfo(HttpResponse response) {
+  void _writeCompletionInfo(HttpResponse response, maxCount) {
     response.write('<h1>Code Completion</h1>');
     AnalysisServer analysisServer = _server.analysisServer;
     if (analysisServer == null) {
@@ -505,19 +508,52 @@
       response.write('<p>No code completion</p>');
       return;
     }
+    if (maxCount is String) {
+      int count = int.parse(maxCount, onError: (_) => 0);
+      handler.performanceListMaxLength = count;
+    }
     CompletionPerformance performance = handler.performance;
     if (performance == null) {
       response.write('<p>No performance stats yet</p>');
       return;
     }
-    response.write('<h2>Performance</h2>');
     response.write('<table>');
     _writeRow(response, ['Elapsed', '', 'Operation'], header: true);
     performance.operations.forEach((OperationPerformance op) {
       String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
       _writeRow(response, [elapsed, '&nbsp;&nbsp;', op.name]);
     });
+    if (handler.priorityChangedPerformance == null) {
+      response.write('<p>No priorityChanged caching</p>');
+    } else {
+      int len = handler.priorityChangedPerformance.operations.length;
+      if (len > 0) {
+        var op = handler.priorityChangedPerformance.operations[len - 1];
+        if (op != null) {
+          _writeRow(response, ['&nbsp;', '&nbsp;', '&nbsp;']);
+          String elapsed = op.elapsed != null ? op.elapsed.toString() : '???';
+          _writeRow(response, [elapsed, '&nbsp;&nbsp;', op.name]);
+        }
+      }
+    }
     response.write('</table>');
+    if (handler.performanceList.length > 0) {
+      response.write('<table>');
+      _writeRow(response, ['Milliseconds', '', '# Notifications', '', '# Suggestions', '', 'Snippet'], header: true);
+      handler.performanceList.forEach((CompletionPerformance performance) {
+        _writeRow(
+            response,
+            [
+                performance.elapsedInMilliseconds,
+                '&nbsp;&nbsp;',
+                performance.notificationCount,
+                '&nbsp;&nbsp;',
+                performance.suggestionCount,
+                '&nbsp;&nbsp;',
+                performance.snippet]);
+      });
+      response.write('</table>');
+    }
   }
 
   /**
diff --git a/pkg/analysis_server/lib/src/services/completion/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
index 4ffb40b..a8d16db 100644
--- a/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/completion_manager.dart
@@ -75,8 +75,11 @@
    * completion request sometime in the future. The default implementation
    * of this method does nothing. Subclasses may override but should not
    * count on this method being called before [computeSuggestions].
+   * Return a future that completes when the cache is computed with a bool
+   * indicating success.
    */
-  void computeCache() {
+  Future<bool> computeCache() {
+    return new Future.value(true);
   }
 
   /**
@@ -89,6 +92,13 @@
   void computeSuggestions(CompletionRequest request);
 
   /**
+   * Discard any pending operations.
+   * Subclasses may override but should call super.dispose
+   */
+  void dispose() {
+  }
+
+  /**
    * Generate a stream of code completion results.
    */
   Stream<CompletionResult> results(CompletionRequest request) {
@@ -109,13 +119,47 @@
   final Stopwatch _stopwatch = new Stopwatch();
   final List<OperationPerformance> operations = <OperationPerformance>[];
 
+  Source source;
+  int offset;
+  String contents;
+  int notificationCount = -1;
+  int suggestionCount = -1;
+
   CompletionPerformance() {
     _stopwatch.start();
   }
 
-  void complete() {
+  int get elapsedInMilliseconds =>
+      operations.length > 0 ? operations.last.elapsed.inMilliseconds : 0;
+
+  String get snippet {
+    if (contents == null || offset < 0 || contents.length < offset) {
+      return '???';
+    }
+    int start = offset;
+    while (start > 0) {
+      String ch = contents[start - 1];
+      if (ch == '\r' || ch == '\n') {
+        break;
+      }
+      --start;
+    }
+    int end = offset;
+    while (end < contents.length) {
+      String ch = contents[end];
+      if (ch == '\r' || ch == '\n') {
+        break;
+      }
+      ++end;
+    }
+    String prefix = contents.substring(start, offset);
+    String suffix = contents.substring(offset, end);
+    return '$prefix^$suffix';
+  }
+
+  void complete([String tag = null]) {
     _stopwatch.stop();
-    _logDuration('total time', _stopwatch.elapsed);
+    _logDuration(tag != null ? tag : 'total time', _stopwatch.elapsed);
   }
 
   logElapseTime(String tag, [f() = null]) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
index 87ae27c..f1e7198 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart_completion_cache.dart
@@ -66,6 +66,11 @@
    */
   Map<String, ClassElement> importedClassMap;
 
+  /**
+   * The [ClassElement] for Object.
+   */
+  ClassElement _objectClassElement;
+
   DartCompletionCache(AnalysisContext context, Source source)
       : super(context, source);
 
@@ -132,6 +137,7 @@
       }
       addSuggestion(elem, CompletionRelevance.DEFAULT);
     });
+    _objectClassElement = importedClassMap['Object'];
 
     /*
      * Don't wait for search of lower relevance results to complete.
@@ -159,6 +165,20 @@
   }
 
   /**
+   * Return the [ClassElement] for Object.
+   */
+  ClassElement get objectClassElement {
+    if (_objectClassElement == null) {
+      Source coreUri = context.sourceFactory.forUri('dart:core');
+      LibraryElement coreLib = context.getLibraryElement(coreUri);
+      Namespace coreNamespace =
+          new NamespaceBuilder().createPublicNamespaceForLibrary(coreLib);
+      _objectClassElement = coreNamespace.definedNames['Object'];
+    }
+    return _objectClassElement;
+  }
+
+  /**
    * Return `true` if the import information is cached for the given
    * compilation unit.
    */
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 e2c9cdc..5426d29 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
@@ -15,9 +15,9 @@
 import 'package:analysis_server/src/services/completion/invocation_computer.dart';
 import 'package:analysis_server/src/services/completion/keyword_computer.dart';
 import 'package:analysis_server/src/services/completion/local_computer.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
 import 'package:analyzer/src/generated/ast.dart';
-import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
 
@@ -76,10 +76,12 @@
   }
 
   @override
-  void computeCache() {
-    waitForAnalysis().then((CompilationUnit unit) {
+  Future<bool> computeCache() {
+    return waitForAnalysis().then((CompilationUnit unit) {
       if (unit != null && !cache.isImportInfoCached(unit)) {
-        cache.computeImportInfo(unit, searchEngine);
+        return cache.computeImportInfo(unit, searchEngine);
+      } else {
+        return new Future.value(false);
       }
     });
   }
@@ -182,27 +184,18 @@
   }
 
   /**
-   * Return a future that completes when analysis is complete.
+   * Return a future that either (a) completes with the resolved compilation
+   * unit when analysis is complete, or (b) completes with null if the
+   * compilation unit is never going to be resolved.
    */
-  Future<CompilationUnit> waitForAnalysis([int waitCount = 10000]) {
-    //TODO (danrubel) replace this when new API is ready.
-    // I expect the new API to be either a stream of resolution events
-    // or a future that completes when the resolved library element is available
-    LibraryElement library = context.getLibraryElement(source);
-    if (library != null) {
-      CompilationUnit unit =
-          context.getResolvedCompilationUnit(source, library);
-      if (unit != null) {
-        return new Future.value(unit);
-      }
-    }
-    //TODO (danrubel) Remove this HACK
-    if (waitCount > 0) {
-      return new Future(() {
-        return waitForAnalysis(waitCount - 1);
-      });
-    }
-    return new Future.value(null);
+  Future<CompilationUnit> waitForAnalysis() {
+    return context.computeResolvedCompilationUnitAsync(
+        source,
+        source).catchError((_) {
+      // This source file is not scheduled for analysis, so a resolved
+      // compilation unit is never going to get computed.
+      return null;
+    }, test: (e) => e is AnalysisNotScheduledError);
   }
 }
 
@@ -245,6 +238,11 @@
   AstNode node;
 
   /**
+   * Information about the types of suggestions that should be included.
+   */
+  OpType _optype;
+
+  /**
    * The offset of the start of the text to be replaced.
    * This will be different than the offset used to request the completion
    * suggestions if there was a portion of an identifier before the original
@@ -268,6 +266,26 @@
   DartCompletionRequest(this.context, this.searchEngine, this.source,
       int offset, this.cache, CompletionPerformance performance)
       : super(offset, performance);
+
+  /**
+   * Return the original text from the [replacementOffset] to the [offset]
+   * that can be used to filter the suggestions on the server side.
+   */
+  String get filterText {
+    return context.getContents(
+        source).data.substring(replacementOffset, offset);
+  }
+
+  /**
+   * Information about the types of suggestions that should be included.
+   * This will return `null` if the [node] has not been set.
+   */
+  OpType get optype {
+    if (_optype == null && node != null) {
+      _optype = new OpType.forCompletion(node, offset);
+    }
+    return _optype;
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/completion/imported_computer.dart b/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
index a74910c..0d39c0b 100644
--- a/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/imported_computer.dart
@@ -11,10 +11,10 @@
     ElementKind;
 import 'package:analysis_server/src/services/completion/dart_completion_cache.dart';
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
 import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/scanner.dart';
 
 /**
  * A computer for calculating imported class and top level variable
@@ -28,8 +28,12 @@
 
   @override
   bool computeFast(DartCompletionRequest request) {
-    builder = request.node.accept(new _ImportedAstVisitor(request));
-    if (builder != null) {
+    OpType optype = request.optype;
+    if (optype.includeTopLevelSuggestions) {
+      builder = new _ImportedSuggestionBuilder(
+          request,
+          typesOnly: optype.includeOnlyTypeNameSuggestions,
+          excludeVoidReturn: !optype.includeVoidReturnSuggestions);
       builder.shouldWaitForLowPrioritySuggestions =
           shouldWaitForLowPrioritySuggestions;
       return builder.computeFast(request.node);
@@ -47,171 +51,6 @@
 }
 
 /**
- * [_ImportedAstVisitor] determines whether an import suggestions are needed
- * and instantiates the builder to create those suggestions.
- */
-class _ImportedAstVisitor extends
-    GeneralizingAstVisitor<_ImportedSuggestionBuilder> {
-  final DartCompletionRequest request;
-
-  _ImportedAstVisitor(this.request);
-
-  @override
-  _ImportedSuggestionBuilder visitArgumentList(ArgumentList node) {
-    return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitBlock(Block node) {
-    return new _ImportedSuggestionBuilder(request);
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitCascadeExpression(CascadeExpression node) {
-    // Make suggestions for the target, but not for the selector
-    // InvocationComputer makes selector suggestions
-    Expression target = node.target;
-    if (target != null && request.offset <= target.end) {
-      return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitClassDeclaration(ClassDeclaration node) {
-    // Make suggestions in the body of the class declaration
-    Token leftBracket = node.leftBracket;
-    if (leftBracket != null && request.offset >= leftBracket.end) {
-      return new _ImportedSuggestionBuilder(request);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitExpression(Expression node) {
-    return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-  }
-
-  @override
-  _ImportedSuggestionBuilder
-      visitExpressionStatement(ExpressionStatement node) {
-    Expression expression = node.expression;
-    // A pre-variable declaration (e.g. C ^) is parsed as an expression
-    // statement. Do not make suggestions for the variable name.
-    if (expression is SimpleIdentifier && request.offset <= expression.end) {
-      return new _ImportedSuggestionBuilder(request);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder
-      visitFormalParameterList(FormalParameterList node) {
-    Token leftParen = node.leftParenthesis;
-    if (leftParen != null && request.offset > leftParen.offset) {
-      Token rightParen = node.rightParenthesis;
-      if (rightParen == null || request.offset <= rightParen.offset) {
-        return new _ImportedSuggestionBuilder(request);
-      }
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitForStatement(ForStatement node) {
-    Token leftParen = node.leftParenthesis;
-    if (leftParen != null && request.offset >= leftParen.end) {
-      return new _ImportedSuggestionBuilder(request);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitIfStatement(IfStatement node) {
-    Token leftParen = node.leftParenthesis;
-    if (leftParen != null && request.offset >= leftParen.end) {
-      Token rightParen = node.rightParenthesis;
-      if (rightParen == null || request.offset <= rightParen.offset) {
-        return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-      }
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder
-      visitInterpolationExpression(InterpolationExpression node) {
-    Expression expression = node.expression;
-    if (expression is SimpleIdentifier) {
-      return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitMethodInvocation(MethodInvocation node) {
-    Token period = node.period;
-    if (period == null || request.offset <= period.offset) {
-      return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitNode(AstNode node) {
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
-    // Make suggestions for the prefix, but not for the selector
-    // InvocationComputer makes selector suggestions
-    Token period = node.period;
-    if (period != null && request.offset <= period.offset) {
-      return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitPropertyAccess(PropertyAccess node) {
-    // Make suggestions for the target, but not for the property name
-    // InvocationComputer makes property name suggestions
-    var operator = node.operator;
-    if (operator != null && request.offset < operator.offset) {
-      return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-    }
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitSimpleIdentifier(SimpleIdentifier node) {
-    return node.parent.accept(this);
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitStringLiteral(StringLiteral node) {
-    return null;
-  }
-
-  @override
-  _ImportedSuggestionBuilder visitTypeName(TypeName node) {
-    return new _ImportedSuggestionBuilder(request, typesOnly: true);
-  }
-
-  @override
-  _ImportedSuggestionBuilder
-      visitVariableDeclaration(VariableDeclaration node) {
-    Token equals = node.equals;
-    // Make suggestions for the RHS of a variable declaration
-    if (equals != null && request.offset >= equals.end) {
-      return new _ImportedSuggestionBuilder(request, excludeVoidReturn: true);
-    }
-    return null;
-  }
-}
-
-/**
  * [_ImportedSuggestionBuilder] traverses the imports and builds suggestions
  * based upon imported elements.
  */
@@ -320,15 +159,41 @@
     }
   }
 
+  /**
+   * Add top level suggestions from the cache.
+   * To reduce the number of suggestions sent to the client,
+   * filter the suggestions based upon the first character typed.
+   * If no characters are available to use for filtering,
+   * then exclude all low priority suggestions.
+   */
   void _addTopLevelSuggestions() {
+    String filterText = request.filterText;
+    if (filterText.length > 1) {
+      filterText = filterText.substring(0, 1);
+    }
+
+    //TODO (danrubel) Revisit this filtering once paged API has been added
+    addFilteredSuggestions(List<CompletionSuggestion> unfiltered) {
+      unfiltered.forEach((CompletionSuggestion suggestion) {
+        if (filterText.length > 0) {
+          if (suggestion.completion.startsWith(filterText)) {
+            request.suggestions.add(suggestion);
+          }
+        } else {
+          if (suggestion.relevance != CompletionRelevance.LOW) {
+            request.suggestions.add(suggestion);
+          }
+        }
+      });
+    }
+
     DartCompletionCache cache = request.cache;
-    request.suggestions
-        ..addAll(cache.importedTypeSuggestions)
-        ..addAll(cache.libraryPrefixSuggestions);
+    addFilteredSuggestions(cache.importedTypeSuggestions);
+    addFilteredSuggestions(cache.libraryPrefixSuggestions);
     if (!typesOnly) {
-      request.suggestions.addAll(cache.otherImportedSuggestions);
+      addFilteredSuggestions(cache.otherImportedSuggestions);
       if (!excludeVoidReturn) {
-        request.suggestions.addAll(cache.importedVoidReturnSuggestions);
+        addFilteredSuggestions(cache.importedVoidReturnSuggestions);
       }
     }
   }
diff --git a/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart b/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart
index 7191f4e..348021e 100644
--- a/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/invocation_computer.dart
@@ -7,10 +7,10 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/services/completion/dart_completion_manager.dart';
+import 'package:analysis_server/src/services/completion/optype.dart';
 import 'package:analysis_server/src/services/completion/suggestion_builder.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/element.dart';
-import 'package:analyzer/src/generated/scanner.dart';
 
 import '../../protocol_server.dart' show CompletionSuggestionKind;
 
@@ -23,10 +23,14 @@
 
   @override
   bool computeFast(DartCompletionRequest request) {
-    builder = request.node.accept(new _InvocationAstVisitor(request));
-    if (builder != null) {
-      return builder.computeFast(request.node);
+    OpType optype = request.optype;
+    if (optype.includeInvocationSuggestions) {
+      builder = request.node.accept(new _InvocationAstVisitor(request));
+      if (builder != null) {
+        return builder.computeFast(request.node);
+      }
     }
+
     return true;
   }
 
@@ -80,12 +84,15 @@
   _InvocationAstVisitor(this.request);
 
   @override
+  visitConstructorName(ConstructorName node) {
+    // some PrefixedIdentifier nodes are transformed into
+    // ConstructorName nodes during the resolution process.
+    return new _PrefixedIdentifierSuggestionBuilder(request);
+  }
+
+  @override
   SuggestionBuilder visitMethodInvocation(MethodInvocation node) {
-    Token period = node.period;
-    if (period == null || period.offset < request.offset) {
-      return new _ExpressionSuggestionBuilder(request);
-    }
-    return null;
+    return new _ExpressionSuggestionBuilder(request);
   }
 
   @override
@@ -97,23 +104,12 @@
   SuggestionBuilder visitPrefixedIdentifier(PrefixedIdentifier node) {
     // some PrefixedIdentifier nodes are transformed into
     // ConstructorName nodes during the resolution process.
-    Token period = node.period;
-    if (request.offset > period.offset) {
-      SimpleIdentifier prefix = node.prefix;
-      if (prefix != null) {
-        return new _PrefixedIdentifierSuggestionBuilder(request);
-      }
-    }
-    return null;
+    return new _PrefixedIdentifierSuggestionBuilder(request);
   }
 
   @override
   SuggestionBuilder visitPropertyAccess(PropertyAccess node) {
-    Token operator = node.operator;
-    if (operator != null && operator.offset < request.offset) {
-      return new _ExpressionSuggestionBuilder(request);
-    }
-    return null;
+    return new _ExpressionSuggestionBuilder(request);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/completion/local_computer.dart b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
index 082260d..519b3c8 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_computer.dart
+++ b/pkg/analysis_server/lib/src/services/completion/local_computer.dart
@@ -11,6 +11,7 @@
 import 'package:analysis_server/src/protocol.dart' hide Element, ElementKind;
 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/optype.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 
@@ -22,10 +23,16 @@
 
   @override
   bool computeFast(DartCompletionRequest request) {
+    OpType optype = request.optype;
+    if (optype.includeTopLevelSuggestions) {
+      _LocalVisitor localVisitor = new _LocalVisitor(request, request.offset);
+      localVisitor.typesOnly = optype.includeOnlyTypeNameSuggestions;
+      localVisitor.excludeVoidReturn = !optype.includeVoidReturnSuggestions;
 
-    // Collect suggestions from the specific child [AstNode] that contains
-    // the completion offset and all of its parents recursively.
-    request.node.accept(new _LocalVisitor(request, request.offset));
+      // Collect suggestions from the specific child [AstNode] that contains
+      // the completion offset and all of its parents recursively.
+      request.node.accept(localVisitor);
+    }
 
     // If the unit is not a part and does not reference any parts
     // then work is complete
@@ -248,82 +255,6 @@
     }
   }
 
-  @override
-  bool visitCascadeExpression(CascadeExpression node) {
-    Expression target = node.target;
-    // This computer handles the expression
-    // while InvocationComputer handles the cascade selector
-    if (target != null && offset <= target.end) {
-      return visitNode(node);
-    } else {
-      return finished;
-    }
-  }
-
-  @override
-  visitCombinator(Combinator node) {
-    // Handled by CombinatorComputer
-  }
-
-  @override
-  visitMethodInvocation(MethodInvocation node) {
-    // InvocationComputer adds suggestions for method selector
-    Token period = node.period;
-    if (period != null && period.offset < request.offset) {
-      ArgumentList argumentList = node.argumentList;
-      if (argumentList == null || request.offset <= argumentList.offset) {
-        return;
-      }
-    }
-    visitNode(node);
-  }
-
-  @override
-  bool visitNamespaceDirective(NamespaceDirective node) {
-    // No suggestions
-    return finished;
-  }
-
-  @override
-  visitPrefixedIdentifier(PrefixedIdentifier node) {
-    // InvocationComputer adds suggestions for prefixed elements
-    // but this computer adds suggestions for the prefix itself
-    SimpleIdentifier prefix = node.prefix;
-    if (prefix == null || request.offset <= prefix.end) {
-      visitNode(node);
-    }
-  }
-
-  @override
-  visitPropertyAccess(PropertyAccess node) {
-    // InvocationComputer adds suggestions for property access selector
-  }
-
-  @override
-  bool visitStringLiteral(StringLiteral node) {
-    // ignore
-    return finished;
-  }
-
-  @override
-  visitTypeName(TypeName node) {
-    // If suggesting completions within a TypeName node
-    // then limit suggestions to only types
-    typesOnly = true;
-    return visitNode(node);
-  }
-
-  @override
-  bool visitVariableDeclaration(VariableDeclaration node) {
-    // Do not add suggestions if editing the name in a var declaration
-    SimpleIdentifier name = node.name;
-    if (name == null || name.offset < offset || offset > name.end) {
-      return visitNode(node);
-    } else {
-      return finished;
-    }
-  }
-
   CompletionSuggestion _addSuggestion(SimpleIdentifier id, TypeName typeName,
       ClassDeclaration classDecl, bool isDeprecated) {
     if (id != null) {
diff --git a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart b/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart
index 09ed9e3..ccdd8ba 100644
--- a/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/local_declaration_visitor.dart
@@ -62,6 +62,17 @@
               }
             });
           }
+        } else if (stmt is FunctionDeclarationStatement) {
+          FunctionDeclaration declaration = stmt.functionDeclaration;
+          if (declaration != null && declaration.offset < offset) {
+            SimpleIdentifier id = declaration.name;
+            if (id != null) {
+              String name = id.name;
+              if (name != null && name.length > 0) {
+                declaredFunction(declaration);
+              }
+            }
+          }
         }
       }
     });
diff --git a/pkg/analysis_server/lib/src/services/completion/optype.dart b/pkg/analysis_server/lib/src/services/completion/optype.dart
new file mode 100644
index 0000000..b6e6bda
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/completion/optype.dart
@@ -0,0 +1,465 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library services.completion.computer.dart.optype;
+
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+
+/**
+ * An [AstVisitor] for determining whether top level suggestions or invocation
+ * suggestions should be made based upon the type of node in which the
+ * suggestions were requested.
+ */
+class OpType {
+
+  /**
+   * Indicates whether invocation suggestions should be included.
+   */
+  bool includeInvocationSuggestions = false;
+
+  /**
+   * Indicates whether type names should be suggested.
+   */
+  bool includeTypeNameSuggestions = false;
+
+  /**
+   * Indicates whether setters along with methods and functions that
+   * have a [void] return type should be suggested.
+   */
+  bool includeVoidReturnSuggestions = false;
+
+  /**
+   * Indicates whether fields and getters along with methods and functions that
+   * have a non-[void] return type should be suggested.
+   */
+  bool includeReturnValueSuggestions = false;
+
+  /**
+   * Determine the suggestions that should be made based upon the given
+   * [AstNode] and offset.
+   */
+  factory OpType.forCompletion(AstNode node, int offset) {
+    OpType optype = new OpType._();
+    node.accept(new _OpTypeAstVisitor(optype, offset));
+    return optype;
+  }
+
+  OpType._();
+
+  /**
+   * Indicate whether only type names should be suggested
+   */
+  bool get includeOnlyTypeNameSuggestions =>
+      includeTypeNameSuggestions &&
+          !includeReturnValueSuggestions &&
+          !includeVoidReturnSuggestions &&
+          !includeInvocationSuggestions;
+
+  /**
+   * Indicate whether top level elements should be suggested
+   */
+  bool get includeTopLevelSuggestions =>
+      includeReturnValueSuggestions ||
+          includeTypeNameSuggestions ||
+          includeVoidReturnSuggestions;
+
+}
+
+class _OpTypeAstVisitor extends GeneralizingAstVisitor {
+
+  /**
+   * The offset within the source at which the completion is requested.
+   */
+  final int offset;
+
+  /**
+   * The [OpType] being initialized
+   */
+  final OpType optype;
+
+  _OpTypeAstVisitor(this.optype, this.offset);
+
+  bool isAfterSemicolon(Token semicolon) =>
+      semicolon != null && !semicolon.isSynthetic && semicolon.offset < offset;
+
+  @override
+  void visitAnnotation(Annotation node) {
+    Token atSign = node.atSign;
+    if (atSign == null || offset <= atSign.offset) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    } else {
+      Token period = node.period;
+      if (period == null || offset <= period.offset) {
+        optype.includeTypeNameSuggestions = true;
+        optype.includeReturnValueSuggestions = true;
+      } else {
+        optype.includeInvocationSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitArgumentList(ArgumentList node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitBlock(Block node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+    optype.includeVoidReturnSuggestions = true;
+  }
+
+  @override
+  void visitCascadeExpression(CascadeExpression node) {
+    Expression target = node.target;
+    if (target != null && offset <= target.end) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    } else {
+      optype.includeInvocationSuggestions = true;
+    }
+  }
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    // Make suggestions in the body of the class declaration
+    Token leftBracket = node.leftBracket;
+    if (leftBracket != null && offset >= leftBracket.end) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitClassMember(ClassMember node) {
+    if (offset <= node.offset || node.end <= offset) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitCommentReference(CommentReference node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+    optype.includeVoidReturnSuggestions = true;
+  }
+
+  @override
+  visitConstructorName(ConstructorName node) {
+    // some PrefixedIdentifier nodes are transformed into
+    // ConstructorName nodes during the resolution process.
+    Token period = node.period;
+    if (period != null && offset > period.offset) {
+      TypeName type = node.type;
+      if (type != null) {
+        SimpleIdentifier prefix = type.name;
+        if (prefix != null) {
+          optype.includeInvocationSuggestions = true;
+        }
+      }
+    }
+  }
+
+  @override
+  void visitDoStatement(DoStatement node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && leftParen.end <= offset) {
+      Token rightParen = node.rightParenthesis;
+      if (rightParen == null || offset <= rightParen.offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitEmptyStatement(EmptyStatement node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+    optype.includeVoidReturnSuggestions = true;
+  }
+
+  @override
+  void visitExpression(Expression node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    Token functionDefinition = node.functionDefinition;
+    if (functionDefinition != null && functionDefinition.end <= offset) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitExpressionStatement(ExpressionStatement node) {
+    Expression expression = node.expression;
+    // A pre-variable declaration (e.g. C ^) is parsed as an expression
+    // statement. Do not make suggestions for the variable name.
+    if (expression is SimpleIdentifier && offset <= expression.end) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    } else {
+      Token semicolon = node.semicolon;
+      if (semicolon != null && semicolon.end <= offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+        optype.includeVoidReturnSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitExtendsClause(ExtendsClause node) {
+    Token keyword = node.keyword;
+    if (keyword != null && keyword.end < offset) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitForEachStatement(ForEachStatement node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && leftParen.end <= offset) {
+      Token rightParen = node.rightParenthesis;
+      if (rightParen == null || offset <= rightParen.offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitFormalParameterList(FormalParameterList node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && offset > leftParen.offset) {
+      Token rightParen = node.rightParenthesis;
+      if (rightParen == null || offset <= rightParen.offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitForStatement(ForStatement node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && offset >= leftParen.end) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+      // TODO (danrubel) void return suggestions only belong after
+      // the 2nd semicolon.  Return value suggestions only belong after the
+      // e1st or second semicolon.
+    }
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    Token keyword = node.keyword;
+    if (keyword != null && keyword.end <= offset) {
+      SimpleIdentifier id = node.name;
+      if (id != null) {
+        TypeName returnType = node.returnType;
+        if (offset <= (returnType != null ? returnType.end : id.end)) {
+          optype.includeTypeNameSuggestions = true;
+        }
+      }
+    }
+  }
+
+  @override
+  void visitIfStatement(IfStatement node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && offset >= leftParen.end) {
+      Token rightParen = node.rightParenthesis;
+      if (rightParen == null || offset <= rightParen.offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    Token keyword = node.keyword;
+    if (keyword != null && keyword.end < offset) {
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitInterpolationExpression(InterpolationExpression node) {
+    Expression expression = node.expression;
+    if (expression is SimpleIdentifier) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    SimpleIdentifier id = node.name;
+    if (id != null && offset < id.offset) {
+      optype.includeTypeNameSuggestions = true;
+    }
+    visitClassMember(node);
+  }
+
+  @override
+  void visitMethodInvocation(MethodInvocation node) {
+    Token period = node.period;
+    if (period == null || offset <= period.offset) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    } else {
+      optype.includeInvocationSuggestions = true;
+    }
+  }
+
+  @override
+  void visitNode(AstNode node) {
+    // no suggestion by default
+  }
+
+  @override
+  void visitNormalFormalParameter(NormalFormalParameter node) {
+    optype.includeReturnValueSuggestions = true;
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier node) {
+    Token period = node.period;
+    if (period == null || offset <= period.offset) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    } else {
+      optype.includeInvocationSuggestions = true;
+    }
+  }
+
+  @override
+  void visitPropertyAccess(PropertyAccess node) {
+    var operator = node.operator;
+    if (operator != null && offset < operator.offset) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    } else {
+      optype.includeInvocationSuggestions = true;
+    }
+  }
+
+  @override
+  void visitReturnStatement(ReturnStatement node) {
+    Token keyword = node.keyword;
+    if (keyword != null && keyword.end < offset) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    node.parent.accept(this);
+  }
+
+  @override
+  void visitStringLiteral(StringLiteral node) {
+    // no suggestions
+  }
+
+  @override
+  void visitSwitchCase(SwitchCase node) {
+    Token keyword = node.keyword;
+    if (keyword == null || keyword.end < offset) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    }
+  }
+
+  @override
+  void visitSwitchStatement(SwitchStatement node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && leftParen.end <= offset) {
+      Token rightParen = node.rightParenthesis;
+      if (rightParen == null || offset <= rightParen.offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
+  void visitTypeName(TypeName node) {
+    // If suggesting completions within a TypeName node
+    // then limit suggestions to only types in specific situations
+    AstNode p = node.parent;
+    if (p is IsExpression || p is ConstructorName || p is AsExpression) {
+      optype.includeTypeNameSuggestions = true;
+      // TODO (danrubel) Possible future improvement:
+      // on the RHS of an "is" or "as" expression, don't suggest types that are
+      // guaranteed to pass or guaranteed to fail the cast.
+      // See dartbug.com/18860
+    } else if (p is VariableDeclarationList) {
+      // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+      // the user may be either (1) entering a type for the assignment
+      // or (2) starting a new statement.
+      // Consider suggesting only types
+      // if only spaces separates the 1st and 2nd identifiers.
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    } else {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    }
+  }
+
+  @override
+  void visitTypeParameter(TypeParameter node) {
+    optype.includeTypeNameSuggestions = true;
+  }
+
+  @override
+  void visitVariableDeclaration(VariableDeclaration node) {
+    Token equals = node.equals;
+    // Make suggestions for the RHS of a variable declaration
+    if (equals != null && offset >= equals.end) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+    }
+  }
+
+  @override
+  void visitVariableDeclarationStatement(VariableDeclarationStatement node) {
+    if (isAfterSemicolon(node.semicolon)) {
+      optype.includeReturnValueSuggestions = true;
+      optype.includeTypeNameSuggestions = true;
+      optype.includeVoidReturnSuggestions = true;
+    }
+  }
+
+  @override
+  void visitWhileStatement(WhileStatement node) {
+    Token leftParen = node.leftParenthesis;
+    if (leftParen != null && leftParen.end <= offset) {
+      Token rightParen = node.rightParenthesis;
+      if (rightParen == null || offset <= rightParen.offset) {
+        optype.includeReturnValueSuggestions = true;
+        optype.includeTypeNameSuggestions = true;
+      }
+    }
+  }
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
index dd313e1..2c5a4e2 100644
--- a/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/suggestion_builder.dart
@@ -196,6 +196,9 @@
    */
   static void suggestionsFor(DartCompletionRequest request, Element element,
       {bool staticOnly: false}) {
+    if (element == DynamicElementImpl.instance) {
+      element = request.cache.objectClassElement;
+    }
     if (element is ClassElement) {
       return element.accept(
           new ClassElementSuggestionBuilder(request, staticOnly));
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 0c338f1..84eeeac 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -236,6 +236,7 @@
     String typeSource;
     DartType type = declaredIdentifier.identifier.bestType;
     if (type is InterfaceType || type is FunctionType) {
+      _configureTargetLocation(node);
       Set<LibraryElement> librariesToImport = new Set<LibraryElement>();
       typeSource = utils.getTypeSource(type, librariesToImport);
       _addLibraryImports(librariesToImport);
@@ -290,6 +291,7 @@
     // prepare type source
     String typeSource;
     if (type is InterfaceType || type is FunctionType) {
+      _configureTargetLocation(node);
       Set<LibraryElement> librariesToImport = new Set<LibraryElement>();
       typeSource = utils.getTypeSource(type, librariesToImport);
       _addLibraryImports(librariesToImport);
@@ -616,13 +618,13 @@
         String newOperator = null;
         TokenType operatorType = operator.type;
         if (operatorType == TokenType.LT) {
-          newOperator = '>=';
-        } else if (operatorType == TokenType.LT_EQ) {
           newOperator = '>';
+        } else if (operatorType == TokenType.LT_EQ) {
+          newOperator = '>=';
         } else if (operatorType == TokenType.GT) {
-          newOperator = '<=';
-        } else if (operatorType == TokenType.GT_EQ) {
           newOperator = '<';
+        } else if (operatorType == TokenType.GT_EQ) {
+          newOperator = '<=';
         }
         // replace the operator
         if (newOperator != null) {
@@ -1259,6 +1261,11 @@
       return;
     }
     IfStatement ifStatement = statement as IfStatement;
+    // no support "else"
+    if (ifStatement.elseStatement != null) {
+      _coverageMarker();
+      return;
+    }
     // check that binary expression is part of first level && condition of "if"
     BinaryExpression condition = binaryExpression;
     while (condition.parent is BinaryExpression &&
@@ -1284,7 +1291,6 @@
     _addRemoveEdit(rangeEndEnd(binaryExpression.leftOperand, condition));
     // update "then" statement
     Statement thenStatement = ifStatement.thenStatement;
-    Statement elseStatement = ifStatement.elseStatement;
     if (thenStatement is Block) {
       Block thenBlock = thenStatement;
       SourceRange thenBlockRange = rangeNode(thenBlock);
@@ -1299,41 +1305,14 @@
       {
         int thenBlockEnd = thenBlockRange.end;
         String source = "${indent}}";
-        // may be move "else" statements
-        if (elseStatement != null) {
-          List<Statement> elseStatements = getStatements(elseStatement);
-          SourceRange elseLinesRange =
-              utils.getLinesRangeStatements(elseStatements);
-          String elseIndentOld = "${prefix}${indent}";
-          String elseIndentNew = "${elseIndentOld}${indent}";
-          String newElseSource =
-              utils.replaceSourceRangeIndent(elseLinesRange, elseIndentOld, elseIndentNew);
-          // append "else" block
-          source += " else {${eol}";
-          source += newElseSource;
-          source += "${prefix}${indent}}";
-          // remove old "else" range
-          _addRemoveEdit(rangeStartEnd(thenBlockEnd, elseStatement));
-        }
         // insert before outer "then" block "}"
         source += "${eol}${prefix}";
         _addInsertEdit(thenBlockEnd - 1, source);
       }
     } else {
       // insert inner "if" with right part of "condition"
-      {
-        String source = "${eol}${prefix}${indent}if (${rightConditionSource})";
-        _addInsertEdit(ifStatement.rightParenthesis.offset + 1, source);
-      }
-      // indent "else" statements to correspond inner "if"
-      if (elseStatement != null) {
-        SourceRange elseRange =
-            rangeStartEnd(ifStatement.elseKeyword.offset, elseStatement);
-        SourceRange elseLinesRange = utils.getLinesRange(elseRange);
-        String elseIndentOld = prefix;
-        String elseIndentNew = "${elseIndentOld}${indent}";
-        _addIndentEdit(elseLinesRange, elseIndentOld, elseIndentNew);
-      }
+      String source = "${eol}${prefix}${indent}if (${rightConditionSource})";
+      _addInsertEdit(ifStatement.rightParenthesis.offset + 1, source);
     }
     // indent "then" statements to correspond inner "if"
     {
@@ -1646,6 +1625,20 @@
   }
 
   /**
+   * Configures [utils] using given [target].
+   */
+  void _configureTargetLocation(Object target) {
+    utils.targetClassElement = null;
+    if (target is AstNode) {
+      ClassDeclaration targetClassDeclaration =
+          target.getAncestor((node) => node is ClassDeclaration);
+      if (targetClassDeclaration != null) {
+        utils.targetClassElement = targetClassDeclaration.element;
+      }
+    }
+  }
+
+  /**
    * Returns an existing or just added [LinkedEditGroup] with [groupId].
    */
   LinkedEditGroup _getLinkedPosition(String groupId) {
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 e86a1cc..143cceb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -612,6 +612,7 @@
       }
       staticModifier = _inStaticContext();
     }
+    utils.targetClassElement = targetClassElement;
     // prepare location
     ClassDeclaration targetClassNode = targetClassElement.node;
     _FieldLocation targetLocation = _prepareNewFieldLocation(targetClassNode);
@@ -1259,6 +1260,7 @@
         node.getAncestor((node) => node is CompilationUnitMember);
     insertOffset = enclosingMember.end;
     sourcePrefix = "${eol}${eol}";
+    utils.targetClassElement = null;
     // build method source
     SourceBuilder sb = new SourceBuilder(file, insertOffset);
     {
@@ -1327,6 +1329,8 @@
         targetElement = unitElement;
         ClassMember enclosingMember =
             node.getAncestor((node) => node is ClassMember);
+        ClassDeclaration enclosingClass = enclosingMember.parent;
+        utils.targetClassElement = enclosingClass.element;
         staticModifier = _inStaticContext();
         prefix = utils.getNodePrefix(enclosingMember);
         insertOffset = enclosingMember.end;
diff --git a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
index bc8b6cc..db4a50a 100644
--- a/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
+++ b/pkg/analysis_server/lib/src/services/correction/statement_analyzer.dart
@@ -54,7 +54,9 @@
    * Records fatal error with given message and [Location].
    */
   void invalidSelection(String message, [Location context]) {
-    _status.addFatalError(message, context);
+    if (!_status.hasFatalError) {
+      _status.addFatalError(message, context);
+    }
     reset();
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index a14fb8a..63c85f8 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -534,6 +534,12 @@
 class CorrectionUtils {
   final CompilationUnit unit;
 
+  /**
+   * The [ClassElement] the generated code is inserted to, so we can decide if
+   * a type parameter may or may not be used.
+   */
+  ClassElement targetClassElement;
+
   LibraryElement _library;
   String _buffer;
   String _endOfLine;
@@ -877,7 +883,8 @@
       // return type
       DartType returnType = functionType.returnType;
       if (returnType != null && !returnType.isDynamic) {
-        sb.write(getTypeSource(returnType, librariesToImport));
+        String returnTypeSource = getTypeSource(returnType, librariesToImport);
+        sb.write(returnTypeSource);
         sb.write(' ');
       }
       // parameter name
@@ -965,14 +972,13 @@
       List<DartType> arguments = type.typeArguments;
       // check if has arguments
       bool hasArguments = false;
+      bool allArgumentsVisible = true;
       for (DartType argument in arguments) {
-        if (!argument.isDynamic) {
-          hasArguments = true;
-          break;
-        }
+        hasArguments = hasArguments || !argument.isDynamic;
+        allArgumentsVisible = allArgumentsVisible && _isTypeVisible(argument);
       }
       // append type arguments
-      if (hasArguments) {
+      if (hasArguments && allArgumentsVisible) {
         sb.write("<");
         for (int i = 0; i < arguments.length; i++) {
           DartType argument = arguments[i];
@@ -990,6 +996,18 @@
   }
 
   /**
+   * Checks if [type] is visible at [targetOffset].
+   */
+  bool _isTypeVisible(DartType type) {
+    if (type is TypeParameterType) {
+      TypeParameterElement parameterElement = type.element;
+      Element parameterClassElement = parameterElement.enclosingElement;
+      return identical(parameterClassElement, targetClassElement);
+    }
+    return true;
+  }
+
+  /**
    * Indents given source left or right.
    */
   String indentSourceLeftRight(String source, bool right) {
diff --git a/pkg/analysis_server/lib/src/services/index/store/split_store.dart b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
index b0b3169..e816fbb 100644
--- a/pkg/analysis_server/lib/src/services/index/store/split_store.dart
+++ b/pkg/analysis_server/lib/src/services/index/store/split_store.dart
@@ -534,7 +534,6 @@
   @override
   bool aboutToIndexDart(AnalysisContext context,
       CompilationUnitElement unitElement) {
-    context = _unwrapContext(context);
     // may be already disposed in other thread
     if (context.isDisposed) {
       return false;
@@ -604,7 +603,6 @@
 
   @override
   bool aboutToIndexHtml(AnalysisContext context, HtmlElement htmlElement) {
-    context = _unwrapContext(context);
     // may be already disposed in other thread
     if (context.isDisposed) {
       return false;
@@ -701,7 +699,6 @@
 
   @override
   void removeContext(AnalysisContext context) {
-    context = _unwrapContext(context);
     if (context == null) {
       return;
     }
@@ -717,7 +714,6 @@
 
   @override
   void removeSource(AnalysisContext context, Source source) {
-    context = _unwrapContext(context);
     if (context == null) {
       return;
     }
@@ -746,7 +742,6 @@
 
   @override
   void removeSources(AnalysisContext context, SourceContainer container) {
-    context = _unwrapContext(context);
     if (context == null) {
       return;
     }
@@ -887,19 +882,6 @@
       }
     }
   }
-
-  /**
-   * When logging is on, [AnalysisEngine] actually creates
-   * [InstrumentedAnalysisContextImpl], which wraps [AnalysisContextImpl] used to create
-   * actual [Element]s. So, in index we have to unwrap [InstrumentedAnalysisContextImpl]
-   * when perform any operation.
-   */
-  AnalysisContext _unwrapContext(AnalysisContext context) {
-    if (context is InstrumentedAnalysisContextImpl) {
-      context = (context as InstrumentedAnalysisContextImpl).basis;
-    }
-    return context;
-  }
 }
 
 
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename.dart b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
index e07edb6..746a8d6 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename.dart
@@ -57,14 +57,7 @@
  * Checks if the given [Element] is in the given [AnalysisContext].
  */
 bool isInContext(Element element, AnalysisContext context) {
-  AnalysisContext elementContext = element.context;
-  if (elementContext == context) {
-    return true;
-  }
-  if (context is InstrumentedAnalysisContextImpl) {
-    return elementContext == context.basis;
-  }
-  return false;
+  return element.context == context;
 }
 
 
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index 12337a8..d6851ec 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -40,7 +40,7 @@
 class SocketServer {
   final AnalysisServerOptions analysisServerOptions;
   final DirectoryBasedDartSdk defaultSdk;
-  final InstrumentationServer instrumentationServer;
+  final InstrumentationService instrumentationService;
 
   /**
    * The analysis server that was created when a client established a
@@ -49,7 +49,7 @@
   AnalysisServer analysisServer;
 
   SocketServer(this.analysisServerOptions, this.defaultSdk,
-      this.instrumentationServer);
+      this.instrumentationService);
 
   /**
    * Create an analysis server which will communicate with the client using the
@@ -75,7 +75,7 @@
         _createIndex(),
         analysisServerOptions,
         defaultSdk,
-        instrumentationServer,
+        instrumentationService,
         rethrowExceptions: false);
     _initializeHandlers(analysisServer);
   }
diff --git a/pkg/analysis_server/lib/stdio_server.dart b/pkg/analysis_server/lib/stdio_server.dart
index 5c3f6ae..d28dbde 100644
--- a/pkg/analysis_server/lib/stdio_server.dart
+++ b/pkg/analysis_server/lib/stdio_server.dart
@@ -34,8 +34,10 @@
    * Return a future that will be completed when stdin closes.
    */
   Future serveStdio() {
-    ByteStreamServerChannel serverChannel =
-        new ByteStreamServerChannel(stdin, stdout);
+    ByteStreamServerChannel serverChannel = new ByteStreamServerChannel(
+        stdin,
+        stdout,
+        socketServer.instrumentationService);
     socketServer.createAnalysisServer(serverChannel);
     return serverChannel.closed;
   }
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index b1a0d38..a4ede1e 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -13,6 +13,6 @@
   watcher: any
 dev_dependencies:
   html5lib: any
-  mock: '>=0.10.0 <0.11.0'
+  mock: '>=0.11.0 <0.12.0'
   typed_mock: '>=0.0.4 <1.0.0'
-  unittest: '>=0.10.0 <0.12.0'
+  unittest: '>=0.11.4 <0.12.0'
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 1e05cc2..fffef7c 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -91,7 +91,7 @@
         index,
         new AnalysisServerOptions(),
         new MockSdk(),
-        const NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
   }
 
   Index createIndex() {
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index c5b3bf4..78e92ff 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -4,11 +4,14 @@
 
 library test.analysis_server;
 
+import 'dart:async';
+
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/constants.dart';
 import 'package:analysis_server/src/domain_server.dart';
 import 'package:analysis_server/src/operation/operation.dart';
 import 'package:analysis_server/src/protocol.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/src/generated/engine.dart';
@@ -19,186 +22,94 @@
 
 import 'mock_sdk.dart';
 import 'mocks.dart';
+import 'reflective_tests.dart';
 
 main() {
-  group('AnalysisServer', () {
-    test('server.status notifications', () {
-      AnalysisServerTestHelper helper = new AnalysisServerTestHelper();
-      MockAnalysisContext context = new MockAnalysisContext('context');
-      MockSource source = new MockSource('source');
-      when(source.fullName).thenReturn('foo.dart');
-      when(source.isInSystemLibrary).thenReturn(false);
-      ChangeNoticeImpl notice = new ChangeNoticeImpl(source);
-      notice.setErrors([], new LineInfo([0]));
-      AnalysisResult firstResult = new AnalysisResult([notice], 0, '', 0);
-      AnalysisResult lastResult = new AnalysisResult(null, 1, '', 1);
-      when(
-          context.performAnalysisTask).thenReturnList(
-              [firstResult, firstResult, firstResult, lastResult]);
-      helper.server.serverServices.add(ServerService.STATUS);
-      helper.server.schedulePerformAnalysisOperation(context);
-      // Pump the event queue to make sure the server has finished any
-      // analysis.
-      return pumpEventQueue().then((_) {
-        List<Notification> notifications = helper.channel.notificationsReceived;
-        expect(notifications, isNot(isEmpty));
-        // expect at least one notification indicating analysis is in progress
-        expect(notifications.any((Notification notification) {
-          if (notification.event == SERVER_STATUS) {
-            var params = new ServerStatusParams.fromNotification(notification);
-            return params.analysis.isAnalyzing;
-          }
-          return false;
-        }), isTrue);
-        // the last notification should indicate that analysis is complete
-        Notification notification = notifications[notifications.length - 1];
-        var params = new ServerStatusParams.fromNotification(notification);
-        expect(params.analysis.isAnalyzing, isFalse);
-      });
-    });
-
-    test('echo', () {
-      AnalysisServerTestHelper helper = new AnalysisServerTestHelper();
-      helper.server.handlers = [new EchoHandler()];
-      var request = new Request('my22', 'echo');
-      return helper.channel.sendRequest(request).then((Response response) {
-        expect(response.id, equals('my22'));
-        expect(response.error, isNull);
-      });
-    });
-
-    test('shutdown', () {
-      AnalysisServerTestHelper helper = new AnalysisServerTestHelper();
-      helper.server.handlers = [new ServerDomainHandler(helper.server)];
-      var request = new Request('my28', SERVER_SHUTDOWN);
-      return helper.channel.sendRequest(request).then((Response response) {
-        expect(response.id, equals('my28'));
-        expect(response.error, isNull);
-      });
-    });
-
-    test('unknownRequest', () {
-      AnalysisServerTestHelper helper = new AnalysisServerTestHelper();
-      helper.server.handlers = [new EchoHandler()];
-      var request = new Request('my22', 'randomRequest');
-      return helper.channel.sendRequest(request).then((Response response) {
-        expect(response.id, equals('my22'));
-        expect(response.error, isNotNull);
-      });
-    });
-
-    test('rethrow exceptions', () {
-      AnalysisServerTestHelper helper = new AnalysisServerTestHelper();
-      Exception exceptionToThrow = new Exception('test exception');
-      MockServerOperation operation =
-          new MockServerOperation(ServerOperationPriority.ANALYSIS, (_) {
-        throw exceptionToThrow;
-      });
-      helper.server.operationQueue.add(operation);
-      helper.server.performOperationPending = true;
-      try {
-        helper.server.performOperation();
-        fail('exception not rethrown');
-      } on AnalysisException catch (exception) {
-        expect(exception.cause.exception, equals(exceptionToThrow));
-      }
-    });
-
-    test('contexts changed event', () {
-      AnalysisServerTestHelper helper = new AnalysisServerTestHelper();
-      helper.resourceProvider.newFolder('/foo');
-
-      bool wasAdded = false;
-      bool wasChanged = false;
-      bool wasRemoved = false;
-      helper.server.onContextsChanged.listen((ContextsChangedEvent event) {
-        wasAdded = event.added.length == 1;
-        if (wasAdded) {
-          expect(event.added[0], isNotNull);
-        }
-        wasChanged = event.changed.length == 1;
-        if (wasChanged) {
-          expect(event.changed[0], isNotNull);
-        }
-        wasRemoved = event.removed.length == 1;
-        if (wasRemoved) {
-          expect(event.removed[0], isNotNull);
-        }
-      });
-
-      helper.server.setAnalysisRoots('0', ['/foo'], [], {});
-      return pumpEventQueue().then((_) {
-        expect(wasAdded, isTrue);
-        expect(wasChanged, isFalse);
-        expect(wasRemoved, isFalse);
-
-        wasAdded = false;
-        wasChanged = false;
-        wasRemoved = false;
-        helper.server.setAnalysisRoots('0', ['/foo'], [], {
-          '/foo': '/bar'
-        });
-        return pumpEventQueue();
-      }).then((_) {
-        expect(wasAdded, isFalse);
-        expect(wasChanged, isTrue);
-        expect(wasRemoved, isFalse);
-
-        wasAdded = false;
-        wasChanged = false;
-        wasRemoved = false;
-        helper.server.setAnalysisRoots('0', [], [], {});
-        return pumpEventQueue();
-      }).then((_) {
-        expect(wasAdded, isFalse);
-        expect(wasChanged, isFalse);
-        expect(wasRemoved, isTrue);
-      });
-    });
-
-    test('priority sources changed event', () {
-      AnalysisServerTestHelper helper = new AnalysisServerTestHelper();
-      helper.resourceProvider.newFolder('/foo');
-
-      int eventCount = 0;
-      Source firstSource = null;
-      helper.server.onPriorityChange.listen((PriorityChangeEvent event) {
-        ++eventCount;
-        firstSource = event.firstSource;
-      });
-
-      helper.server.setAnalysisRoots('0', ['/foo'], [], {});
-      return pumpEventQueue().then((_) {
-        expect(eventCount, 0);
-
-        helper.server.setPriorityFiles('1', ['/foo/bar.dart']);
-        return pumpEventQueue();
-      }).then((_) {
-        expect(eventCount, 1);
-        expect(firstSource.fullName, '/foo/bar.dart');
-
-        helper.server.setPriorityFiles('2', ['/foo/b1.dart', '/foo/b2.dart']);
-        return pumpEventQueue();
-      }).then((_) {
-        expect(eventCount, 2);
-        expect(firstSource.fullName, '/foo/b1.dart');
-
-        helper.server.setPriorityFiles('17', []);
-        return pumpEventQueue();
-      }).then((_) {
-        expect(eventCount, 3);
-        expect(firstSource, isNull);
-      });
-    });
-  });
+  groupSep = ' | ';
+  runReflectiveTests(AnalysisServerTest);
 }
 
-class AnalysisServerTestHelper {
+@ReflectiveTestCase()
+class AnalysisServerTest {
   MockServerChannel channel;
   AnalysisServer server;
   MemoryResourceProvider resourceProvider;
 
-  AnalysisServerTestHelper({bool rethrowExceptions: true}) {
+  /**
+   * Verify that getAnalysisContextForSource returns the correct contexts even
+   * for sources that are included by multiple contexts.
+   *
+   * See dartbug.com/21898
+   */
+  Future fail_getAnalysisContextForSource_crossImports() {
+    // Subscribe to STATUS so we'll know when analysis is done.
+    server.serverServices = [ServerService.STATUS].toSet();
+    // Analyze project foo containing foo.dart and project bar containing
+    // bar.dart.
+    resourceProvider.newFolder('/foo');
+    resourceProvider.newFolder('/bar');
+    File foo = resourceProvider.newFile('/foo/foo.dart', '''
+libary foo;
+import "../bar/bar.dart";
+''');
+    Source fooSource = foo.createSource();
+    File bar = resourceProvider.newFile('/bar/bar.dart', '''
+library bar;
+import "../foo/foo.dart";
+''');
+    Source barSource = bar.createSource();
+    server.setAnalysisRoots('0', ['/foo', '/bar'], [], {});
+    return pumpEventQueue(40).then((_) {
+      expect(server.statusAnalyzing, isFalse);
+      // Make sure getAnalysisContext returns the proper context for each.
+      AnalysisContext fooContext =
+          server.getAnalysisContextForSource(fooSource);
+      expect(fooContext, isNotNull);
+      AnalysisContext barContext =
+          server.getAnalysisContextForSource(barSource);
+      expect(barContext, isNotNull);
+      expect(fooContext, isNot(same(barContext)));
+      expect(fooContext.getKindOf(fooSource), SourceKind.LIBRARY);
+      expect(fooContext.getKindOf(barSource), SourceKind.UNKNOWN);
+      expect(barContext.getKindOf(fooSource), SourceKind.UNKNOWN);
+      expect(barContext.getKindOf(barSource), SourceKind.LIBRARY);
+    });
+  }
+
+  /**
+   * Verify that getAnalysisContextForSource returns the correct contexts even
+   * for sources that haven't been analyzed yet.
+   *
+   * See dartbug.com/21898
+   */
+  Future fail_getAnalysisContextForSource_unanalyzed() {
+    // Subscribe to STATUS so we'll know when analysis is done.
+    server.serverServices = [ServerService.STATUS].toSet();
+    // Analyze project foo containing foo.dart and project bar containing
+    // bar.dart.
+    resourceProvider.newFolder('/foo');
+    resourceProvider.newFolder('/bar');
+    File foo = resourceProvider.newFile('/foo/foo.dart', 'library lib;');
+    Source fooSource = foo.createSource();
+    File bar = resourceProvider.newFile('/bar/bar.dart', 'library lib;');
+    Source barSource = bar.createSource();
+    server.setAnalysisRoots('0', ['/foo', '/bar'], [], {});
+    AnalysisContext fooContext = server.getAnalysisContextForSource(fooSource);
+    expect(fooContext, isNotNull);
+    AnalysisContext barContext = server.getAnalysisContextForSource(barSource);
+    expect(barContext, isNotNull);
+    expect(fooContext, isNot(same(barContext)));
+    return pumpEventQueue(40).then((_) {
+      expect(server.statusAnalyzing, isFalse);
+      // Make sure getAnalysisContext returned the proper context for each.
+      expect(fooContext.getKindOf(fooSource), SourceKind.LIBRARY);
+      expect(fooContext.getKindOf(barSource), SourceKind.UNKNOWN);
+      expect(barContext.getKindOf(fooSource), SourceKind.UNKNOWN);
+      expect(barContext.getKindOf(barSource), SourceKind.LIBRARY);
+    });
+  }
+
+  void setUp() {
     channel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
     server = new AnalysisServer(
@@ -208,8 +119,212 @@
         null,
         new AnalysisServerOptions(),
         new MockSdk(),
-        new NullInstrumentationServer(),
-        rethrowExceptions: rethrowExceptions);
+        InstrumentationService.NULL_SERVICE,
+        rethrowExceptions: true);
+  }
+
+  Future test_contextDisposed() {
+    resourceProvider.newFolder('/foo');
+    resourceProvider.newFile('/foo/bar.dart', 'library lib;');
+    server.setAnalysisRoots('0', ['/foo'], [], {});
+    AnalysisContext context;
+    return pumpEventQueue().then((_) {
+      context = server.getAnalysisContext('/foo/bar.dart');
+      server.setAnalysisRoots('1', [], [], {});
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(context.isDisposed, isTrue);
+    });
+  }
+
+  Future test_contextsChangedEvent() {
+    resourceProvider.newFolder('/foo');
+
+    bool wasAdded = false;
+    bool wasChanged = false;
+    bool wasRemoved = false;
+    server.onContextsChanged.listen((ContextsChangedEvent event) {
+      wasAdded = event.added.length == 1;
+      if (wasAdded) {
+        expect(event.added[0], isNotNull);
+      }
+      wasChanged = event.changed.length == 1;
+      if (wasChanged) {
+        expect(event.changed[0], isNotNull);
+      }
+      wasRemoved = event.removed.length == 1;
+      if (wasRemoved) {
+        expect(event.removed[0], isNotNull);
+      }
+    });
+
+    server.setAnalysisRoots('0', ['/foo'], [], {});
+    return pumpEventQueue().then((_) {
+      expect(wasAdded, isTrue);
+      expect(wasChanged, isFalse);
+      expect(wasRemoved, isFalse);
+
+      wasAdded = false;
+      wasChanged = false;
+      wasRemoved = false;
+      server.setAnalysisRoots('0', ['/foo'], [], {
+        '/foo': '/bar'
+      });
+      return pumpEventQueue();
+    }).then((_) {
+      expect(wasAdded, isFalse);
+      expect(wasChanged, isTrue);
+      expect(wasRemoved, isFalse);
+
+      wasAdded = false;
+      wasChanged = false;
+      wasRemoved = false;
+      server.setAnalysisRoots('0', [], [], {});
+      return pumpEventQueue();
+    }).then((_) {
+      expect(wasAdded, isFalse);
+      expect(wasChanged, isFalse);
+      expect(wasRemoved, isTrue);
+    });
+  }
+
+  Future test_echo() {
+    server.handlers = [new EchoHandler()];
+    var request = new Request('my22', 'echo');
+    return channel.sendRequest(request).then((Response response) {
+      expect(response.id, equals('my22'));
+      expect(response.error, isNull);
+    });
+  }
+
+  Future test_getAnalysisContextForSource() {
+    // Subscribe to STATUS so we'll know when analysis is done.
+    server.serverServices = [ServerService.STATUS].toSet();
+    // Analyze project foo containing foo.dart and project bar containing
+    // bar.dart.
+    resourceProvider.newFolder('/foo');
+    resourceProvider.newFolder('/bar');
+    File foo = resourceProvider.newFile('/foo/foo.dart', 'library lib;');
+    Source fooSource = foo.createSource();
+    File bar = resourceProvider.newFile('/bar/bar.dart', 'library lib;');
+    Source barSource = bar.createSource();
+    server.setAnalysisRoots('0', ['/foo', '/bar'], [], {});
+    return pumpEventQueue(40).then((_) {
+      expect(server.statusAnalyzing, isFalse);
+      // Make sure getAnalysisContext returns the proper context for each.
+      AnalysisContext fooContext =
+          server.getAnalysisContextForSource(fooSource);
+      expect(fooContext, isNotNull);
+      AnalysisContext barContext =
+          server.getAnalysisContextForSource(barSource);
+      expect(barContext, isNotNull);
+      expect(fooContext, isNot(same(barContext)));
+      expect(fooContext.getKindOf(fooSource), SourceKind.LIBRARY);
+      expect(fooContext.getKindOf(barSource), SourceKind.UNKNOWN);
+      expect(barContext.getKindOf(fooSource), SourceKind.UNKNOWN);
+      expect(barContext.getKindOf(barSource), SourceKind.LIBRARY);
+    });
+  }
+
+  Future test_prioritySourcesChangedEvent() {
+    resourceProvider.newFolder('/foo');
+
+    int eventCount = 0;
+    Source firstSource = null;
+    server.onPriorityChange.listen((PriorityChangeEvent event) {
+      ++eventCount;
+      firstSource = event.firstSource;
+    });
+
+    server.setAnalysisRoots('0', ['/foo'], [], {});
+    return pumpEventQueue().then((_) {
+      expect(eventCount, 0);
+
+      server.setPriorityFiles('1', ['/foo/bar.dart']);
+      return pumpEventQueue();
+    }).then((_) {
+      expect(eventCount, 1);
+      expect(firstSource.fullName, '/foo/bar.dart');
+
+      server.setPriorityFiles('2', ['/foo/b1.dart', '/foo/b2.dart']);
+      return pumpEventQueue();
+    }).then((_) {
+      expect(eventCount, 2);
+      expect(firstSource.fullName, '/foo/b1.dart');
+
+      server.setPriorityFiles('17', []);
+      return pumpEventQueue();
+    }).then((_) {
+      expect(eventCount, 3);
+      expect(firstSource, isNull);
+    });
+  }
+
+  void test_rethrowExceptions() {
+    Exception exceptionToThrow = new Exception('test exception');
+    MockServerOperation operation =
+        new MockServerOperation(ServerOperationPriority.ANALYSIS, (_) {
+      throw exceptionToThrow;
+    });
+    server.operationQueue.add(operation);
+    server.performOperationPending = true;
+    try {
+      server.performOperation();
+      fail('exception not rethrown');
+    } on AnalysisException catch (exception) {
+      expect(exception.cause.exception, equals(exceptionToThrow));
+    }
+  }
+
+  Future test_serverStatusNotifications() {
+    MockAnalysisContext context = new MockAnalysisContext('context');
+    MockSource source = new MockSource('source');
+    when(source.fullName).thenReturn('foo.dart');
+    when(source.isInSystemLibrary).thenReturn(false);
+    ChangeNoticeImpl notice = new ChangeNoticeImpl(source);
+    notice.setErrors([], new LineInfo([0]));
+    AnalysisResult firstResult = new AnalysisResult([notice], 0, '', 0);
+    AnalysisResult lastResult = new AnalysisResult(null, 1, '', 1);
+    when(
+        context.performAnalysisTask).thenReturnList(
+            [firstResult, firstResult, firstResult, lastResult]);
+    server.serverServices.add(ServerService.STATUS);
+    server.schedulePerformAnalysisOperation(context);
+    // Pump the event queue to make sure the server has finished any
+    // analysis.
+    return pumpEventQueue().then((_) {
+      List<Notification> notifications = channel.notificationsReceived;
+      expect(notifications, isNotEmpty);
+      // expect at least one notification indicating analysis is in progress
+      expect(notifications.any((Notification notification) {
+        if (notification.event == SERVER_STATUS) {
+          var params = new ServerStatusParams.fromNotification(notification);
+          return params.analysis.isAnalyzing;
+        }
+        return false;
+      }), isTrue);
+      // the last notification should indicate that analysis is complete
+      Notification notification = notifications[notifications.length - 1];
+      var params = new ServerStatusParams.fromNotification(notification);
+      expect(params.analysis.isAnalyzing, isFalse);
+    });
+  }
+
+  Future test_shutdown() {
+    server.handlers = [new ServerDomainHandler(server)];
+    var request = new Request('my28', SERVER_SHUTDOWN);
+    return channel.sendRequest(request).then((Response response) {
+      expect(response.id, equals('my28'));
+      expect(response.error, isNull);
+    });
+  }
+
+  Future test_unknownRequest() {
+    server.handlers = [new EchoHandler()];
+    var request = new Request('my22', 'randomRequest');
+    return channel.sendRequest(request).then((Response response) {
+      expect(response.id, equals('my22'));
+      expect(response.error, isNotNull);
+    });
   }
 }
 
diff --git a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
index 3feaaa19..297a3a0 100644
--- a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
+++ b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
@@ -10,6 +10,7 @@
 
 import 'package:analysis_server/src/channel/byte_stream_channel.dart';
 import 'package:analysis_server/src/protocol.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:unittest/unittest.dart';
 
 import '../mocks.dart';
@@ -240,7 +241,10 @@
     outputLineStream = outputStream.stream.transform(
         (new Utf8Codec()).decoder).transform(new LineSplitter());
     IOSink outputSink = new IOSink(outputStream);
-    channel = new ByteStreamServerChannel(inputStream.stream, outputSink);
+    channel = new ByteStreamServerChannel(
+        inputStream.stream,
+        outputSink,
+        InstrumentationService.NULL_SERVICE);
     StreamController<Request> requestStreamController =
         new StreamController<Request>();
     requestStream = requestStreamController.stream;
diff --git a/pkg/analysis_server/test/channel/web_socket_channel_test.dart b/pkg/analysis_server/test/channel/web_socket_channel_test.dart
index e28aa72..f88798d 100644
--- a/pkg/analysis_server/test/channel/web_socket_channel_test.dart
+++ b/pkg/analysis_server/test/channel/web_socket_channel_test.dart
@@ -8,6 +8,7 @@
 
 import 'package:analysis_server/src/channel/web_socket_channel.dart';
 import 'package:analysis_server/src/protocol.dart';
+import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:unittest/unittest.dart';
 
 import '../mocks.dart';
@@ -138,7 +139,8 @@
   static void setUp() {
     socket = new MockSocket.pair();
     client = new WebSocketClientChannel(socket);
-    server = new WebSocketServerChannel(socket.twin);
+    server =
+        new WebSocketServerChannel(socket.twin, InstrumentationService.NULL_SERVICE);
 
     requestsReceived = [];
     responsesReceived = [];
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index ee966c8..f786ffc 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -4,8 +4,11 @@
 
 library test.completion.support;
 
+import 'dart:async';
 import 'dart:collection';
 
+import 'package:unittest/unittest.dart';
+
 import 'completion_test_support.dart';
 
 main() {
@@ -17,42 +20,55 @@
  * A builder that builds the completion tests.
  */
 class CompletionTestBuilder {
+  /**
+   * Number of tests that have been built that are expected to pass.
+   */
+  int expectedPassCount = 0;
+
+  /**
+   * Number of tests that have been built that are expected to fail.
+   */
+  int expectedFailCount = 0;
+
   void buildAll() {
     buildNumberedTests();
     buildCommentSnippetTests();
     buildCompletionTests();
     buildOtherTests();
     buildLibraryTests();
+    int testCount = expectedPassCount + expectedFailCount;
+    print(
+        'Total $testCount tests, of which $expectedFailCount are expected to fail.');
   }
 
   void buildCommentSnippetTests() {
-    CompletionTestCase.buildTests('testCommentSnippets001', '''
+    buildTests('testCommentSnippets001', '''
 class X {static final num MAX = 0;num yc,xc;mth() {xc = yc = MA!1X;x!2c.abs();num f = M!3AX;}}''',
         <String>["1+MAX", "2+xc", "3+MAX"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets002', '''
+    buildTests('testCommentSnippets002', '''
 class Y {String x='hi';mth() {x.l!1ength;int n = 0;x!2.codeUnitAt(n!3);}}''',
         <String>["1+length", "2+x", "3+n"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets004', '''
+    buildTests('testCommentSnippets004', '''
 class A {!1int x; !2mth() {!3int y = this.!5x!6;}}class B{}''',
-        <String>["1+A", "2+B", "3+x", "3-y", "5+mth", "6+x"],
-        failingTests: '3');
+        <String>["1+A", "2+B", "3+x", "3-y", "5+mth", "6+x"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets005', '''
+    buildTests('testCommentSnippets005', '''
 class Date { static Date JUN, JUL;}class X { m() { return Da!1te.JU!2L; }}''',
         <String>["1+Date", "2+JUN", "2+JUL"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets007', '''
-class C {mth(Map x, !1) {}mtf(!2, Map x) {}m() {for (in!3t i=0; i<5; i++); A!4 x;}}class int{}class Arrays{}class bool{}''',
-        <String>["1+bool", "2+bool", "3+int", "4+Arrays"], failingTests: '3');
+    buildTests('testCommentSnippets007', '''
+class C {mth(Map x, !1) {}mtf(!2, Map x) {}m() {for (in!3t i=0; i<5; i++); A!4 x;}}class int{}class Arrays{}''',
+        <String>["1+bool", "2+bool", "3+int", "4+Arrays"],
+        failingTests: '3');
 
-    CompletionTestCase.buildTests('testCommentSnippets008', '''
+    buildTests('testCommentSnippets008', '''
 class Date{}final num M = Dat!1''', <String>["1+Date"]);
 
     // space, char, eol are important
-    CompletionTestCase.buildTests('testCommentSnippets009', '''
-class Map{}class Maps{}class x extends!5 !2M!3 !4implements!6 !1\n{}''',
+    buildTests('testCommentSnippets009', '''
+class Maps{}class x extends!5 !2M!3 !4implements!6 !1\n{}''',
         <String>[
             "1+Map",
             "2+Maps",
@@ -65,168 +81,164 @@
         failingTests: '46');
 
     // space, char, eol are important
-    CompletionTestCase.buildTests('testCommentSnippets010', '''
-class Map{}class x implements !1{}''', <String>["1+Map"], failingTests: '1');
+    buildTests('testCommentSnippets010', '''
+class x implements !1{}''', <String>["1+Map"]);
 
     // space, char, eol are important
-    CompletionTestCase.buildTests('testCommentSnippets011', '''
-class Map{}class x implements M!1{}''', <String>["1+Map"], failingTests: '1');
+    buildTests('testCommentSnippets011', '''
+class x implements M!1{}''', <String>["1+Map"]);
 
     // space, char, eol are important
-    CompletionTestCase.buildTests('testCommentSnippets012', '''
-class Map{}class x implements M!1\n{}''', <String>["1+Map"], failingTests: '1');
+    buildTests('testCommentSnippets012', '''
+class x implements M!1\n{}''', <String>["1+Map"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets013', '''
-class num{}class x !2{!1}!3''',
-        <String>["1+num", "2-num", "3-num"],
-        failingTests: '1');
+    buildTests('testCommentSnippets013', '''
+class x !2{!1}!3''', <String>["1+num", "2-num", "3-num"], failingTests: '3');
 
     // trailing space is important
-    CompletionTestCase.buildTests('testCommentSnippets014', '''
-class num{}typedef n!1 ;''', <String>["1+num"]);
+    buildTests('testCommentSnippets014', '''
+typedef n!1 ;''', <String>["1+num"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets015', '''
+    buildTests('testCommentSnippets015', '''
 class D {f(){} g(){f!1(f!2);}}''', <String>["1+f", "2+f"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets016', '''
+    buildTests('testCommentSnippets016', '''
 class F {m() { m(); !1}}''', <String>["1+m"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets017', '''
+    buildTests('testCommentSnippets017', '''
 class F {var x = !1false;}''', <String>["1+true"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets018', '''
+    buildTests('testCommentSnippets018', '''
 class Map{}class Arrays{}class C{ m(!1){} n(!2 x, q)''',
         <String>["1+Map", "1-void", "1-null", "2+Arrays", "2-void", "2-null"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets019', '''
-class A{m(){Object x;x.!1/**/clear()''',
-        <String>["1+toString"],
-        failingTests: '1');
+    buildTests('testCommentSnippets019', '''
+class A{m(){Object x;x.!1/**/clear()''', <String>["1+toString"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets020', '''
+    buildTests('testCommentSnippets020', '''
 classMap{}class tst {var newt;void newf(){}test() {var newz;new!1/**/;}}''',
         <String>["1+newt", "1+newf", "1+newz", "1-Map"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets021', '''
+    buildTests('testCommentSnippets021', '''
 class Map{}class tst {var newt;void newf(){}test() {var newz;new !1/**/;}}''',
         <String>["1+Map", "1-newt"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets022', '''
+    buildTests('testCommentSnippets022', '''
 class Map{}class F{m(){new !1;}}''', <String>["1+Map"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets022a', '''
+    buildTests('testCommentSnippets022a', '''
 class Map{}class F{m(){new !1''', <String>["1+Map"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets022b', '''
+    buildTests('testCommentSnippets022b', '''
 class Map{factory Map.qq(){return null;}}class F{m(){new Map.!1qq();}}''',
-        <String>["1+qq"],
-        failingTests: '1');
+        <String>["1+qq"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets023', '''
+    buildTests('testCommentSnippets023', '''
 class X {X c; X(this.!1c!3) : super() {c.!2}}''',
         <String>["1+c", "2+c", "3+c"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets024', '''
+    buildTests('testCommentSnippets024', '''
 class q {m(Map q){var x;m(!1)}n(){var x;n(!2)}}''', <String>["1+x", "2+x"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets025', '''
+    buildTests('testCommentSnippets025', '''
 class q {num m() {var q; num x=!1 q!3 + !2/**/;}}''',
         <String>["1+q", "2+q", "3+q"],
         failingTests: '123');
 
-    CompletionTestCase.buildTests('testCommentSnippets026', '''
+    buildTests('testCommentSnippets026', '''
 class List{}class a implements !1{}''', <String>["1+List"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets027', '''
+    buildTests('testCommentSnippets027', '''
 class String{}class List{}class test <X extends !1String!2> {}''',
         <String>["1+List", "2+String", "2-List"],
         failingTests: '12');
 
-    CompletionTestCase.buildTests('testCommentSnippets028', '''
+    buildTests('testCommentSnippets028', '''
 class String{}class List{}class DateTime{}typedef T Y<T extends !1>(List input);''',
         <String>["1+DateTime", "1+String"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets029', '''
+    buildTests('testCommentSnippets029', '''
 interface A<X> default B<X extends !1List!2> {}''',
         <String>["1+DateTime", "2+List"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets030', '''
+    buildTests('testCommentSnippets030', '''
 class Bar<T extends Foo> {const Bar(!1T!2 k);T!3 m(T!4 a, T!5 b){}final T!6 f = null;}''',
         <String>["1+T", "2+T", "3+T", "4+T", "5+T", "6+T"],
         failingTests: '123456');
 
-    CompletionTestCase.buildTests('testCommentSnippets031', '''
+    buildTests('testCommentSnippets031', '''
 class Bar<T extends Foo> {m(x){if (x is !1) return;if (x is!!!2)}}''',
         <String>["1+Bar", "1+T", "2+T", "2+Bar"],
         failingTests: '12');
 
-    CompletionTestCase.buildTests('testCommentSnippets032', '''
-class Fit{}class Bar<T extends Fooa> {const F!1ara();}''',
-        <String>["1+Fit", "1+Fara", "1-Bar"]);
+    buildTests('testCommentSnippets032', '''
+class Fit{}class Bar<T extends Fooa> {const !2F!1ara();}''',
+        <String>["1+Fit", "1+Fara", "1-Bar", "2+Fit"],
+        failingTests: '1');
 
     // Type propagation
-    CompletionTestCase.buildTests('testCommentSnippets033', '''
+    buildTests('testCommentSnippets033', '''
 class List{add(){}length(){}}t1() {var x;if (x is List) {x.!1add(3);}}''',
         <String>["1+add", "1+length"]);
 
     // Type propagation
-    CompletionTestCase.buildTests('testCommentSnippets035', '''
+    buildTests('testCommentSnippets035', '''
 class List{clear(){}length(){}}t3() {var x=new List(), y=x.!1length();x.!2clear();}''',
         <String>["1+length", "2+clear"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets036', '''
+    buildTests('testCommentSnippets036', '''
 class List{}t3() {var x=new List!1}''', <String>["1+List"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets037', '''
+    buildTests('testCommentSnippets037', '''
 class List{factory List.from(){}}t3() {var x=new List.!1}''',
-        <String>["1+from"],
-        failingTests: '1');
+        <String>["1+from"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets038', '''
+    buildTests('testCommentSnippets038', '''
 f(){int xa; String s = '\$x!1';}''', <String>["1+xa"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets038a', '''
+    buildTests('testCommentSnippets038a', '''
 int xa; String s = '\$x!1\'''', <String>["1+xa"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets039', '''
+    buildTests('testCommentSnippets039', '''
 f(){int xa; String s = '\$!1';}''', <String>["1+xa"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets039a', '''
+    buildTests('testCommentSnippets039a', '''
 int xa; String s = '\$!1\'''', <String>["1+xa"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets040', '''
+    buildTests('testCommentSnippets040', '''
 class List{add(){}}class Map{}class X{m(){List list; list.!1 Map map;}}''',
         <String>["1+add"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets041', '''
+    buildTests('testCommentSnippets041', '''
 class List{add(){}length(){}}class X{m(){List list; list.!1 zox();}}''',
         <String>["1+add"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets042', '''
+    buildTests('testCommentSnippets042', '''
 class DateTime{static const int WED=3;int get day;}fd(){DateTime d=new DateTime.now();d.!1WED!2;}''',
-        <String>["1+day", "2-WED"]);
+        <String>["1+day", "2-WED"],
+        failingTests: '2');
 
-    CompletionTestCase.buildTests('testCommentSnippets043', '''
+    buildTests('testCommentSnippets043', '''
 class L{var k;void.!1}''', <String>["1-k"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets044', '''
+    buildTests('testCommentSnippets044', '''
 class List{}class XXX {XXX.fisk();}main() {main(); new !1}}''',
         <String>["1+List", "1+XXX.fisk"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets047', '''
+    buildTests('testCommentSnippets047', '''
 f(){int x;int y=!1;}''', <String>["1+x"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets048', '''
+    buildTests('testCommentSnippets048', '''
 import 'dart:convert' as json;f() {var x=new js!1}''',
         <String>["1+json"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets049', '''
+    buildTests('testCommentSnippets049', '''
 import 'dart:convert' as json;
 import 'dart:convert' as jxx;
 class JsonParserX{}
@@ -241,7 +253,7 @@
             "3-jxx"],
         failingTests: '123');
 
-    CompletionTestCase.buildTests('testCommentSnippets050', '''
+    buildTests('testCommentSnippets050', '''
 class xdr {
   xdr();
   const xdr.a(a,b,c);
@@ -267,7 +279,7 @@
         failingTests: '123');
 
     // Type propagation.
-    CompletionTestCase.buildTests('testCommentSnippets051', '''
+    buildTests('testCommentSnippets051', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void r() {
   var v;
@@ -278,7 +290,7 @@
 }''', <String>["1+length", "2-getKeys"], failingTests: '1');
 
     // Type propagation.
-    CompletionTestCase.buildTests('testCommentSnippets052', '''
+    buildTests('testCommentSnippets052', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void r() {
   List<String> values = ['a','b','c'];
@@ -289,7 +301,7 @@
 }''', <String>["1+toUpperCase", "2-getKeys"], failingTests: '1');
 
     // Type propagation.
-    CompletionTestCase.buildTests('testCommentSnippets053', '''
+    buildTests('testCommentSnippets053', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void r() {
   var v;
@@ -299,7 +311,7 @@
   }
 }''', <String>["1+toUpperCase", "2-getKeys"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets054', '''
+    buildTests('testCommentSnippets054', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void r() {
   var v;
@@ -309,7 +321,7 @@
   }
 }''', <String>["1+isEmpty", "2+toUpperCase", "3-getKeys"], failingTests: '12');
 
-    CompletionTestCase.buildTests('testCommentSnippets055', '''
+    buildTests('testCommentSnippets055', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void r() {
   String v;
@@ -319,7 +331,7 @@
 }''', <String>["1+toUpperCase"]);
 
     // Type propagation.
-    CompletionTestCase.buildTests('testCommentSnippets056', '''
+    buildTests('testCommentSnippets056', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void f(var v) {
   if (v is!! String) {
@@ -329,7 +341,7 @@
 }''', <String>["1+toUpperCase"], failingTests: '1');
 
     // Type propagation.
-    CompletionTestCase.buildTests('testCommentSnippets057', '''
+    buildTests('testCommentSnippets057', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void f(var v) {
   if ((v as String).length == 0) {
@@ -337,7 +349,7 @@
   }
 }''', <String>["1+toUpperCase"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets058', '''
+    buildTests('testCommentSnippets058', '''
 typedef vo!2id callback(int k);
 void x(callback q){}
 void r() {
@@ -345,10 +357,10 @@
   x(!1);
 }''', <String>["1+v", "2+void"], failingTests: '2');
 
-    CompletionTestCase.buildTests('testCommentSnippets059', '''
+    buildTests('testCommentSnippets059', '''
 f(){((int x) => x+4).!1call(1);}''', <String>["1-call"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets060', '''
+    buildTests('testCommentSnippets060', '''
 class Map{}
 abstract class MM extends Map{factory MM() => new Map();}
 class Z {
@@ -358,12 +370,12 @@
   }
 }''', <String>["1+x", "1-x[]"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets061', '''
+    buildTests('testCommentSnippets061', '''
 class A{m(){!1f(3);!2}}n(){!3f(3);!4}f(x)=>x*3;''',
         <String>["1+f", "1+n", "2+f", "2+n", "3+f", "3+n", "4+f", "4+n"]);
 
     // Type propagation.
-    CompletionTestCase.buildTests('testCommentSnippets063', '''
+    buildTests('testCommentSnippets063', '''
 class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
 void r(var v) {
   v.!1toUpperCase;
@@ -371,7 +383,7 @@
   v.!2toUpperCase;
 }''', <String>["1-toUpperCase", "2+toUpperCase"], failingTests: '2');
 
-    CompletionTestCase.buildTests('testCommentSnippets064', '''
+    buildTests('testCommentSnippets064', '''
 class Spline {
   Line c;
   Spline a() {
@@ -408,7 +420,7 @@
             "8+j",
             "9+h"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets065', '''
+    buildTests('testCommentSnippets065', '''
 class Spline {
   Line c;
   Spline a() {
@@ -432,7 +444,7 @@
   }
 }''', <String>["1+a"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets066', '''
+    buildTests('testCommentSnippets066', '''
 class Spline {
   Line c;
   Spline a() {
@@ -456,7 +468,7 @@
   }
 }''', <String>["1+b"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets067', '''
+    buildTests('testCommentSnippets067', '''
 class Spline {
   Line c;
   Spline a() {
@@ -480,7 +492,7 @@
   }
 }''', <String>["1+b"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets068', '''
+    buildTests('testCommentSnippets068', '''
 class Spline {
   Line c;
   Spline a() {
@@ -504,7 +516,7 @@
   }
 }''', <String>["1+c"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets069', '''
+    buildTests('testCommentSnippets069', '''
 class Spline {
   Line c;
   Spline a() {
@@ -528,7 +540,7 @@
   }
 }''', <String>["1+c"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets070', '''
+    buildTests('testCommentSnippets070', '''
 class Spline {
   Line c;
   Spline a() {
@@ -552,7 +564,7 @@
   }
 }''', <String>["1+b"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets072', '''
+    buildTests('testCommentSnippets072', '''
 class X {
   int _p;
   set p(int x) => _p = x;
@@ -562,7 +574,7 @@
   x.!1p = 3;
 }''', <String>["1+p"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets073', '''
+    buildTests('testCommentSnippets073', '''
 class X {
   m() {
     JSON.stri!1;
@@ -573,7 +585,7 @@
   static stringify() {}
 }''', <String>["1+stringify"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets074', '''
+    buildTests('testCommentSnippets074', '''
 class X {
   m() {
     _x!1
@@ -581,20 +593,20 @@
   _x1(){}
 }''', <String>["1+_x1"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets075', '''
+    buildTests('testCommentSnippets075', '''
 p(x)=>0;var E;f(q)=>!1p(!2E);''', <String>["1+p", "2+E"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets076', '''
+    buildTests('testCommentSnippets076', '''
 class Map<K,V>{}class List<E>{}class int{}main() {var m=new Map<Lis!1t<Map<int,in!2t>>,List<!3int>>();}''',
         <String>["1+List", "2+int", "3+int"],
         failingTests: '123');
 
-    CompletionTestCase.buildTests('testCommentSnippets076a', '''
+    buildTests('testCommentSnippets076a', '''
 class Map<K,V>{}class List<E>{}class int{}main() {var m=new Map<Lis!1t<Map<int,in!2t>>,List<!3>>();}''',
         <String>["1+List", "2+int", "3+int"],
         failingTests: '123');
 
-    CompletionTestCase.buildTests('testCommentSnippets077', '''
+    buildTests('testCommentSnippets077', '''
 class FileMode {
   static const READ = const FileMode._internal(0);
   static const WRITE = const FileMode._internal(1);
@@ -617,58 +629,59 @@
             "1+FileMode._internal"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets078', '''
+    buildTests('testCommentSnippets078', '''
 class Map{static from()=>null;clear(){}}void main() { Map.!1 }''',
         <String>["1+from", "1-clear"]); // static method, instance method
 
-    CompletionTestCase.buildTests('testCommentSnippets079', '''
+    buildTests('testCommentSnippets079', '''
 class Map{static from()=>null;clear(){}}void main() { Map s; s.!1 }''',
-        <String>["1-from", "1+clear"]); // static method, instance method
+        <String>["1-from", "1+clear"],
+        failingTests: '1'); // static method, instance method
 
-    CompletionTestCase.buildTests('testCommentSnippets080', '''
+    buildTests('testCommentSnippets080', '''
 class RuntimeError{var message;}void main() { RuntimeError.!1 }''',
         <String>["1-message"]); // field
 
-    CompletionTestCase.buildTests('testCommentSnippets081', '''
-class Foo {this.!1}''', <String>["1-Object"]);
+    buildTests('testCommentSnippets081', '''
+class Foo {this.!1}''', <String>["1-Object"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets082', '''
+    buildTests('testCommentSnippets082', '''
         class HttpRequest {}
         class HttpResponse {}
         main() {
           var v = (HttpRequest req, HttpResp!1)
         }''', <String>["1+HttpResponse"]);
 
-    CompletionTestCase.buildTests('testCommentSnippets083', '''
-main() {(.!1)}''', <String>["1-toString"]);
+    buildTests('testCommentSnippets083', '''
+main() {(.!1)}''', <String>["1-toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets083a', '''
-main() { .!1 }''', <String>["1-toString"]);
+    buildTests('testCommentSnippets083a', '''
+main() { .!1 }''', <String>["1-toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets083b', '''
+    buildTests('testCommentSnippets083b', '''
 main() { null.!1 }''', <String>["1+toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets084', '''
+    buildTests('testCommentSnippets084', '''
 class List{}class Map{}typedef X = !1Lis!2t with !3Ma!4p;''',
         <String>["1+Map", "2+List", "2-Map", "3+List", "4+Map", "4-List"],
         failingTests: '1234');
 
-    CompletionTestCase.buildTests('testCommentSnippets085', '''
+    buildTests('testCommentSnippets085', '''
 class List{}class Map{}class Z extends List with !1Ma!2p {}''',
         <String>["1+List", "1+Map", "2+Map", "2-List"],
         failingTests: '12');
 
-    CompletionTestCase.buildTests('testCommentSnippets086', '''
+    buildTests('testCommentSnippets086', '''
 class Q{f(){xy() {!2};x!1y();}}''',
         <String>["1+xy", "2+f", "2-xy"],
-        failingTests: '1');
+        failingTests: '2');
 
-    CompletionTestCase.buildTests('testCommentSnippets087', '''
+    buildTests('testCommentSnippets087', '''
 class Map{}class Q extends Object with !1Map {}''',
         <String>["1+Map", "1-HashMap"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCommentSnippets088', '''
+    buildTests('testCommentSnippets088', '''
 class A {
   int f;
   B m(){}
@@ -682,7 +695,7 @@
   f() {q.!1}
 }''', <String>["1+f", "1+m"]); // f->num, m()->A
 
-    CompletionTestCase.buildTests('testCommentSnippets089', '''
+    buildTests('testCommentSnippets089', '''
 class Q {
   fqe() {
     xya() {
@@ -732,19 +745,19 @@
             "5-xya",
             "5-xyb",
             "5-xza"],
-        failingTests: '34');
+        failingTests: '123');
 
-    CompletionTestCase.buildTests('testCommentSnippets090', '''
+    buildTests('testCommentSnippets090', '''
 class X { f() { var a = 'x'; a.!1 }}''',
         <String>["1+length"],
         failingTests: '1');
   }
 
   void buildCompletionTests() {
-    CompletionTestCase.buildTests('testCompletion_alias_field', '''
+    buildTests('testCompletion_alias_field', '''
 typedef int fnint(int k); fn!1int x;''', <String>["1+fnint"]);
 
-    CompletionTestCase.buildTests('testCompletion_annotation_argumentList', '''
+    buildTests('testCompletion_annotation_argumentList', '''
 class AAA {",
   const AAA({int aaa, int bbb});",
 }",
@@ -755,16 +768,16 @@
         <String>["1+AAA" /*":" + ProposalKind.ARGUMENT_LIST*/, "1+aaa", "1+bbb"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_annotation_topLevelVar', '''
+    buildTests('testCompletion_annotation_topLevelVar', '''
 const fooConst = null;
 final fooNotConst = null;
 const bar = null;
 
 @foo!1
 main() {
-}''', <String>["1+fooConst", "1-fooNotConst", "1-bar"]);
+}''', <String>["1+fooConst", "1-fooNotConst", "1-bar"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_annotation_type', '''
+    buildTests('testCompletion_annotation_type', '''
 class AAA {
   const AAA({int a, int b});
   const AAA.nnn(int c, int d);
@@ -777,9 +790,7 @@
             "1+AAA.nnn" /*":" + ProposalKind.CONSTRUCTOR*/],
         failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_annotation_type_inClass_withoutMember',
-        '''
+    buildTests('testCompletion_annotation_type_inClass_withoutMember', '''
 class AAA {
   const AAA();
 }
@@ -788,7 +799,7 @@
   @A!1
 }''', <String>["1+AAA" /*":" + ProposalKind.CONSTRUCTOR*/]);
 
-    CompletionTestCase.buildTests('testCompletion_argument_typeName', '''
+    buildTests('testCompletion_argument_typeName', '''
 class Enum {
   static Enum FOO = new Enum();
 }
@@ -797,7 +808,7 @@
   f(En!1);
 }''', <String>["1+Enum"]);
 
-    CompletionTestCase.buildTests('testCompletion_arguments_ignoreEmpty', '''
+    buildTests('testCompletion_arguments_ignoreEmpty', '''
 class A {
   test() {}
 }
@@ -805,15 +816,13 @@
   a.test(!1);
 }''', <String>["1-test"]);
 
-    CompletionTestCase.buildTests('testCompletion_as_asIdentifierPrefix', '''
+    buildTests('testCompletion_as_asIdentifierPrefix', '''
 main(p) {
   var asVisible;
   var v = as!1;
 }''', <String>["1+asVisible"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_as_asPrefixedIdentifierStart',
-        '''
+    buildTests('testCompletion_as_asPrefixedIdentifierStart', '''
 class A {
   var asVisible;
 }
@@ -822,14 +831,14 @@
   var v = p.as!1;
 }''', <String>["1+asVisible"]);
 
-    CompletionTestCase.buildTests('testCompletion_as_incompleteStatement', '''
+    buildTests('testCompletion_as_incompleteStatement', '''
 class MyClass {}
 main(p) {
   var justSomeVar;
   var v = p as !1
-}''', <String>["1+MyClass", "1-justSomeVar"]);
+}''', <String>["1+MyClass", "1-justSomeVar"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_cascade', '''
+    buildTests('testCompletion_cascade', '''
 class A {
   aaa() {}
 }
@@ -839,42 +848,42 @@
   a..!1 aaa();
 }''', <String>["1+aaa", "1-main"]);
 
-    CompletionTestCase.buildTests('testCompletion_combinator_afterComma', '''
+    buildTests('testCompletion_combinator_afterComma', '''
 "import 'dart:math' show cos, !1;''',
         <String>["1+PI", "1+sin", "1+Random", "1-String"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_combinator_ended', '''
+    buildTests('testCompletion_combinator_ended', '''
 import 'dart:math' show !1;"''',
         <String>["1+PI", "1+sin", "1+Random", "1-String"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_combinator_export', '''
+    buildTests('testCompletion_combinator_export', '''
 export 'dart:math' show !1;"''',
         <String>["1+PI", "1+sin", "1+Random", "1-String"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_combinator_hide', '''
+    buildTests('testCompletion_combinator_hide', '''
 import 'dart:math' hide !1;"''',
         <String>["1+PI", "1+sin", "1+Random", "1-String"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_combinator_notEnded', '''
+    buildTests('testCompletion_combinator_notEnded', '''
 import 'dart:math' show !1"''',
         <String>["1+PI", "1+sin", "1+Random", "1-String"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_combinator_usePrefix', '''
+    buildTests('testCompletion_combinator_usePrefix', '''
 import 'dart:math' show s!1"''',
         <String>["1+sin", "1+sqrt", "1-cos", "1-String"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_constructor_field', '''
-class X { X(this.field); int f!1ield;}''', <String>["1+field"]);
+    buildTests('testCompletion_constructor_field', '''
+class X { X(this.field); int f!1ield;}''',
+        <String>["1+field"],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_constructorArguments_showOnlyCurrent',
-        '''
+    buildTests('testCompletion_constructorArguments_showOnlyCurrent', '''
 class A {
   A.first(int p);
   A.second(double p);
@@ -883,28 +892,22 @@
   new A.first(!1);
 }''', <String>["1+A.first", "1-A.second"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_constructorArguments_whenPrefixedType',
-        '''
+    buildTests('testCompletion_constructorArguments_whenPrefixedType', '''
 import 'dart:math' as m;
 main() {
   new m.Random(!1);
 }''', <String>["1+Random:ARGUMENT_LIST"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_dartDoc_reference_forClass',
-        '''
+    buildTests('testCompletion_dartDoc_reference_forClass', '''
 /**
  * [int!1]
  * [method!2]
  */
 class AAA {
   methodA() {}
-}''', <String>["1+int", "1-method", "2+methodA", "2-int"], failingTests: '1');
+}''', <String>["1+int", "1-method", "2+methodA", "2-int"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_dartDoc_reference_forConstructor',
-        '''
+    buildTests('testCompletion_dartDoc_reference_forConstructor', '''
 class A {
   /**
    * [aa!1]
@@ -915,11 +918,9 @@
   methodA() {}
 }''',
         <String>["1+aaa", "1-bbb", "2+int", "2-double", "3+methodA"],
-        failingTests: '12');
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_dartDoc_reference_forFunction',
-        '''
+    buildTests('testCompletion_dartDoc_reference_forFunction', '''
 /**
  * [aa!1]
  * [int!2]
@@ -935,11 +936,9 @@
             "3+functionA",
             "3+functionB",
             "3-int"],
-        failingTests: '12');
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_dartDoc_reference_forFunctionTypeAlias',
-        '''
+    buildTests('testCompletion_dartDoc_reference_forFunctionTypeAlias', '''
 /**
  * [aa!1]
  * [int!2]
@@ -955,11 +954,9 @@
             "3+FunctionA",
             "3+FunctionB",
             "3-int"],
-        failingTests: '12');
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_dartDoc_reference_forMethod',
-        '''
+    buildTests('testCompletion_dartDoc_reference_forMethod', '''
 class A {
   /**
    * [aa!1]
@@ -976,12 +973,9 @@
             "2-double",
             "3+methodA",
             "3+methodB",
-            "3-int"],
-        failingTests: '2');
+            "3-int"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_dartDoc_reference_incomplete',
-        '''
+    buildTests('testCompletion_dartDoc_reference_incomplete', '''
 /**
  * [doubl!1 some text
  * other text
@@ -996,23 +990,20 @@
  * [!3] some text
  */
 class C {}''',
-        <String>["1+double", "1-int", "2+int", "2+String", "3+int", "3+String"],
-        failingTests: '123');
+        <String>["1+double", "1-int", "2+int", "2+String", "3+int", "3+String"]);
 
-    CompletionTestCase.buildTests('testCompletion_double_inFractionPart', '''
+    buildTests('testCompletion_double_inFractionPart', '''
 main() {
   1.0!1
-}''', <String>["1-abs", "1-main"]);
+}''', <String>["1-abs", "1-main"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_enum', '''
+    buildTests('testCompletion_enum', '''
 enum MyEnum {A, B, C}
 main() {
   MyEnum.!1;
 }''', <String>["1+values", "1+A", "1+B", "1+C"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_exactPrefix_hasHigherRelevance',
-        '''
+    buildTests('testCompletion_exactPrefix_hasHigherRelevance', '''
 var STR;
 main(p) {
   var str;
@@ -1029,7 +1020,7 @@
             "3+STR" /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 0)*/,
             "3+str" /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 0)*/]);
 
-    CompletionTestCase.buildTests('testCompletion_export_dart', '''
+    buildTests('testCompletion_export_dart', '''
 import 'dart:math
 import 'dart:_chrome
 import 'dart:_collection.dev
@@ -1041,65 +1032,58 @@
             "1-dart:_collection.dev"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_export_noStringLiteral_noSemicolon',
-        '''
+    buildTests('testCompletion_export_noStringLiteral_noSemicolon', '''
 import !1
 
 class A {}''', <String>["1+'dart:!';", "1+'package:!';"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_forStmt_vars', '''
+    buildTests('testCompletion_forStmt_vars', '''
 class int{}class Foo { mth() { for (in!1t i = 0; i!2 < 5; i!3++); }}''',
         <String>["1+int", "2+i", "3+i"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_function', '''
-class String{}class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1) => a.compareTo(b)); }}''',
+    buildTests('testCompletion_function', '''
+class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1) => a.compareTo(b)); }}''',
         <String>["1+String"]);
 
-    CompletionTestCase.buildTests('testCompletion_function_partial', '''
-class String{}class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1)); }}''',
-        <String>["1+String"],
-        failingTests: '1');
+    buildTests('testCompletion_function_partial', '''
+class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1)); }}''',
+        <String>["1+String"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_functionTypeParameter_namedArgument',
-        '''
+    buildTests('testCompletion_functionTypeParameter_namedArgument', '''
 typedef FFF(a, b, {x1, x2, y});
 main(FFF fff) {
   fff(1, 2, !1)!2;
 }''', <String>["1+x1", "2-x2"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_field1', '''
+    buildTests('testCompletion_ifStmt_field1', '''
 class Foo { int myField = 7; mth() { if (!1) {}}}''', <String>["1+myField"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_field1a', '''
+    buildTests('testCompletion_ifStmt_field1a', '''
 class Foo { int myField = 7; mth() { if (!1) }}''', <String>["1+myField"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_field2', '''
+    buildTests('testCompletion_ifStmt_field2', '''
 class Foo { int myField = 7; mth() { if (m!1) {}}}''', <String>["1+myField"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_field2a', '''
+    buildTests('testCompletion_ifStmt_field2a', '''
 class Foo { int myField = 7; mth() { if (m!1) }}''', <String>["1+myField"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_field2b', '''
+    buildTests('testCompletion_ifStmt_field2b', '''
 class Foo { myField = 7; mth() { if (m!1) {}}}''', <String>["1+myField"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_localVar', '''
+    buildTests('testCompletion_ifStmt_localVar', '''
 class Foo { mth() { int value = 7; if (v!1) {}}}''', <String>["1+value"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_localVara', '''
+    buildTests('testCompletion_ifStmt_localVara', '''
 class Foo { mth() { value = 7; if (v!1) {}}}''', <String>["1-value"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_topLevelVar', '''
+    buildTests('testCompletion_ifStmt_topLevelVar', '''
 int topValue = 7; class Foo { mth() { if (t!1) {}}}''', <String>["1+topValue"]);
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_topLevelVara', '''
+    buildTests('testCompletion_ifStmt_topLevelVara', '''
 topValue = 7; class Foo { mth() { if (t!1) {}}}''', <String>["1+topValue"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_ifStmt_unionType_nonStrict',
-        '''
+    buildTests('testCompletion_ifStmt_unionType_nonStrict', '''
 class A { a() => null; x() => null}
 class B { a() => null; y() => null}
 void main() {
@@ -1113,7 +1097,7 @@
   x.!1;
 }''', <String>["1+a", "1+x", "1+y"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_ifStmt_unionType_strict', '''
+    buildTests('testCompletion_ifStmt_unionType_strict', '''
 class A { a() => null; x() => null}
 class B { a() => null; y() => null}
 void main() {
@@ -1127,10 +1111,10 @@
   x.!1;
 }''', <String>["1+a", "1-x", "1-y"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_import', '''
+    buildTests('testCompletion_import', '''
 import '!1';''', <String>["1+dart:!", "1+package:!"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_import_dart', '''
+    buildTests('testCompletion_import_dart', '''
 import 'dart:math
 import 'dart:_chrome
 import 'dart:_collection.dev
@@ -1142,35 +1126,29 @@
             "1-dart:_collection.dev"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_import_hasStringLiteral_noSemicolon',
-        '''
+    buildTests('testCompletion_import_hasStringLiteral_noSemicolon', '''
 import '!1'
 
 class A {}''', <String>["1+dart:!", "1+package:!"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_import_noSpace', '''
+    buildTests('testCompletion_import_noSpace', '''
 import!1''', <String>["1+ 'dart:!';", "1+ 'package:!';"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_import_noStringLiteral', '''
+    buildTests('testCompletion_import_noStringLiteral', '''
 import !1;''', <String>["1+'dart:!'", "1+'package:!'"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_import_noStringLiteral_noSemicolon',
-        '''
+    buildTests('testCompletion_import_noStringLiteral_noSemicolon', '''
 import !1
 
 class A {}''', <String>["1+'dart:!';", "1+'package:!';"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_incompleteClassMember', '''
+    buildTests('testCompletion_incompleteClassMember', '''
 class A {
   Str!1
   final f = null;
 }''', <String>["1+String", "1-bool"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_incompleteClosure_parameterType',
-        '''
+    buildTests('testCompletion_incompleteClosure_parameterType', '''
 f1(cb(String s)) {}
 f2(String s) {}
 main() {
@@ -1178,7 +1156,7 @@
   f2((Str!2));
 }''', <String>["1+String", "1-bool", "2+String", "2-bool"]);
 
-    CompletionTestCase.buildTests('testCompletion_inPeriodPeriod', '''
+    buildTests('testCompletion_inPeriodPeriod', '''
 main(String str) {
   1 < str.!1.length;
   1 + str.!2.length;
@@ -1188,9 +1166,7 @@
         failingTests: '123');
 
     // no checks, but no exceptions
-    CompletionTestCase.buildTests(
-        'testCompletion_instanceCreation_unresolved',
-        '''
+    buildTests('testCompletion_instanceCreation_unresolved', '''
 class A {
 }
 main() {
@@ -1198,12 +1174,12 @@
   new A.noSuchConstructor(!2);
 }''', <String>["1+int", "2+int"]);
 
-    CompletionTestCase.buildTests('testCompletion_import_lib', '''
+    buildTests('testCompletion_import_lib', '''
 import '!1''', <String>["1+my_lib.dart"], extraFiles: <String, String>{
       "/my_lib.dart": ""
     }, failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_is', '''
+    buildTests('testCompletion_is', '''
 class MyClass {}
 main(p) {
   var isVariable;
@@ -1215,16 +1191,14 @@
         <String>["1+MyClass", "2+MyClass", "3+MyClass", "3-v1", "4+is", "4-isVariable"],
         failingTests: '4');
 
-    CompletionTestCase.buildTests('testCompletion_is_asIdentifierStart', '''
+    buildTests('testCompletion_is_asIdentifierStart', '''
 main(p) {
   var isVisible;
   var v1 = is!1;
   var v2 = is!2
 }''', <String>["1+isVisible", "2+isVisible"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_is_asPrefixedIdentifierStart',
-        '''
+    buildTests('testCompletion_is_asPrefixedIdentifierStart', '''
 class A {
   var isVisible;
 }
@@ -1234,41 +1208,37 @@
   var v2 = p.is!2
 }''', <String>["1+isVisible", "2+isVisible"]);
 
-    CompletionTestCase.buildTests('testCompletion_is_incompleteStatement1', '''
+    buildTests('testCompletion_is_incompleteStatement1', '''
 class MyClass {}
 main(p) {
   var justSomeVar;
   var v = p is !1
-}''', <String>["1+MyClass", "1-justSomeVar"]);
+}''', <String>["1+MyClass", "1-justSomeVar"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_is_incompleteStatement2', '''
+    buildTests('testCompletion_is_incompleteStatement2', '''
 class MyClass {}
 main(p) {
   var isVariable;
   var v = p is!1
 }''', <String>["1+is", "1-isVariable"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_keyword_in', '''
+    buildTests('testCompletion_keyword_in', '''
 class Foo { int input = 7; mth() { if (in!1) {}}}''', <String>["1+input"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_keyword_syntheticIdentifier',
-        '''
+    buildTests('testCompletion_keyword_syntheticIdentifier', '''
 main() {
   var caseVar;
   var otherVar;
   var v = case!1
 }''', <String>["1+caseVar", "1-otherVar"]);
 
-    CompletionTestCase.buildTests('testCompletion_libraryIdentifier_atEOF', '''
-library int.!1''', <String>["1-parse", "1-bool"]);
+    buildTests('testCompletion_libraryIdentifier_atEOF', '''
+library int.!1''', <String>["1-parse", "1-bool"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_libraryIdentifier_notEOF', '''
-library int.!1''', <String>["1-parse", "1-bool"]);
+    buildTests('testCompletion_libraryIdentifier_notEOF', '''
+library int.!1''', <String>["1-parse", "1-bool"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_methodRef_asArg_incompatibleFunctionType',
-        '''
+    buildTests('testCompletion_methodRef_asArg_incompatibleFunctionType', '''
 foo( f(int p) ) {}
 class Functions {
   static myFuncInt(int p) {}
@@ -1280,11 +1250,10 @@
 }''',
         <String>[
             "1+myFuncInt" /*":" + ProposalKind.METHOD_NAME*/,
-            "1-myFuncDouble" /*":" + ProposalKind.METHOD_NAME*/]);
+            "1-myFuncDouble" /*":" + ProposalKind.METHOD_NAME*/],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_methodRef_asArg_notFunctionType',
-        '''
+    buildTests('testCompletion_methodRef_asArg_notFunctionType', '''
 foo( f(int p) ) {}
 class Functions {
   static myFunc(int p) {}
@@ -1295,11 +1264,10 @@
 }''',
         <String>[
             "1+myFunc" /*":" + ProposalKind.METHOD*/,
-            "1-myFunc" /*":" + ProposalKind.METHOD_NAME*/]);
+            "1-myFunc" /*":" + ProposalKind.METHOD_NAME*/],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_methodRef_asArg_ofFunctionType',
-        '''
+    buildTests('testCompletion_methodRef_asArg_ofFunctionType', '''
 foo( f(int p) ) {}
 class Functions {
   static int myFunc(int p) {}
@@ -1311,60 +1279,52 @@
             "1+myFunc" /*":" + ProposalKind.METHOD*/,
             "1+myFunc" /*":" + ProposalKind.METHOD_NAME*/]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_namedArgument_alreadyUsed',
-        '''
+    buildTests('testCompletion_namedArgument_alreadyUsed', '''
 func({foo}) {} main() { func(foo: 0, fo!1); }''', <String>["1-foo"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_namedArgument_constructor',
-        '''
+    buildTests('testCompletion_namedArgument_constructor', '''
 class A {A({foo, bar}) {}} main() { new A(fo!1); }''',
         <String>["1+foo", "1-bar"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_namedArgument_empty', '''
+    buildTests('testCompletion_namedArgument_empty', '''
 func({foo, bar}) {} main() { func(!1); }''',
         <String>[
             "1+foo" /*":" + ProposalKind.NAMED_ARGUMENT*/,
             "1-foo" /*":" + ProposalKind.OPTIONAL_ARGUMENT*/],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_namedArgument_function', '''
+    buildTests('testCompletion_namedArgument_function', '''
 func({foo, bar}) {} main() { func(fo!1); }''',
         <String>["1+foo", "1-bar"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_namedArgument_notNamed', '''
+    buildTests('testCompletion_namedArgument_notNamed', '''
 func([foo]) {} main() { func(fo!1); }''', <String>["1-foo"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_namedArgument_unresolvedFunction',
-        '''
+    buildTests('testCompletion_namedArgument_unresolvedFunction', '''
 main() { func(fo!1); }''', <String>["1-foo"]);
 
-    CompletionTestCase.buildTests('testCompletion_newMemberType1', '''
+    buildTests('testCompletion_newMemberType1', '''
 class Collection{}class List extends Collection{}class Foo { !1 }''',
         <String>["1+Collection", "1+List"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_newMemberType2', '''
+    buildTests('testCompletion_newMemberType2', '''
 class Collection{}class List extends Collection{}class Foo {!1}''',
         <String>["1+Collection", "1+List"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_newMemberType3', '''
+    buildTests('testCompletion_newMemberType3', '''
 class Collection{}class List extends Collection{}class Foo {L!1}''',
         <String>["1-Collection", "1+List"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_newMemberType4', '''
+    buildTests('testCompletion_newMemberType4', '''
 class Collection{}class List extends Collection{}class Foo {C!1}''',
         <String>["1+Collection", "1-List"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_positionalArgument_constructor',
-        '''
+    buildTests('testCompletion_positionalArgument_constructor', '''
 class A {
   A([foo, bar]);
 }
@@ -1379,9 +1339,7 @@
             "2+bar" /*":"
         + ProposalKind.OPTIONAL_ARGUMENT*/], failingTests: '12');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_positionalArgument_function',
-        '''
+    buildTests('testCompletion_positionalArgument_function', '''
 func([foo, bar]) {}
 main() {
   func(!1);
@@ -1394,7 +1352,7 @@
             "2+bar" /*":"
         + ProposalKind.OPTIONAL_ARGUMENT*/], failingTests: '12');
 
-    CompletionTestCase.buildTests('testCompletion_preferStaticType', '''
+    buildTests('testCompletion_preferStaticType', '''
 class A {
   foo() {}
 }
@@ -1411,20 +1369,16 @@
             "1+bar,potential=true,declaringType=B"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_privateElement_sameLibrary_constructor',
-        '''
+    buildTests('testCompletion_privateElement_sameLibrary_constructor', '''
 class A {
   A._c();
   A.c();
 }
 main() {
   new A.!1
-}''', <String>["1+_c", "1+c"], failingTests: '1');
+}''', <String>["1+_c", "1+c"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_privateElement_sameLibrary_member',
-        '''
+    buildTests('testCompletion_privateElement_sameLibrary_member', '''
 class A {
   _m() {}
   m() {}
@@ -1433,9 +1387,7 @@
   a.!1
 }''', <String>["1+_m", "1+m"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_propertyAccess_whenClassTarget',
-        '''
+    buildTests('testCompletion_propertyAccess_whenClassTarget', '''
 class A {
   static int FIELD;
   int field;
@@ -1444,9 +1396,7 @@
   A.!1
 }''', <String>["1+FIELD", "1-field"]);
 
-    CompletionTestCase.buildTests(
-        'testCompletion_propertyAccess_whenClassTarget_excludeSuper',
-        '''
+    buildTests('testCompletion_propertyAccess_whenClassTarget_excludeSuper', '''
 class A {
   static int FIELD_A;
   static int methodA() {}
@@ -1457,11 +1407,11 @@
 }
 main() {
   B.!1;
-}''', <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"]);
+}''',
+        <String>["1+FIELD_B", "1-FIELD_A", "1+methodB", "1-methodA"],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_propertyAccess_whenInstanceTarget',
-        '''
+    buildTests('testCompletion_propertyAccess_whenInstanceTarget', '''
 class A {
   static int FIELD;
   int fieldA;
@@ -1475,22 +1425,22 @@
 main(B b, C c) {
   b.a.!1;
   c.!2;
-}''', <String>["1-FIELD", "1+fieldA", "2+fieldC", "2+fieldA"]);
+}''',
+        <String>["1-FIELD", "1+fieldA", "2+fieldC", "2+fieldA"],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_return_withIdentifierPrefix',
-        '''
+    buildTests('testCompletion_return_withIdentifierPrefix', '''
 f() { var vvv = 42; return v!1 }''', <String>["1+vvv"]);
 
-    CompletionTestCase.buildTests('testCompletion_return_withoutExpression', '''
+    buildTests('testCompletion_return_withoutExpression', '''
 f() { var vvv = 42; return !1 }''', <String>["1+vvv"]);
 
-    CompletionTestCase.buildTests('testCompletion_staticField1', '''
+    buildTests('testCompletion_staticField1', '''
 class num{}class Sunflower {static final n!2um MAX_D = 300;nu!3m xc, yc;Sun!4flower() {x!Xc = y!Yc = MA!1 }}''',
         <String>["1+MAX_D", "X+xc", "Y+yc", "2+num", "3+num", "4+Sunflower"],
-        failingTests: '23');
+        failingTests: '234');
 
-    CompletionTestCase.buildTests('testCompletion_super_superType', '''
+    buildTests('testCompletion_super_superType', '''
 class A {
   var fa;
   ma() {}
@@ -1501,11 +1451,9 @@
   main() {
     super.!1
   }
-}''', <String>["1+fa", "1-fb", "1+ma", "1-mb"]);
+}''', <String>["1+fa", "1-fb", "1+ma", "1-mb"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_superConstructorInvocation_noNamePrefix',
-        '''
+    buildTests('testCompletion_superConstructorInvocation_noNamePrefix', '''
 class A {
   A.fooA();
   A.fooB();
@@ -1515,9 +1463,7 @@
   B() : super.!1
 }''', <String>["1+fooA", "1+fooB", "1+bar"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_superConstructorInvocation_withNamePrefix',
-        '''
+    buildTests('testCompletion_superConstructorInvocation_withNamePrefix', '''
 class A {
   A.fooA();
   A.fooB();
@@ -1527,43 +1473,33 @@
   B() : super.f!1
 }''', <String>["1+fooA", "1+fooB", "1-bar"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_this_bad_inConstructorInitializer',
-        '''
+    buildTests('testCompletion_this_bad_inConstructorInitializer', '''
 class A {
   var f;
   A() : f = this.!1;
-}''', <String>["1-toString"]);
+}''', <String>["1-toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_this_bad_inFieldDeclaration',
-        '''
+    buildTests('testCompletion_this_bad_inFieldDeclaration', '''
 class A {
   var f = this.!1;
-}''', <String>["1-toString"]);
+}''', <String>["1-toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_this_bad_inStaticMethod', '''
+    buildTests('testCompletion_this_bad_inStaticMethod', '''
 class A {
   static m() {
     this.!1;
   }
-}''', <String>["1-toString"]);
+}''', <String>["1-toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_this_bad_inTopLevelFunction',
-        '''
+    buildTests('testCompletion_this_bad_inTopLevelFunction', '''
 main() {
   this.!1;
-}''', <String>["1-toString"]);
+}''', <String>["1-toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_this_bad_inTopLevelVariableDeclaration',
-        '''
-var v = this.!1;''', <String>["1-toString"]);
+    buildTests('testCompletion_this_bad_inTopLevelVariableDeclaration', '''
+var v = this.!1;''', <String>["1-toString"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
-        'testCompletion_this_OK_inConstructorBody',
-        '''
+    buildTests('testCompletion_this_OK_inConstructorBody', '''
 class A {
   var f;
   m() {}
@@ -1572,7 +1508,7 @@
   }
 }''', <String>["1+f", "1+m"]);
 
-    CompletionTestCase.buildTests('testCompletion_this_OK_localAndSuper', '''
+    buildTests('testCompletion_this_OK_localAndSuper', '''
 class A {
   var fa;
   ma() {}
@@ -1585,19 +1521,19 @@
   }
 }''', <String>["1+fa", "1+fb", "1+ma", "1+mb"]);
 
-    CompletionTestCase.buildTests('testCompletion_topLevelField_init2', '''
+    buildTests('testCompletion_topLevelField_init2', '''
 class DateTime{static var JUN;}final num M = Dat!1eTime.JUN;''',
         <String>["1+DateTime", "1-void"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('testCompletion_while', '''
+    buildTests('testCompletion_while', '''
 class Foo { int boo = 7; mth() { while (b!1) {} }}''', <String>["1+boo"]);
   }
 
   void buildLibraryTests() {
     Map<String, String> sources = new HashMap<String, String>();
 
-    CompletionTestCase.buildTests('test_export_ignoreIfThisLibraryExports', '''
+    buildTests('test_export_ignoreIfThisLibraryExports', '''
 export 'dart:math';
 libFunction() {};
 main() {
@@ -1609,9 +1545,7 @@
 library lib;
 export 'dart:math' hide sin;
 libFunction() {};''';
-    CompletionTestCase.buildTests(
-        'test_export_showIfImportLibraryWithExport',
-        '''
+    buildTests('test_export_showIfImportLibraryWithExport', '''
 import 'lib.dart' as p;
 main() {
   p.!1
@@ -1620,13 +1554,13 @@
         extraFiles: sources,
         failingTests: '1');
 
-    CompletionTestCase.buildTests('test_importPrefix_hideCombinator', '''
+    buildTests('test_importPrefix_hideCombinator', '''
 import 'dart:math' as math hide PI;
 main() {
   math.!1
 }''', <String>["1-PI", "1+LN10"], failingTests: '1');
 
-    CompletionTestCase.buildTests('test_importPrefix_showCombinator', '''
+    buildTests('test_importPrefix_showCombinator', '''
 import 'dart:math' as math show PI;
 main() {
   math.!1
@@ -1640,7 +1574,7 @@
 
 class A extends _A {
 }''';
-    CompletionTestCase.buildTests('test_memberOfPrivateClass_otherLibrary', '''
+    buildTests('test_memberOfPrivateClass_otherLibrary', '''
 import 'lib.dart';
 main(A a) {
   a.!1
@@ -1653,9 +1587,7 @@
   A.c();
   A._c();
 }''';
-    CompletionTestCase.buildTests(
-        'test_noPrivateElement_otherLibrary_constructor',
-        '''
+    buildTests('test_noPrivateElement_otherLibrary_constructor', '''
 import 'lib.dart';
 main() {
   new A.!1
@@ -1668,9 +1600,7 @@
   var f;
   var _f;
 }''';
-    CompletionTestCase.buildTests(
-        'test_noPrivateElement_otherLibrary_member',
-        '''
+    buildTests('test_noPrivateElement_otherLibrary_member', '''
               import 'lib.dart';
               main(A a) {
                 a.!1
@@ -1685,7 +1615,7 @@
 class SerializationException {
   const SerializationException();
 }''';
-    CompletionTestCase.buildTests('test001', '''
+    buildTests('test001', '''
 import 'firth.dart';
 main() {
 throw new Seria!1lizationException();}''',
@@ -1695,14 +1625,14 @@
 
     // Type propagation.
     // TODO Include corelib analysis (this works in the editor)
-    CompletionTestCase.buildTests(
+    buildTests(
         'test002',
         '''t2() {var q=[0],z=q.!1length;q.!2clear();}''',
         <String>["1+length", "1+isEmpty", "2+clear"],
         failingTests: '12');
 
     // TODO Include corelib analysis
-    CompletionTestCase.buildTests(
+    buildTests(
         'test003',
         '''class X{var q; f() {q.!1a!2}}''',
         <String>["1+end", "2+abs", "2-end"],
@@ -1710,7 +1640,7 @@
 
     // TODO Include corelib analysis
     // Resolving dart:html takes between 2.5s and 30s; json, about 0.12s
-    CompletionTestCase.buildTests('test004', '''
+    buildTests('test004', '''
             library foo;
             import 'dart:convert' as json;
             class JsonParserX{}
@@ -1728,7 +1658,7 @@
 
     // TODO Enable after type propagation is implemented. Not yet.
     // TODO Include corelib analysis
-    CompletionTestCase.buildTests(
+    buildTests(
         'test005',
         '''var PHI;main(){PHI=5.3;PHI.abs().!1 Object x;}''',
         <String>["1+abs"],
@@ -1755,7 +1685,7 @@
 library imp2;
 export 'exp2a.dart';
 i2() {}''';
-    CompletionTestCase.buildTests('test006', '''
+    buildTests('test006', '''
 import 'imp1.dart';
 import 'imp2.dart';
 main() {!1
@@ -1775,7 +1705,7 @@
     sources["/l1.dart"] = '''
 library l1;
 var _l1t; var l1t;''';
-    CompletionTestCase.buildTests('test007', '''
+    buildTests('test007', '''
 import 'l1.dart';
 main() {
   var x = l!1
@@ -1800,7 +1730,7 @@
   void privateMethod() {
   }
 }''';
-    CompletionTestCase.buildTests('test008', '''
+    buildTests('test008', '''
 import 'private.dart';
 import 'public.dart';
 class Test {
@@ -1820,7 +1750,7 @@
 int X = 1;
 void m(){}
 class Y {}''';
-    CompletionTestCase.buildTests('test009', '''
+    buildTests('test009', '''
 import 'lib.dart' as Q;
 void a() {
   var x = Q.!1
@@ -1852,7 +1782,7 @@
   }
 
   void buildNumberedTests() {
-    CompletionTestCase.buildTests('test001', '''
+    buildTests('test001', '''
 void r1(var v) {
   v.!1toString!2().!3hash!4Code
 }''',
@@ -1863,30 +1793,29 @@
             "3+hashCode",
             "3+toString",
             "4+hashCode",
-            "4-toString"],
-        failingTests: '1234');
+            "4-toString"]);
 
-    CompletionTestCase.buildTests('test002', '''
+    buildTests('test002', '''
 void r2(var vim) {
   v!1.toString()
 }''', <String>["1+vim"]);
 
-    CompletionTestCase.buildTests('test003', '''
+    buildTests('test003', '''
 class A {
   int a() => 3;
   int b() => this.!1a();
 }''', <String>["1+a"]);
 
-    CompletionTestCase.buildTests('test004', '''
+    buildTests('test004', '''
 class A {
   int x;
   A() : this.!1x = 1;
   A.b() : this();
   A.c() : this.!2b();
   g() => new A.!3c();
-}''', <String>["1+x", "2+b", "3+c"], failingTests: '23');
+}''', <String>["1+x", "2+b", "3+c"], failingTests: '12');
 
-    CompletionTestCase.buildTests('test005', '''
+    buildTests('test005', '''
 class A {}
 void rr(var vim) {
   var !1vq = v!2.toString();
@@ -1916,18 +1845,18 @@
             "3-A"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests('test006', '''
+    buildTests('test006', '''
 void r2(var vim, {va: 2, b: 3}) {
   v!1.toString()
 }''', <String>["1+va", "1-b"]);
 
-    CompletionTestCase.buildTests('test007', '''
+    buildTests('test007', '''
 void r2(var vim, [va: 2, b: 3]) {
   v!1.toString()
 }''', <String>["1+va", "1-b"]);
 
     // keywords
-    CompletionTestCase.buildTests('test008', '''
+    buildTests('test008', '''
 !1class Aclass {}
 class Bclass !2extends!3 !4Aclass {}
 !5typedef Ctype = !6Bclass with !7Aclass;
@@ -1956,11 +1885,10 @@
             "B-Ctype",
             "C+Bclass",
             "C-Eclass"],
-        failingTests: '12359A');
+        failingTests: '12345679ABC');
 
     // keywords
-    CompletionTestCase.buildTests('test009', '''
-class num{}
+    buildTests('test009', '''
 typedef !1dy!2namic TestFn1();
 typedef !3vo!4id TestFn2();
 typ!7edef !5n!6''',
@@ -1977,8 +1905,7 @@
             "7+typedef"],
         failingTests: '12347');
 
-    CompletionTestCase.buildTests('test010', '''
-class String{}class List{}
+    buildTests('test010', '''
 class test !8<!1t !2 !3extends String,!4 List,!5 !6>!7 {}
 class tezetst !9<!BString,!C !DList>!A {}''',
         <String>[
@@ -2001,17 +1928,17 @@
             "C-tezetst",
             "D+List",
             "D+test"],
-        failingTests: '3');
+        failingTests: '12345C');
 
     // name generation with conflicts
-    CompletionTestCase.buildTests(
+    buildTests(
         'test011',
         '''r2(var object, Object object1, Object !1);''',
         <String>["1+object2"],
         failingTests: '1');
 
     // reserved words
-    CompletionTestCase.buildTests('test012', '''
+    buildTests('test012', '''
 class X {
   f() {
     g(!1var!2 z) {!3true.!4toString();};
@@ -2026,10 +1953,10 @@
             "3+false",
             "3+true",
             "4+toString"],
-        failingTests: '1234');
+        failingTests: '123');
 
     // conditions & operators
-    CompletionTestCase.buildTests('test013', '''
+    buildTests('test013', '''
 class Q {
   bool x;
   List zs;
@@ -2057,10 +1984,10 @@
             "8+==",
             "9+==",
             "0+k"],
-        failingTests: '689');
+        failingTests: '5689');
 
     // keywords
-    CompletionTestCase.buildTests('test014', '''
+    buildTests('test014', '''
 class Q {
   bool x;
   List zs;
@@ -2103,21 +2030,21 @@
         failingTests: '123456789ABCDEFGHJKL');
 
     // operators in function
-    CompletionTestCase.buildTests(
+    buildTests(
         'test015',
         '''f(a,b,c) => a + b * c !1;''',
         <String>["1+=="],
         failingTests: '1');
 
     // operators in return
-    CompletionTestCase.buildTests(
+    buildTests(
         'test016',
         '''class X {dynamic f(a,b,c) {return a + b * c !1;}}''',
         <String>["1+=="],
         failingTests: '1');
 
     // keywords
-    CompletionTestCase.buildTests('test017', '''
+    buildTests('test017', '''
 !1library foo;
 !2import 'x' !5as r;
 !3export '!8uri' !6hide Q !7show X;
@@ -2133,39 +2060,39 @@
             "8-null"],
         failingTests: '1234567');
 
-    // The following test is disabled because it prevents the Dart VM from
-    // exiting, for some unknown reason.  TODO(paulberry): fix this.
-//    // keywords
-//    CompletionTestCase.buildTests(
-//        'test018',
-//        '''!1part !2of foo;''',
-//        <String>["1+part", "2+of"],
-//        failingTests: '12');
+    // keywords
+    buildTests(
+        'test018',
+        '''!1part !2of foo;''',
+        <String>["1+part", "2+of"],
+        failingTests: '12');
 
-    CompletionTestCase.buildTests('test019', '''
+    buildTests('test019', '''
 var truefalse = 0;
 var falsetrue = 1;
 main() {
   var foo = true!1
 }''', <String>["1+true", "1+truefalse", "1-falsetrue"], failingTests: '1');
 
-    CompletionTestCase.buildTests(
+    buildTests(
         'test020',
         '''var x = null.!1''',
         <String>["1+toString"],
         failingTests: '1');
 
-    CompletionTestCase.buildTests(
+    buildTests(
         'test021',
         '''var x = .!1''',
-        <String>["1-toString"]);
+        <String>["1-toString"],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests(
+    buildTests(
         'test022',
         '''var x = .!1;''',
-        <String>["1-toString"]);
+        <String>["1-toString"],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests('test023', '''
+    buildTests('test023', '''
 class Map{getKeys(){}}
 class X {
   static x1(Map m) {
@@ -2177,15 +2104,15 @@
 }''', <String>["1+getKeys", "2+getKeys"]);
 
 // Note lack of semicolon following completion location
-    CompletionTestCase.buildTests('test024', '''
+    buildTests('test024', '''
 class List{factory List.from(Iterable other) {}}
 class F {
   f() {
     new List.!1
   }
-}''', <String>["1+from"], failingTests: '1');
+}''', <String>["1+from"]);
 
-    CompletionTestCase.buildTests('test025', '''
+    buildTests('test025', '''
 class R {
   static R _m;
   static R m;
@@ -2233,39 +2160,29 @@
             "C+g",
             "D+_m",
             "E+m",
-            "F+g"]);
+            "F+g"],
+        failingTests: '789');
 
-    CompletionTestCase.buildTests(
-        'test026',
-        '''var aBcD; var x=ab!1''',
-        <String>["1+aBcD"]);
+    buildTests('test026', '''var aBcD; var x=ab!1''', <String>["1+aBcD"]);
 
-    CompletionTestCase.buildTests(
+    buildTests(
         'test027',
         '''m(){try{}catch(eeee,ssss){s!1}''',
         <String>["1+ssss"]);
 
-    CompletionTestCase.buildTests(
-        'test028',
-        '''m(){var isX=3;if(is!1)''',
-        <String>["1+isX"]);
+    buildTests('test028', '''m(){var isX=3;if(is!1)''', <String>["1+isX"]);
 
-    CompletionTestCase.buildTests(
-        'test029',
-        '''m(){[1].forEach((x)=>!1x);}''',
-        <String>["1+x"]);
+    buildTests('test029', '''m(){[1].forEach((x)=>!1x);}''', <String>["1+x"]);
 
-    CompletionTestCase.buildTests(
-        'test030',
-        '''n(){[1].forEach((x){!1});}''',
-        <String>["1+x"]);
+    buildTests('test030', '''n(){[1].forEach((x){!1});}''', <String>["1+x"]);
 
-    CompletionTestCase.buildTests(
+    buildTests(
         'test031',
         '''class Caster {} m() {try {} on Cas!1ter catch (CastBlock) {!2}}''',
-        <String>["1+Caster", "1-CastBlock", "2+Caster", "2+CastBlock"]);
+        <String>["1+Caster", "1-CastBlock", "2+Caster", "2+CastBlock"],
+        failingTests: '1');
 
-    CompletionTestCase.buildTests('test032', '''
+    buildTests('test032', '''
 const ONE = 1;
 const ICHI = 10;
 const UKSI = 100;
@@ -2290,7 +2207,7 @@
             "3+EIN",
             "3+ONE"]);
 
-    CompletionTestCase.buildTests(
+    buildTests(
         'test033',
         '''class A{}class B extends A{b(){}}class C implements A {c(){}}class X{x(){A f;f.!1}}''',
         <String>["1+b", "1-c"],
@@ -2299,7 +2216,7 @@
     // TODO(scheglov) decide what to do with Type for untyped field (not
     // supported by the new store)
     // test analysis of untyped fields and top-level vars
-    CompletionTestCase.buildTests('test034', '''
+    buildTests('test034', '''
 var topvar;
 class Top {top(){}}
 class Left extends Top {left(){}}
@@ -2325,7 +2242,7 @@
 }''', <String>["1+top", "2+top"], failingTests: '12');
 
     // test analysis of untyped fields and top-level vars
-    CompletionTestCase.buildTests(
+    buildTests(
         'test035',
         '''class Y {final x='hi';mth() {x.!1length;}}''',
         <String>["1+length"],
@@ -2334,7 +2251,7 @@
     // TODO(scheglov) decide what to do with Type for untyped field (not
     // supported by the new store)
     // test analysis of untyped fields and top-level vars
-    CompletionTestCase.buildTests('test036', '''
+    buildTests('test036', '''
 class A1 {
   var field;
   A1() : field = 0;
@@ -2348,14 +2265,14 @@
   a.field.!2
 }''', <String>["1+round", "2+round"], failingTests: '12');
 
-    CompletionTestCase.buildTests('test037', '''
+    buildTests('test037', '''
 class HttpServer{}
 class HttpClient{}
 main() {
   new HtS!1
-}''', <String>["1+HttpServer", "1-HttpClient"]);
+}''', <String>["1+HttpServer", "1-HttpClient"], failingTests: '1');
 
-    CompletionTestCase.buildTests('test038', '''
+    buildTests('test038', '''
 class X {
   x(){}
 }
@@ -2372,27 +2289,27 @@
 }''', <String>["1+y", "1-x", "2+x", "2-y"], failingTests: '2');
 
     // test analysis of untyped fields and top-level vars
-    CompletionTestCase.buildTests(
+    buildTests(
         'test039',
         '''class X{}var x = null as !1X;''',
         <String>["1+X", "1-void"]);
 
     // test arg lists with named params
-    CompletionTestCase.buildTests(
+    buildTests(
         'test040',
         '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1)!2;}''',
         <String>["1+x1", "2-x2"],
         failingTests: '1');
 
     // test arg lists with named params
-    CompletionTestCase.buildTests(
+    buildTests(
         'test041',
         '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1''',
         <String>["1+x1", "1+x2", "1+y"],
         failingTests: '1');
 
     // test arg lists with named params
-    CompletionTestCase.buildTests(
+    buildTests(
         'test042',
         '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1;!2''',
         <String>["1+x1", "1+x2", "2-y"],
@@ -2400,14 +2317,77 @@
   }
 
   void buildOtherTests() {
-    CompletionTestCase.buildTests(
+    buildTests(
         'test_classMembers_inGetter',
         '''class A { var fff; get z {ff!1}}''',
         <String>["1+fff"]);
 
-    CompletionTestCase.buildTests(
+    buildTests(
         'testSingle',
         '''class A {int x; !2mth() {int y = this.x;}}class B{}''',
         <String>["2+B"]);
   }
+
+  /**
+   * Generate a set of completion tests based on the given [originalSource].
+   *
+   * The source string has completion points embedded in it, which are
+   * identified by '!X' where X is a single character. Each X is matched to
+   * positive or negative results in the array of [validationStrings].
+   * Validation strings contain the name of a prediction with a two character
+   * prefix. The first character of the prefix corresponds to an X in the
+   * [originalSource]. The second character is either a '+' or a '-' indicating
+   * whether the string is a positive or negative result.
+   *
+   * The [originalSource] is the source for a completion test that contains
+   * completion points. The [validationStrings] are the positive and negative
+   * predictions.
+   *
+   * Optional argument [failingTests], if given, is a string, each character of
+   * which corresponds to an X in the [originalSource] for which the test is
+   * expected to fail.  This sould be used to mark known completion bugs that
+   * have not yet been fixed.
+   */
+  void buildTests(String baseName, String originalSource, List<String> results,
+      {Map<String, String> extraFiles, String failingTests: ''}) {
+    List<LocationSpec> completionTests =
+        LocationSpec.from(originalSource, results);
+    completionTests.sort((LocationSpec first, LocationSpec second) {
+      return first.id.compareTo(second.id);
+    });
+    if (completionTests.isEmpty) {
+      test(baseName, () {
+        fail(
+            "Expected exclamation point ('!') within the source denoting the"
+                "position at which code completion should occur");
+      });
+    }
+    Set<String> allSpecIds =
+        completionTests.map((LocationSpec spec) => spec.id).toSet();
+    for (String id in failingTests.split('')) {
+      if (!allSpecIds.contains(id)) {
+        test("$baseName-$id", () {
+          fail(
+              "Test case '$id' included in failingTests, but this id does not exist.");
+        });
+      }
+    }
+    for (LocationSpec spec in completionTests) {
+      if (failingTests.contains(spec.id)) {
+        ++expectedFailCount;
+        test("$baseName-${spec.id} (expected failure)", () {
+          CompletionTestCase test = new CompletionTestCase();
+          return new Future(() => test.runTest(spec, extraFiles)).then((_) {
+            fail('Test passed - expected to fail.');
+          }, onError: (_) {});
+        });
+      } else {
+        ++expectedPassCount;
+        test("$baseName-${spec.id}", () {
+          CompletionTestCase test = new CompletionTestCase();
+          return test.runTest(spec, extraFiles);
+        });
+      }
+    }
+  }
 }
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index bca1b38..d9fb3c6 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -4,6 +4,7 @@
 
 library test.completion.support;
 
+import 'dart:async';
 import 'dart:collection';
 
 import 'package:analysis_server/src/protocol.dart';
@@ -11,7 +12,6 @@
 import 'package:unittest/unittest.dart';
 
 import 'domain_completion_test.dart';
-import 'dart:async';
 
 /**
  * A base class for classes containing completion tests.
@@ -53,9 +53,6 @@
   }
 
   void assertHasNoCompletion(String completion) {
-    // As a temporary measure, disable negative tests.
-    // TODO(paulberry): fix this.
-    return;
     if (suggestions.any(
         (CompletionSuggestion suggestion) => suggestion.completion == completion)) {
       fail(
@@ -63,6 +60,18 @@
     }
   }
 
+  /**
+   * Discard any results that do not start with the characters the user has
+   * "already typed".
+   */
+  void filterResults(String content) {
+    String charsAlreadyTyped =
+        content.substring(replacementOffset, completionOffset).toLowerCase();
+    suggestions = suggestions.where(
+        (CompletionSuggestion suggestion) =>
+            suggestion.completion.toLowerCase().startsWith(charsAlreadyTyped)).toList();
+  }
+
   runTest(LocationSpec spec, [Map<String, String> extraFiles]) {
     super.setUp();
     return new Future(() {
@@ -76,8 +85,7 @@
         });
       }
     }).then((_) => getSuggestions()).then((_) {
-      //expect(replacementOffset, equals(completionOffset));
-      //expect(replacementLength, equals(0));
+      filterResults(spec.source);
       for (String result in spec.positiveResults) {
         assertHasCompletion(result);
       }
@@ -88,68 +96,6 @@
       super.tearDown();
     });
   }
-
-  /**
-   * Generate a set of completion tests based on the given [originalSource].
-   *
-   * The source string has completion points embedded in it, which are
-   * identified by '!X' where X is a single character. Each X is matched to
-   * positive or negative results in the array of [validationStrings].
-   * Validation strings contain the name of a prediction with a two character
-   * prefix. The first character of the prefix corresponds to an X in the
-   * [originalSource]. The second character is either a '+' or a '-' indicating
-   * whether the string is a positive or negative result.
-   *
-   * The [originalSource] is the source for a completion test that contains
-   * completion points. The [validationStrings] are the positive and negative
-   * predictions.
-   *
-   * Optional argument [failingTests], if given, is a string, each character of
-   * which corresponds to an X in the [originalSource] for which the test is
-   * expected to fail.  This sould be used to mark known completion bugs that
-   * have not yet been fixed.
-   */
-  static void buildTests(String baseName, String originalSource,
-      List<String> results, {Map<String, String> extraFiles, String failingTests:
-      ''}) {
-    List<LocationSpec> completionTests =
-        LocationSpec.from(originalSource, results);
-    completionTests.sort((LocationSpec first, LocationSpec second) {
-      return first.id.compareTo(second.id);
-    });
-    if (completionTests.isEmpty) {
-      test(baseName, () {
-        fail(
-            "Expected exclamation point ('!') within the source denoting the"
-                "position at which code completion should occur");
-      });
-    }
-    Set<String> allSpecIds =
-        completionTests.map((LocationSpec spec) => spec.id).toSet();
-    for (String id in failingTests.split('')) {
-      if (!allSpecIds.contains(id)) {
-        test("$baseName-$id", () {
-          fail(
-              "Test case '$id' included in failingTests, but this id does not exist.");
-        });
-      }
-    }
-    for (LocationSpec spec in completionTests) {
-      if (failingTests.contains(spec.id)) {
-        test("$baseName-${spec.id} (expected failure)", () {
-          CompletionTestCase test = new CompletionTestCase();
-          return new Future(() => test.runTest(spec, extraFiles)).then((_) {
-            fail('Test passed - expected to fail.');
-          }, onError: (_) {});
-        });
-      } else {
-        test("$baseName-${spec.id}", () {
-          CompletionTestCase test = new CompletionTestCase();
-          return test.runTest(spec, extraFiles);
-        });
-      }
-    }
-  }
 }
 
 /**
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 6f242c1..3489e67 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -41,7 +41,7 @@
         null,
         new AnalysisServerOptions(),
         new MockSdk(),
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
     handler = new AnalysisDomainHandler(server);
   });
 
@@ -179,7 +179,7 @@
     // wait, there are highlight regions
     helper.waitForOperationsFinished().then((_) {
       var highlights = helper.getHighlights(helper.testFile);
-      expect(highlights, isNot(isEmpty));
+      expect(highlights, isNotEmpty);
     });
   });
 
@@ -196,7 +196,7 @@
       // wait, has regions
       return helper.waitForOperationsFinished().then((_) {
         var highlights = helper.getHighlights(helper.testFile);
-        expect(highlights, isNot(isEmpty));
+        expect(highlights, isNotEmpty);
       });
     });
   });
@@ -226,7 +226,7 @@
       helper.addAnalysisSubscriptionNavigation(file);
       return helper.waitForOperationsFinished().then((_) {
         var navigationRegions = helper.getNavigation(file);
-        expect(navigationRegions, isNot(isEmpty));
+        expect(navigationRegions, isNotEmpty);
       });
     });
   });
@@ -396,7 +396,7 @@
     // Create project and wait for analysis
     createProject();
     return waitForTasksFinished().then((_) {
-      expect(filesErrors[testFile], isNot(isEmpty));
+      expect(filesErrors[testFile], isNotEmpty);
       // Add the package to the package map and tickle the package dependency.
       packageMapProvider.packageMap = {
         'pkgA': [resourceProvider.getResource('/packages/pkgA')]
@@ -464,7 +464,7 @@
         null,
         new AnalysisServerOptions(),
         new MockSdk(),
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
     handler = new AnalysisDomainHandler(server);
     // listen for notifications
     Stream<Notification> notificationStream =
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 95dd240..34246b7 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -51,7 +51,7 @@
         index,
         new AnalysisServerOptions(),
         new MockSdk(),
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
   }
 
   void sendRequest(String path) {
@@ -85,7 +85,8 @@
     expect(completionDomain.manager, isNull);
     sendRequest(testFile);
     expect(completionDomain.manager, isNotNull);
-    CompletionManager expectedManager = completionDomain.manager;
+    MockCompletionManager expectedManager = completionDomain.manager;
+    expect(expectedManager.disposeCallCount, 0);
     expect(completionDomain.mockContext.mockStream.listenCount, 1);
     expect(completionDomain.mockContext.mockStream.cancelCount, 0);
     return pumpEventQueue().then((_) {
@@ -94,6 +95,7 @@
       sendRequest(testFile2);
       expect(completionDomain.manager, isNotNull);
       expect(completionDomain.manager, isNot(expectedManager));
+      expect(expectedManager.disposeCallCount, 1);
       expectedManager = completionDomain.manager;
       expect(completionDomain.mockContext.mockStream.listenCount, 2);
       expect(completionDomain.mockContext.mockStream.cancelCount, 1);
@@ -401,6 +403,16 @@
     });
   }
 
+  test_local_named_constructor() {
+    addTestFile('class A {A.c(); x() {new A.^}}');
+    return getSuggestions().then((_) {
+      expect(replacementOffset, equals(completionOffset));
+      expect(replacementLength, equals(0));
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'c');
+      assertNoResult('A');
+    });
+  }
+
   test_locals() {
     addTestFile('class A {var a; x() {var b;^}}');
     return getSuggestions().then((_) {
@@ -422,7 +434,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset - 3));
       expect(replacementLength, equals(4));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
+      // Suggestions based upon imported elements are partially filtered
+      //assertHasResult(CompletionSuggestionKind.INVOCATION, 'Object');
       assertHasResult(CompletionSuggestionKind.INVOCATION, 'test');
       assertNoResult('HtmlElement');
     });
@@ -439,12 +452,13 @@
   final SearchEngine searchEngine;
   StreamController<CompletionResult> controller;
   int computeCallCount = 0;
+  int disposeCallCount = 0;
 
   MockCompletionManager(this.context, this.source, this.searchEngine);
 
   @override
-  void computeCache() {
-    // ignored
+  Future<bool> computeCache() {
+    return new Future.value(true);
   }
 
   @override
@@ -455,6 +469,11 @@
   }
 
   @override
+  void dispose() {
+    ++disposeCallCount;
+  }
+
+  @override
   Stream<CompletionResult> results(CompletionRequest request) {
     controller = new StreamController<CompletionResult>(onListen: () {
       scheduleMicrotask(() {
@@ -520,7 +539,7 @@
   Test_AnalysisServer(ServerCommunicationChannel channel,
       ResourceProvider resourceProvider, PackageMapProvider packageMapProvider,
       Index index, AnalysisServerOptions analysisServerOptions, DartSdk defaultSdk,
-      InstrumentationServer instrumentationServer)
+      InstrumentationService instrumentationService)
       : super(
           channel,
           resourceProvider,
@@ -528,7 +547,7 @@
           index,
           analysisServerOptions,
           defaultSdk,
-          instrumentationServer);
+          instrumentationService);
 
   AnalysisContext getAnalysisContext(String path) {
     return mockContext;
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index 96edfbe..dc912de 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -42,7 +42,7 @@
           null,
           new AnalysisServerOptions(),
           new MockSdk(),
-          new NullInstrumentationServer());
+          InstrumentationService.NULL_SERVICE);
       handler = new ExecutionDomainHandler(server);
     });
 
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index 1156b3f..19d3b66 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -29,7 +29,7 @@
         null,
         new AnalysisServerOptions(),
         new MockSdk(),
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
     handler = new ServerDomainHandler(server);
   });
 
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index cbfc511..814e563 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -437,6 +437,28 @@
     });
   }
 
+  test_init_fatalError_invalidStatement() {
+    addTestFile('''
+main(bool b) {
+// start
+  if (b) {
+    print(1);
+// end
+    print(2);
+  }
+}
+''');
+    _setOffsetLengthForStartEnd();
+    return waitForTasksFinished().then((_) {
+      return _sendExtractRequest();
+    }).then((Response response) {
+      var result = new EditGetRefactoringResult.fromResponse(response);
+      assertResultProblemsFatal(result.initialProblems);
+      // ...there is no any feedback
+      expect(result.feedback, isNull);
+    });
+  }
+
   test_names() {
     addTestFile('''
 class TreeItem {}
diff --git a/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart b/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart
index 7a979c2..d91a5b0 100644
--- a/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart
@@ -33,7 +33,7 @@
     });
     return analysisFinished.then((_) {
       // The overridden contents (badText) are missing quotation marks.
-      expect(currentAnalysisErrors[pathname], isNot(isEmpty));
+      expect(currentAnalysisErrors[pathname], isNotEmpty);
     }).then((_) {
       // Prepare a set of edits which add the missing quotation marks, in the
       // order in which they appear in the file.  If these edits are applied in
diff --git a/pkg/analysis_server/test/integration/analysis/update_content_test.dart b/pkg/analysis_server/test/integration/analysis/update_content_test.dart
index cca4ec6..ec6d696 100644
--- a/pkg/analysis_server/test/integration/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/update_content_test.dart
@@ -27,7 +27,7 @@
     standardAnalysisSetup();
     return analysisFinished.then((_) {
       // The contents on disk (badText) are missing a semicolon.
-      expect(currentAnalysisErrors[pathname], isNot(isEmpty));
+      expect(currentAnalysisErrors[pathname], isNotEmpty);
     }).then((_) => sendAnalysisUpdateContent({
       pathname: new AddContentOverlay(goodText)
     })).then((result) => analysisFinished).then((_) {
@@ -40,7 +40,7 @@
       });
     }).then((result) => analysisFinished).then((_) {
       // There should be errors now because we've removed the semicolon.
-      expect(currentAnalysisErrors[pathname], isNot(isEmpty));
+      expect(currentAnalysisErrors[pathname], isNotEmpty);
       return sendAnalysisUpdateContent({
         pathname: new ChangeContentOverlay(
             [new SourceEdit(goodText.indexOf(';'), 0, ';')])
@@ -54,7 +54,7 @@
     }).then((result) => analysisFinished).then((_) {
       // Now there should be errors again, because the contents on disk are no
       // longer overridden.
-      expect(currentAnalysisErrors[pathname], isNot(isEmpty));
+      expect(currentAnalysisErrors[pathname], isNotEmpty);
     });
   }
 }
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index ec5fdb3..6f3bb56 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -141,6 +141,11 @@
    *
    *   The current status of analysis, including whether analysis is being
    *   performed and if so what is being analyzed.
+   *
+   * pub ( optional PubStatus )
+   *
+   *   The current status of pub execution, indicating whether we are currently
+   *   running pub.
    */
   Stream<ServerStatusParams> onServerStatus;
 
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index a2bd8cc..1970ab1 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -119,7 +119,7 @@
     // SERVER_STATUS (e.g. using sendServerSetSubscriptions(['STATUS']))
     expect(_subscribedToServerStatus, isTrue);
     subscription = onServerStatus.listen((ServerStatusParams params) {
-      if (!params.analysis.isAnalyzing) {
+      if (params.analysis != null && !params.analysis.isAnalyzing) {
         completer.complete(params);
         subscription.cancel();
       }
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index cc5e809..f9cbc01 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -86,11 +86,13 @@
  *
  * {
  *   "analysis": optional AnalysisStatus
+ *   "pub": optional PubStatus
  * }
  */
 final Matcher isServerStatusParams = new LazyMatcher(() => new MatchesJsonObject(
   "server.status params", null, optionalFields: {
-    "analysis": isAnalysisStatus
+    "analysis": isAnalysisStatus,
+    "pub": isPubStatus
   }));
 
 /**
@@ -1595,6 +1597,18 @@
   }));
 
 /**
+ * PubStatus
+ *
+ * {
+ *   "isListingPackageDirs": bool
+ * }
+ */
+final Matcher isPubStatus = new LazyMatcher(() => new MatchesJsonObject(
+  "PubStatus", {
+    "isListingPackageDirs": isBool
+  }));
+
+/**
  * RefactoringKind
  *
  * enum {
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index ffca2a3..564e8cb 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -20,6 +20,8 @@
 
 class Object {
   bool operator ==(other) => identical(this, other);
+  String toString() => 'a string';
+  int get hashCode => 0;
 }
 
 class Function {}
@@ -32,6 +34,8 @@
 }
 
 class String implements Comparable<String> {
+  external factory String.fromCharCodes(Iterable<int> charCodes,
+                                        [int start = 0, int end]);
   bool get isEmpty => false;
   bool get isNotEmpty => false;
   int get length => 0;
diff --git a/pkg/analysis_server/test/services/completion/completion_computer_test.dart b/pkg/analysis_server/test/services/completion/completion_computer_test.dart
index ac21d89..217a11d 100644
--- a/pkg/analysis_server/test/services/completion/completion_computer_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_computer_test.dart
@@ -50,6 +50,7 @@
   MockCompletionComputer computer2;
   CompletionSuggestion suggestion1;
   CompletionSuggestion suggestion2;
+  bool _continuePerformingAnalysis = true;
 
   void resolveLibrary() {
     context.resolveCompilationUnit(
@@ -81,6 +82,12 @@
         2,
         false,
         false);
+    new Future(_performAnalysis);
+  }
+
+  @override
+  void tearDown() {
+    _continuePerformingAnalysis = false;
   }
 
   test_compute_fastAndFull() {
@@ -148,6 +155,14 @@
       expect(done, isTrue);
     });
   }
+
+  void _performAnalysis() {
+    if (!_continuePerformingAnalysis) {
+      return;
+    }
+    context.performAnalysisTask();
+    new Future(_performAnalysis);
+  }
 }
 
 class MockCompletionComputer extends DartCompletionComputer {
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 632f30a..cf4a551 100644
--- a/pkg/analysis_server/test/services/completion/completion_test_util.dart
+++ b/pkg/analysis_server/test/services/completion/completion_test_util.dart
@@ -459,6 +459,16 @@
           request.unit = unit;
           request.node =
               new NodeLocator.con1(completionOffset).searchWithin(unit);
+          if (request.node is SimpleIdentifier) {
+            request.replacementOffset = request.node.offset;
+            request.replacementLength = request.node.length;
+          } else {
+            request.replacementOffset = request.offset;
+            request.replacementLength = 0;
+          }
+          if (request.replacementOffset == null) {
+            fail('expected non null');
+          }
           resolved = true;
           if (!fullAnalysis) {
             break;
@@ -880,6 +890,20 @@
     });
   }
 
+  test_AsExpression() {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('''
+      class A {var b; X _c; foo() {var a; (a as ^).foo();}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertNotSuggested('b');
+      assertNotSuggested('_c');
+      assertSuggestImportedClass('Object');
+      assertSuggestLocalClass('A');
+      assertNotSuggested('==');
+    });
+  }
+
   test_AssignmentExpression_name() {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // VariableDeclarationStatement  Block
@@ -906,13 +930,86 @@
   test_AssignmentExpression_type() {
     // SimpleIdentifier  TypeName  VariableDeclarationList
     // VariableDeclarationStatement  Block
-    addTestSource('class A {} main() {int a; int^ b = 1;}');
+    addTestSource('''
+      class A {} main() {
+        int a;
+        ^ b = 1;}''');
     computeFast();
     return computeFull((bool result) {
       assertSuggestLocalClass('A');
       assertSuggestImportedClass('int');
-      assertNotSuggested('a');
-      assertNotSuggested('main');
+      // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+      // the user may be either (1) entering a type for the assignment
+      // or (2) starting a new statement.
+      // Consider suggesting only types
+      // if only spaces separates the 1st and 2nd identifiers.
+      //assertNotSuggested('a');
+      //assertNotSuggested('main');
+      //assertNotSuggested('identical');
+    });
+  }
+
+  test_AssignmentExpression_type_partial() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      class A {} main() {
+        int a;
+        int^ b = 1;}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestLocalClass('A');
+      assertSuggestImportedClass('int');
+      // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+      // the user may be either (1) entering a type for the assignment
+      // or (2) starting a new statement.
+      // Consider suggesting only types
+      // if only spaces separates the 1st and 2nd identifiers.
+      //assertNotSuggested('a');
+      //assertNotSuggested('main');
+      //assertNotSuggested('identical');
+    });
+  }
+
+  test_AssignmentExpression_type_newline() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      class A {} main() {
+        int a;
+        ^
+        b = 1;}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestLocalClass('A');
+      assertSuggestImportedClass('int');
+      // Allow non-types preceding an identifier on LHS of assignment
+      // if newline follows first identifier
+      // because user is probably starting a new statement
+      assertSuggestLocalVariable('a', 'int');
+      assertSuggestLocalFunction('main', null);
+      assertSuggestImportedFunction('identical', 'bool');
+    });
+  }
+
+  test_AssignmentExpression_type_partial_newline() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      class A {} main() {
+        int a;
+        i^
+        b = 1;}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestLocalClass('A');
+      assertSuggestImportedClass('int');
+      // Allow non-types preceding an identifier on LHS of assignment
+      // if newline follows first identifier
+      // because user is probably starting a new statement
+      assertSuggestLocalVariable('a', 'int');
+      assertSuggestLocalFunction('main', null);
+      assertSuggestImportedFunction('identical', 'bool');
     });
   }
 
@@ -983,7 +1080,90 @@
       int T5;
       var _T6;
       Z D2() {int x;}
-      class X {a() {var f; {var x;} ^ var r;} void b() { }}
+      class X {
+        a() {
+          var f;
+          localF(int arg1) { }
+          {var x;}
+          ^ var r;
+        }
+        void b() { }}
+      class Z { }''');
+    computeFast();
+    return computeFull((bool result) {
+
+      assertSuggestLocalClass('X');
+      assertSuggestLocalClass('Z');
+      assertLocalSuggestMethod('a', 'X', null);
+      assertLocalSuggestMethod('b', 'X', 'void');
+      assertSuggestLocalFunction('localF', null);
+      assertSuggestLocalVariable('f', null);
+      // Don't suggest locals out of scope
+      assertNotSuggested('r');
+      assertNotSuggested('x');
+
+      assertSuggestImportedClass('A');
+      assertNotSuggested('_B');
+      assertSuggestImportedClass('C');
+      // hidden element suggested as low relevance
+      // but imported results are partially filtered
+      //assertSuggestImportedClass('D', CompletionRelevance.LOW);
+      //assertSuggestImportedFunction(
+      //    'D1', null, true, CompletionRelevance.LOW);
+      assertSuggestLocalFunction('D2', 'Z');
+      assertSuggestImportedClass('EE');
+      // hidden element suggested as low relevance
+      //assertSuggestImportedClass('F', CompletionRelevance.LOW);
+      assertSuggestLibraryPrefix('g');
+      assertNotSuggested('G');
+      //assertSuggestImportedClass('H', CompletionRelevance.LOW);
+      assertSuggestImportedClass('Object');
+      assertSuggestImportedFunction('min', 'num', false);
+      //assertSuggestImportedFunction(
+      //    'max',
+      //    'num',
+      //    false,
+      //    CompletionRelevance.LOW);
+      assertSuggestTopLevelVarGetterSetter('T1', 'String');
+      assertNotSuggested('_T2');
+      //assertSuggestImportedTopLevelVar('T3', 'int', CompletionRelevance.LOW);
+      assertNotSuggested('_T4');
+      assertSuggestLocalTopLevelVar('T5', 'int');
+      assertSuggestLocalTopLevelVar('_T6', null);
+      assertNotSuggested('==');
+      // TODO (danrubel) suggest HtmlElement as low relevance
+      assertNotSuggested('HtmlElement');
+    });
+  }
+
+  test_Block_identifier_partial() {
+    addSource('/testAB.dart', '''
+      export "dart:math" hide max;
+      class A {int x;}
+      @deprecated D1() {int x;}
+      class _B { }''');
+    addSource('/testCD.dart', '''
+      String T1;
+      var _T2;
+      class C { }
+      class D { }''');
+    addSource('/testEEF.dart', '''
+      class EE { }
+      class F { }''');
+    addSource('/testG.dart', 'class G { }');
+    addSource('/testH.dart', '''
+      class H { }
+      int T3;
+      var _T4;'''); // not imported
+    addTestSource('''
+      import "/testAB.dart";
+      import "/testCD.dart" hide D;
+      import "/testEEF.dart" show EE;
+      import "/testG.dart" as g;
+      int T5;
+      var _T6;
+      Z D2() {int x;}
+      class X {a() {var f; {var x;} D^ var r;} void b() { }}
       class Z { }''');
     computeFast();
     return computeFull((bool result) {
@@ -997,32 +1177,33 @@
       assertNotSuggested('r');
       assertNotSuggested('x');
 
-      assertSuggestImportedClass('A');
+      // imported elements are portially filtered
+      //assertSuggestImportedClass('A');
       assertNotSuggested('_B');
-      assertSuggestImportedClass('C');
+      //assertSuggestImportedClass('C');
       // hidden element suggested as low relevance
       assertSuggestImportedClass('D', CompletionRelevance.LOW);
       assertSuggestImportedFunction('D1', null, true, CompletionRelevance.LOW);
       assertSuggestLocalFunction('D2', 'Z');
-      assertSuggestImportedClass('EE');
+      //assertSuggestImportedClass('EE');
       // hidden element suggested as low relevance
-      assertSuggestImportedClass('F', CompletionRelevance.LOW);
-      assertSuggestLibraryPrefix('g');
+      //assertSuggestImportedClass('F', CompletionRelevance.LOW);
+      //assertSuggestLibraryPrefix('g');
       assertNotSuggested('G');
-      assertSuggestImportedClass('H', CompletionRelevance.LOW);
-      assertSuggestImportedClass('Object');
-      assertSuggestImportedFunction('min', 'num', false);
-      assertSuggestImportedFunction(
-          'max',
-          'num',
-          false,
-          CompletionRelevance.LOW);
-      assertSuggestTopLevelVarGetterSetter('T1', 'String');
+      //assertSuggestImportedClass('H', CompletionRelevance.LOW);
+      //assertSuggestImportedClass('Object');
+      //assertSuggestImportedFunction('min', 'num', false);
+      //assertSuggestImportedFunction(
+      //    'max',
+      //    'num',
+      //    false,
+      //    CompletionRelevance.LOW);
+      //assertSuggestTopLevelVarGetterSetter('T1', 'String');
       assertNotSuggested('_T2');
-      assertSuggestImportedTopLevelVar('T3', 'int', CompletionRelevance.LOW);
+      //assertSuggestImportedTopLevelVar('T3', 'int', CompletionRelevance.LOW);
       assertNotSuggested('_T4');
-      assertSuggestLocalTopLevelVar('T5', 'int');
-      assertSuggestLocalTopLevelVar('_T6', null);
+      //assertSuggestLocalTopLevelVar('T5', 'int');
+      //assertSuggestLocalTopLevelVar('_T6', null);
       assertNotSuggested('==');
       // TODO (danrubel) suggest HtmlElement as low relevance
       assertNotSuggested('HtmlElement');
@@ -1157,7 +1338,8 @@
       assertSuggestLocalVariable('a', 'A');
       assertSuggestLocalClass('A');
       assertSuggestLocalClass('X');
-      assertSuggestImportedClass('Object');
+      // top level results are partially filtered
+      //assertSuggestImportedClass('Object');
       assertNotSuggested('==');
     });
   }
@@ -1214,7 +1396,7 @@
         expect(suggestionO.element.isDeprecated, isFalse);
         expect(suggestionO.element.isPrivate, isFalse);
       }
-      assertSuggestLocalTopLevelVar('T', 'A');
+      assertNotSuggested('T');
       assertSuggestLibraryPrefix('x');
     });
   }
@@ -1271,6 +1453,34 @@
     });
   }
 
+  test_ConditionalExpression_empty() {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+      class A {var b; X _c; foo() {A a; if (^) something}}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestLocalGetter('b', null);
+      assertSuggestLocalGetter('_c', 'X');
+      assertSuggestImportedClass('Object');
+      assertSuggestLocalClass('A');
+      assertNotSuggested('==');
+    });
+  }
+
+  test_ConditionalExpression_invocation() {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('''
+      main() {var a; if (a.^) something}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestInvocationMethod('toString', 'Object', 'String');
+      //TODO (danrubel) type for '_c' should be 'X' not null
+      assertNotSuggested('Object');
+      assertNotSuggested('A');
+      assertNotSuggested('==');
+    });
+  }
+
   test_ConstructorName_importedClass() {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
@@ -1294,6 +1504,45 @@
     });
   }
 
+  test_ConstructorName_importedFactory() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addSource('/testB.dart', '''
+      lib B;
+      int T1;
+      F1() { }
+      class X {factory X.c(); factory X._d(); z() {}}''');
+    addTestSource('''
+      import "/testB.dart";
+      var m;
+      main() {new X.^}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestNamedConstructor('c', 'X');
+      assertNotSuggested('F1');
+      assertNotSuggested('T1');
+      assertNotSuggested('_d');
+      assertNotSuggested('z');
+      assertNotSuggested('m');
+    });
+  }
+
+  test_ConstructorName_importedFactory2() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+      main() {new String.fr^omCharCodes([]);}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestNamedConstructor('fromCharCodes', 'String');
+      assertNotSuggested('isEmpty');
+      assertNotSuggested('isNotEmpty');
+      assertNotSuggested('length');
+      assertNotSuggested('Object');
+      assertNotSuggested('String');
+    });
+  }
+
   test_ConstructorName_localClass() {
     // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
     // InstanceCreationExpression
@@ -1313,6 +1562,25 @@
     });
   }
 
+  test_ConstructorName_localFactory() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('''
+      int T1;
+      F1() { }
+      class X {factory X.c(); factory X._d(); z() {}}
+      main() {new X.^}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestNamedConstructor('c', 'X');
+      assertSuggestNamedConstructor('_d', 'X');
+      assertNotSuggested('F1');
+      assertNotSuggested('T1');
+      assertNotSuggested('z');
+      assertNotSuggested('m');
+    });
+  }
+
   test_ExpressionStatement_identifier() {
     // SimpleIdentifier  ExpressionStatement  Block
     addSource('/testA.dart', '''
@@ -1323,7 +1591,7 @@
       import "/testA.dart";
       typedef int F2(int blat);
       class Clz = Object with Object;
-      class C {foo(){O^} void bar() {}}''');
+      class C {foo(){^} void bar() {}}''');
     computeFast();
     return computeFull((bool result) {
       assertSuggestImportedClass('A');
@@ -1555,7 +1823,8 @@
     computeFast();
     return computeFull((bool result) {
       assertSuggestLocalVariable('name', 'String');
-      assertSuggestImportedClass('Object');
+      // top level results are partially filtered
+      //assertSuggestImportedClass('Object');
     });
   }
 
@@ -1577,7 +1846,8 @@
     computeFast();
     return computeFull((bool result) {
       assertSuggestLocalVariable('name', 'String');
-      assertSuggestImportedClass('Object');
+      // top level results are partially filtered
+      //assertSuggestImportedClass('Object');
       assertNotSuggested('length');
     });
   }
@@ -1634,6 +1904,20 @@
     });
   }
 
+  test_IsExpression_type_partial() {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('''
+      class A {int x; int y() => 0;}
+      main(){var a; if (a is Obj^)}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertNotSuggested('a');
+      assertNotSuggested('main');
+      assertSuggestLocalClass('A');
+      assertSuggestImportedClass('Object');
+    });
+  }
+
   test_Literal_string() {
     // SimpleStringLiteral  ExpressionStatement  Block
     addTestSource('class A {a() {"hel^lo"}}');
@@ -1971,6 +2255,76 @@
     });
   }
 
+  test_ThisExpression_block() {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      main() { }
+      class I {X get f => new A();get _g => new A();}
+      class A implements I {
+        A() {}
+        A.z() {}
+        var b; X _c;
+        X get d => new A();get _e => new A();
+        // no semicolon between completion point and next statement
+        set s1(I x) {} set _s2(I x) {this.^ m(null);}
+        m(X x) {} I _n(X x) {}}
+      class X{}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestInvocationGetter('b', null);
+      assertSuggestInvocationGetter('_c', 'X');
+      assertSuggestInvocationGetter('d', 'X');
+      assertSuggestInvocationGetter('_e', null);
+      assertSuggestInvocationGetter('f', 'X');
+      assertSuggestInvocationGetter('_g', null);
+      assertSuggestInvocationMethod('m', 'A', null);
+      assertSuggestInvocationMethod('_n', 'A', 'I');
+      assertSuggestInvocationSetter('s1');
+      assertSuggestInvocationSetter('_s2');
+      assertNotSuggested('z');
+      assertNotSuggested('I');
+      assertNotSuggested('A');
+      assertNotSuggested('X');
+      assertNotSuggested('Object');
+      assertNotSuggested('==');
+    });
+  }
+
+  test_ThisExpression_constructor() {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      main() { }
+      class I {X get f => new A();get _g => new A();}
+      class A implements I {
+        A() {this.^}
+        A.z() {}
+        var b; X _c;
+        X get d => new A();get _e => new A();
+        // no semicolon between completion point and next statement
+        set s1(I x) {} set _s2(I x) {m(null);}
+        m(X x) {} I _n(X x) {}}
+      class X{}''');
+    computeFast();
+    return computeFull((bool result) {
+      assertSuggestInvocationGetter('b', null);
+      assertSuggestInvocationGetter('_c', 'X');
+      assertSuggestInvocationGetter('d', 'X');
+      assertSuggestInvocationGetter('_e', null);
+      assertSuggestInvocationGetter('f', 'X');
+      assertSuggestInvocationGetter('_g', null);
+      assertSuggestInvocationMethod('m', 'A', null);
+      assertSuggestInvocationMethod('_n', 'A', 'I');
+      assertSuggestInvocationSetter('s1');
+      assertSuggestInvocationSetter('_s2');
+      assertNotSuggested('z');
+      assertNotSuggested('I');
+      assertNotSuggested('A');
+      assertNotSuggested('X');
+      assertNotSuggested('Object');
+      assertNotSuggested('==');
+    });
+  }
+
   test_TopLevelVariableDeclaration_typed_name() {
     // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
     // TopLevelVariableDeclaration
diff --git a/pkg/analysis_server/test/services/completion/imported_computer_test.dart b/pkg/analysis_server/test/services/completion/imported_computer_test.dart
index bec1272..6c8cf16 100644
--- a/pkg/analysis_server/test/services/completion/imported_computer_test.dart
+++ b/pkg/analysis_server/test/services/completion/imported_computer_test.dart
@@ -54,6 +54,8 @@
      * Calculate a new completion at the same location
      */
     setUpComputer();
+    int replacementOffset = request.replacementOffset;
+    int replacementLength = request.replacementLength;
     request = new DartCompletionRequest(
         context,
         searchEngine,
@@ -61,6 +63,8 @@
         completionOffset,
         cache,
         new CompletionPerformance());
+    request.replacementOffset = replacementOffset;
+    request.replacementLength = replacementLength;
     expect(computeFast(), isTrue);
     expect(request.unit.element, isNull);
     List<CompletionSuggestion> newSuggestions = request.suggestions;
diff --git a/pkg/analysis_server/test/services/completion/optype_test.dart b/pkg/analysis_server/test/services/completion/optype_test.dart
new file mode 100644
index 0000000..3017031
--- /dev/null
+++ b/pkg/analysis_server/test/services/completion/optype_test.dart
@@ -0,0 +1,656 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library test.services.completion.computer.dart.optype;
+
+import 'package:analysis_server/src/services/completion/optype.dart';
+import 'package:analyzer/src/generated/ast.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../abstract_context.dart';
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(OpTypeTest);
+}
+
+@ReflectiveTestCase()
+class OpTypeTest {
+
+  OpType visitor;
+
+  void addTestSource(String content, {bool resolved: false}) {
+    int offset = content.indexOf('^');
+    expect(offset, isNot(equals(-1)), reason: 'missing ^');
+    int nextOffset = content.indexOf('^', offset + 1);
+    expect(nextOffset, equals(-1), reason: 'too many ^');
+    content = content.substring(0, offset) + content.substring(offset + 1);
+    Source source = new _TestSource('/completionTest.dart');
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    context.sourceFactory =
+        new SourceFactory([AbstractContextTest.SDK_RESOLVER]);
+    context.setContents(source, content);
+    CompilationUnit unit = resolved ?
+        context.resolveCompilationUnit2(source, source) :
+        context.parseCompilationUnit(source);
+    AstNode node = new NodeLocator.con1(offset).searchWithin(unit);
+    visitor = new OpType.forCompletion(node, offset);
+  }
+
+  void assertOpType({bool invocation: false, bool returnValue: false,
+      bool typeNames: false, bool voidReturn: false}) {
+    expect(visitor.includeInvocationSuggestions, equals(invocation));
+    expect(visitor.includeReturnValueSuggestions, equals(returnValue));
+    expect(visitor.includeTypeNameSuggestions, equals(typeNames));
+    expect(visitor.includeVoidReturnSuggestions, equals(voidReturn));
+  }
+
+  test_Annotation() {
+    // SimpleIdentifier  Annotation  MethodDeclaration  ClassDeclaration
+    addTestSource('class C { @A^ }');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ArgumentList() {
+    // ArgumentList  MethodInvocation  ExpressionStatement  Block
+    addTestSource('void main() {expect(^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ArgumentList_namedParam() {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addTestSource('void main() {expect(foo: ^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AsExpression() {
+    // SimpleIdentifier  TypeName  AsExpression
+    addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
+    assertOpType(typeNames: true);
+  }
+
+  test_AssignmentExpression_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int ^b = 1;}');
+    assertOpType();
+  }
+
+  test_AssignmentExpression_RHS() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('class A {} main() {int a; int b = ^}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_AssignmentExpression_type() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        ^ b = 1;}''');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AssignmentExpression_type_newline() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        ^
+        b = 1;}''');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AssignmentExpression_type_partial() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        int^ b = 1;}''');
+    // TODO (danrubel) When entering 1st of 2 identifiers on assignment LHS
+    // the user may be either (1) entering a type for the assignment
+    // or (2) starting a new statement.
+    // Consider suggesting only types
+    // if only spaces separates the 1st and 2nd identifiers.
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AssignmentExpression_type_partial_newline() {
+    // SimpleIdentifier  TypeName  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('''
+      main() {
+        int a;
+        i^
+        b = 1;}''');
+    // Allow non-types preceding an identifier on LHS of assignment
+    // if newline follows first identifier
+    // because user is probably starting a new statement
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_AwaitExpression() {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    addTestSource('main(){A a; await ^}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_BinaryExpression_LHS() {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = ^ + 2;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_BinaryExpression_RHS() {
+    // SimpleIdentifier  BinaryExpression  VariableDeclaration
+    // VariableDeclarationList  VariableDeclarationStatement
+    addTestSource('main() {int a = 1, b = 2 + ^;}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_Block() {
+    // Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('''
+      class X {
+        a() {
+          var f;
+          localF(int arg1) { }
+          {var x;}
+          ^ var r;
+        }
+      }''');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_Block_empty() {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('class A extends E implements I with M {a() {^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_Block_identifier_partial() {
+    addTestSource('class X {a() {var f; {var x;} D^ var r;} void b() { }}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_CascadeExpression_selector1() {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addTestSource('''
+      // looks like a cascade to the parser
+      // but the user is trying to get completions for a non-cascade
+      main() {A a; a.^.z}''');
+    assertOpType(invocation: true);
+  }
+
+  test_CascadeExpression_selector2() {
+    // SimpleIdentifier  PropertyAccess  CascadeExpression  ExpressionStatement
+    addTestSource('main() {A a; a..^z}');
+    assertOpType(invocation: true);
+  }
+
+  test_CascadeExpression_selector2_withTrailingReturn() {
+    // PropertyAccess  CascadeExpression  ExpressionStatement  Block
+    addTestSource('main() {A a; a..^ return}');
+    assertOpType(invocation: true);
+  }
+
+  test_CascadeExpression_target() {
+    // SimpleIdentifier  CascadeExpression  ExpressionStatement
+    addTestSource('main() {A a; a^..b}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_CatchClause_typed() {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} on E catch (e) {^}}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_CatchClause_untyped() {
+    // Block  CatchClause  TryStatement
+    addTestSource('class A {a() {try{var x;} catch (e, s) {^}}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ClassDeclaration_body() {
+    // ClassDeclaration  CompilationUnit
+    addTestSource('@deprecated class A {^}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ClassDeclaration_body2() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('@deprecated class A {^mth() {}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Combinator_hide() {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addTestSource('''
+      import "/testAB.dart" hide ^;
+      class X {}''');
+    assertOpType();
+  }
+
+  test_Combinator_show() {
+    // SimpleIdentifier  HideCombinator  ImportDirective
+    addTestSource('''
+      import "/testAB.dart" show ^;
+      import "/testCD.dart";
+      class X {}''');
+    assertOpType();
+  }
+
+  test_CommentReference() {
+    // SimpleIdentifier  CommentReference  Comment  MethodDeclaration
+    addTestSource('class A {/** [^] */ mth() {}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ConditionalExpression_empty() {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('class A {foo() {A a; if (^) something}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ConditionalExpression_invocation() {
+    // SimpleIdentifier  PrefixIdentifier  IfStatement
+    addTestSource('main() {var a; if (a.^) something}');
+    assertOpType(invocation: true);
+  }
+
+  test_ConstructorName() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new X.^}');
+    assertOpType(invocation: true);
+  }
+
+  test_ConstructorName_name_resolved() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new Str^ing.fromCharCodes([]);}', resolved: true);
+    assertOpType(typeNames: true);
+  }
+
+  test_ConstructorName_resolved() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new String.fr^omCharCodes([]);}', resolved: true);
+    assertOpType(invocation: true);
+  }
+
+  test_ConstructorName_unresolved() {
+    // SimpleIdentifier  PrefixedIdentifier  TypeName  ConstructorName
+    // InstanceCreationExpression
+    addTestSource('main() {new String.fr^omCharCodes([]);}');
+    assertOpType(invocation: true);
+  }
+
+  test_DoStatement() {
+    // SimpleIdentifier  DoStatement  Block
+    addTestSource('main() {do{} while(^x);}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ExpressionFunctionBody() {
+    // SimpleIdentifier  ExpressionFunctionBody  FunctionExpression
+    addTestSource('m(){[1].forEach((x)=>^x);}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ExpressionStatement() {
+    // ExpressionStatement  Block  BlockFunctionBody
+    addTestSource('n(){f(3);^}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ExpressionStatement_name() {
+    // ExpressionStatement  Block  BlockFunctionBody  MethodDeclaration
+    addTestSource('class C {a() {C ^}}');
+    assertOpType();
+  }
+
+  test_ExtendsClause() {
+    // ExtendsClause  ClassDeclaration
+    addTestSource('class x extends ^\n{}');
+    assertOpType(typeNames: true);
+  }
+
+  test_FieldDeclaration_name_typed() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {A ^}');
+    assertOpType();
+  }
+
+  test_FieldDeclaration_name_var() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // FieldDeclaration
+    addTestSource('class C {var ^}');
+    assertOpType();
+  }
+
+  test_ForEachStatement() {
+    // SimpleIdentifier  ForEachStatement  Block
+    addTestSource('main() {for(z in ^zs) {}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ForEachStatement_body_typed() {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (int foo in bar) {^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForEachStatement_body_untyped() {
+    // Block  ForEachStatement
+    addTestSource('main(args) {for (foo in bar) {^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_FormalParameterList() {
+    // FormalParameterList MethodDeclaration
+    addTestSource('class A {a(^) { }}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ForStatement_condition() {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; i^)}');
+    // TODO (danrubel) may want to exclude methods/functions with void return
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForStatement_initializer() {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (^)}');
+    // TODO (danrubel) may want to exclude methods/functions with void return
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForStatement_updaters() {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; i^)}');
+    // TODO (danrubel) may want to exclude methods/functions with void return
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_ForStatement_updaters_prefix_expression() {
+    // SimpleIdentifier  PrefixExpression  ForStatement
+    addTestSource('main() {for (int index = 0; index < 10; ++i^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_FunctionTypeAlias() {
+    // SimpleIdentifier  FunctionTypeAlias  CompilationUnit
+    addTestSource('typedef n^ ;');
+    assertOpType(typeNames: true);
+  }
+
+  test_IfStatement() {
+    // EmptyStatement  IfStatement  Block  BlockFunctionBody
+    addTestSource('main(){var a; if (true) ^}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_IfStatement_condition() {
+    // SimpleIdentifier  IfStatement  Block  BlockFunctionBody
+    addTestSource('main(){var a; if (^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ImplementsClause() {
+    // ImplementsClause  ClassDeclaration
+    addTestSource('class x implements ^\n{}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ImportDirective_dart() {
+    // SimpleStringLiteral  ImportDirective
+    addTestSource('''
+      import "dart^";
+      main() {}''');
+    assertOpType();
+  }
+
+  test_InstanceCreationExpression_imported() {
+    // SimpleIdentifier  TypeName  ConstructorName  InstanceCreationExpression
+    addTestSource('class C {foo(){var f; {var x;} new ^}}');
+    assertOpType(typeNames: true);
+  }
+
+  test_InterpolationExpression() {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \$^");}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_InterpolationExpression_block() {
+    // SimpleIdentifier  InterpolationExpression  StringInterpolation
+    addTestSource('main() {String name; print("hello \${n^}");}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_InterpolationExpression_prefix_selector() {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${name.^}");}');
+    assertOpType(invocation: true);
+  }
+
+  test_InterpolationExpression_prefix_target() {
+    // SimpleIdentifier  PrefixedIdentifier  InterpolationExpression
+    addTestSource('main() {String name; print("hello \${nam^e.length}");}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_IsExpression() {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('main() {var x; if (x is ^) { }}');
+    assertOpType(typeNames: true);
+  }
+
+  test_IsExpression_target() {
+    // IfStatement  Block  BlockFunctionBody
+    addTestSource('main(){var a; if (^ is A)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_IsExpression_type_partial() {
+    // SimpleIdentifier  TypeName  IsExpression  IfStatement
+    addTestSource('main(){var a; if (a is Obj^)}');
+    assertOpType(typeNames: true);
+  }
+
+  test_Literal_string() {
+    // SimpleStringLiteral  ExpressionStatement  Block
+    addTestSource('class A {a() {"hel^lo"}}');
+    assertOpType();
+  }
+
+  test_MethodDeclaration1() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('class Bar {const ^Fara();}');
+    assertOpType(typeNames: true);
+  }
+
+  test_MethodDeclaration2() {
+    // SimpleIdentifier  MethodDeclaration  ClassDeclaration
+    addTestSource('class Bar {const F^ara();}');
+    assertOpType();
+  }
+
+  test_MethodInvocation_no_semicolon() {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      class A implements I {
+        // no semicolon between completion point and next statement
+        set _s2(I x) {x.^ m(null);}
+      }''');
+    assertOpType(invocation: true);
+  }
+
+  test_PrefixedIdentifier_class_const() {
+    // SimpleIdentifier PrefixedIdentifier ExpressionStatement Block
+    addTestSource('main() {A.^}');
+    assertOpType(invocation: true);
+  }
+
+  test_PrefixedIdentifier_class_imported() {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('main() {A a; a.^}');
+    assertOpType(invocation: true);
+  }
+
+  test_PrefixedIdentifier_prefix() {
+    // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
+    addTestSource('class X {foo(){A^.bar}}');
+    assertOpType(typeNames: true, returnValue: true);
+  }
+
+  test_PropertyAccess_expression() {
+    // SimpleIdentifier  MethodInvocation  PropertyAccess  ExpressionStatement
+    addTestSource('class A {a() {"hello".to^String().length}}');
+    assertOpType(invocation: true);
+  }
+
+  test_PropertyAccess_selector() {
+    // SimpleIdentifier  PropertyAccess  ExpressionStatement  Block
+    addTestSource('class A {a() {"hello".length.^}}');
+    assertOpType(invocation: true);
+  }
+
+  test_ReturnStatement() {
+    // ReturnStatement  Block
+    addTestSource('f() { var vvv = 42; return ^ }');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SimpleFormalParameter() {
+    // SimpleIdentifier  SimpleFormalParameter  FormalParameterList
+    addTestSource('mth() { PNGS.sort((String a, Str^) => a.compareTo(b)); }');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_SwitchCase() {
+    // SimpleIdentifier  SwitchCase  SwitchStatement
+    addTestSource('''m() {switch (x) {case ^D: return;}}''');
+    // TODO (danrubel) should refine this to return constants
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_SwitchStatement() {
+    // SimpleIdentifier  SwitchStatement  Block
+    addTestSource('main() {switch(^k) {case 1:{}}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ThisExpression_block() {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      class A implements I {
+        // no semicolon between completion point and next statement
+        set s1(I x) {} set _s2(I x) {this.^ m(null);}
+      }''');
+    assertOpType(invocation: true);
+  }
+
+  test_ThisExpression_constructor() {
+    // MethodInvocation  ExpressionStatement  Block
+    addTestSource('''
+      class A implements I {
+        A() {this.^}
+      }''');
+    assertOpType(invocation: true);
+  }
+
+  test_TopLevelVariableDeclaration_typed_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} B ^');
+    assertOpType();
+  }
+
+  test_TopLevelVariableDeclaration_untyped_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // TopLevelVariableDeclaration
+    addTestSource('class A {} var ^');
+    assertOpType();
+  }
+
+  test_TypeParameter() {
+    // SimpleIdentifier  TypeParameter  TypeParameterList
+    addTestSource('class tezetst <String, ^List> {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_TypeParameterList_empty() {
+    // SimpleIdentifier  TypeParameter  TypeParameterList
+    addTestSource('class tezetst <^> {}');
+    assertOpType(typeNames: true);
+  }
+
+  test_VariableDeclaration_name() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement  Block
+    addTestSource('main() {var ^}');
+    assertOpType();
+  }
+
+  test_VariableDeclarationStatement_afterSemicolon() {
+    // VariableDeclarationStatement  Block  BlockFunctionBody
+    addTestSource('class A {var a; x() {var b;^}}');
+    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+  }
+
+  test_VariableDeclarationStatement_RHS() {
+    // SimpleIdentifier  VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addTestSource('class C {bar(){var f; {var x;} var e = ^}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_VariableDeclarationStatement_RHS_missing_semicolon() {
+    // VariableDeclaration  VariableDeclarationList
+    // VariableDeclarationStatement
+    addTestSource('class C {bar(){var f; {var x;} var e = ^ var g}}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_WhileStatement() {
+    // SimpleIdentifier  WhileStatement  Block
+    addTestSource('mth() { while (b^) {} }}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+}
+
+class _TestSource implements Source {
+  String fullName;
+  _TestSource(this.fullName);
+
+  @override
+  bool get isInSystemLibrary => false;
+
+  @override
+  String get shortName => fullName;
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index 5770bb4..e1fb92c 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.dart
@@ -14,6 +14,7 @@
 import 'invocation_computer_test.dart' as invocation_test;
 import 'keyword_computer_test.dart' as keyword_test;
 import 'local_computer_test.dart' as local_test;
+import 'optype_test.dart' as optype_test;
 
 /// Utility for manually running all tests.
 main() {
@@ -27,5 +28,6 @@
     keyword_test.main();
     invocation_test.main();
     local_test.main();
+    optype_test.main();
   });
 }
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index e5916c7..793c870 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -166,6 +166,25 @@
     assertNoAssistAt('item in', AssistKind.ADD_TYPE_ANNOTATION);
   }
 
+  void test_addTypeAnnotation_declaredIdentifier_generic_OK() {
+    _indexTestUnit('''
+class A<T> {
+  main(List<List<T>> items) {
+    for (var item in items) {
+    }
+  }
+}
+''');
+    assertHasAssistAt('item in', AssistKind.ADD_TYPE_ANNOTATION, '''
+class A<T> {
+  main(List<List<T>> items) {
+    for (List<T> item in items) {
+    }
+  }
+}
+''');
+  }
+
   void test_addTypeAnnotation_declaredIdentifier_OK() {
     _indexTestUnit('''
 main(List<String> items) {
@@ -226,6 +245,40 @@
 ''');
   }
 
+  void test_addTypeAnnotation_local_generic_OK_literal() {
+    _indexTestUnit('''
+class A {
+  main(List<int> items) {
+    var v = items;
+  }
+}
+''');
+    assertHasAssistAt('v =', AssistKind.ADD_TYPE_ANNOTATION, '''
+class A {
+  main(List<int> items) {
+    List<int> v = items;
+  }
+}
+''');
+  }
+
+  void test_addTypeAnnotation_local_generic_OK_local() {
+    _indexTestUnit('''
+class A<T> {
+  main(List<T> items) {
+    var v = items;
+  }
+}
+''');
+    assertHasAssistAt('v =', AssistKind.ADD_TYPE_ANNOTATION, '''
+class A<T> {
+  main(List<T> items) {
+    List<T> v = items;
+  }
+}
+''');
+  }
+
   void test_addTypeAnnotation_local_OK_addImport_dartUri() {
     addSource('/my_lib.dart', r'''
 import 'dart:async';
@@ -1008,10 +1061,10 @@
 
   void test_exchangeBinaryExpressionArguments_OK_compare() {
     Map<String, String> operatorMap = {
-      '<': '>=',
-      '<=': '>',
-      '>': '<=',
-      '>=': '<'
+      '<': '>',
+      '<=': '>=',
+      '>': '<',
+      '>=': '<='
     };
     operatorMap.forEach((initialOperator, resultOperator) {
       _indexTestUnit('''
@@ -2220,35 +2273,6 @@
 ''');
   }
 
-  void test_splitAndCondition_OK_thenBlock_elseBlock() {
-    _indexTestUnit('''
-main() {
-  if (true && false) {
-    print(0);
-  } else {
-    print(1);
-    if (2 == 2) {
-      print(2);
-    }
-  }
-}
-''');
-    assertHasAssistAt('&& false', AssistKind.SPLIT_AND_CONDITION, '''
-main() {
-  if (true) {
-    if (false) {
-      print(0);
-    } else {
-      print(1);
-      if (2 == 2) {
-        print(2);
-      }
-    }
-  }
-}
-''');
-  }
-
   void test_splitAndCondition_OK_thenStatement() {
     _indexTestUnit('''
 main() {
@@ -2265,26 +2289,6 @@
 ''');
   }
 
-  void test_splitAndCondition_OK_thenStatement_elseStatement() {
-    _indexTestUnit('''
-main() {
-  if (true && false)
-    print(0);
-  else
-    print(1);
-}
-''');
-    assertHasAssistAt('&& false', AssistKind.SPLIT_AND_CONDITION, '''
-main() {
-  if (true)
-    if (false)
-      print(0);
-    else
-      print(1);
-}
-''');
-  }
-
   void test_splitAndCondition_wrong() {
     _indexTestUnit('''
 main() {
@@ -2303,6 +2307,19 @@
     }
   }
 
+  void test_splitAndCondition_wrong_hasElse() {
+    _indexTestUnit('''
+main() {
+  if (1 == 1 && 2 == 2) {
+    print(1);
+  } else {
+    print(2);
+  }
+}
+''');
+    assertNoAssistAt('&& 2', AssistKind.SPLIT_AND_CONDITION);
+  }
+
   void test_splitAndCondition_wrong_notAnd() {
     _indexTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 625be28..794b284 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -233,9 +233,7 @@
   new A.named(1, 2.0);
 }
 ''');
-    _assertLinkedGroup(
-        change.linkedEditGroups[0],
-        ['named(int ', 'named(1']);
+    _assertLinkedGroup(change.linkedEditGroups[0], ['named(int ', 'named(1']);
   }
 
   void test_createConstructorSuperExplicit() {
@@ -528,6 +526,53 @@
 ''');
   }
 
+  void test_createField_setter_generic_BAD() {
+    _indexTestUnit('''
+class A {
+}
+class B<T> {
+  List<T> items;
+  main(A a) {
+    a.test = items;
+  }
+}
+''');
+    assertHasFix(FixKind.CREATE_FIELD, '''
+class A {
+  List test;
+}
+class B<T> {
+  List<T> items;
+  main(A a) {
+    a.test = items;
+  }
+}
+''');
+  }
+
+  void test_createField_setter_generic_OK_local() {
+    _indexTestUnit('''
+class A<T> {
+  List<T> items;
+
+  main(A a) {
+    test = items;
+  }
+}
+''');
+    assertHasFix(FixKind.CREATE_FIELD, '''
+class A<T> {
+  List<T> items;
+
+  List<T> test;
+
+  main(A a) {
+    test = items;
+  }
+}
+''');
+  }
+
   void test_createField_setter_qualified_instance_hasField() {
     _indexTestUnit('''
 class A {
@@ -1829,6 +1874,50 @@
 ''');
   }
 
+  void test_undefinedFunction_create_generic_BAD() {
+    _indexTestUnit('''
+class A<T> {
+  Map<int, T> items;
+  main() {
+    process(items);
+  }
+}
+''');
+    assertHasFix(FixKind.CREATE_FUNCTION, '''
+class A<T> {
+  Map<int, T> items;
+  main() {
+    process(items);
+  }
+}
+
+void process(Map items) {
+}
+''');
+  }
+
+  void test_undefinedFunction_create_generic_OK() {
+    _indexTestUnit('''
+class A {
+  List<int> items;
+  main() {
+    process(items);
+  }
+}
+''');
+    assertHasFix(FixKind.CREATE_FUNCTION, '''
+class A {
+  List<int> items;
+  main() {
+    process(items);
+  }
+}
+
+void process(List<int> items) {
+}
+''');
+  }
+
   void test_undefinedFunction_create_returnType_bool_expressions() {
     assert_undefinedFunction_create_returnType_bool("!test();");
     assert_undefinedFunction_create_returnType_bool("b && test();");
@@ -1990,6 +2079,86 @@
 ''');
   }
 
+  void test_undefinedMethod_create_generic_BAD() {
+    _indexTestUnit('''
+class A<T> {
+  B b;
+  Map<int, T> items;
+  main() {
+    b.process(items);
+  }
+}
+
+class B {
+}
+''');
+    assertHasFix(FixKind.CREATE_METHOD, '''
+class A<T> {
+  B b;
+  Map<int, T> items;
+  main() {
+    b.process(items);
+  }
+}
+
+class B {
+  void process(Map items) {
+  }
+}
+''');
+  }
+
+  void test_undefinedMethod_create_generic_OK_literal() {
+    _indexTestUnit('''
+class A {
+  B b;
+  List<int> items;
+  main() {
+    b.process(items);
+  }
+}
+
+class B {
+}
+''');
+    assertHasFix(FixKind.CREATE_METHOD, '''
+class A {
+  B b;
+  List<int> items;
+  main() {
+    b.process(items);
+  }
+}
+
+class B {
+  void process(List<int> items) {
+  }
+}
+''');
+  }
+
+  void test_undefinedMethod_create_generic_OK_local() {
+    _indexTestUnit('''
+class A<T> {
+  List<T> items;
+  main() {
+    process(items);
+  }
+}
+''');
+    assertHasFix(FixKind.CREATE_METHOD, '''
+class A<T> {
+  List<T> items;
+  main() {
+    process(items);
+  }
+
+  void process(List<T> items) {
+  }
+}
+''');
+  }
+
   void test_undefinedMethod_createQualified_fromClass() {
     _indexTestUnit('''
 class A {
diff --git a/pkg/analysis_server/test/services/index/store/mocks.dart b/pkg/analysis_server/test/services/index/store/mocks.dart
index 4aec3c6..ee14ada 100644
--- a/pkg/analysis_server/test/services/index/store/mocks.dart
+++ b/pkg/analysis_server/test/services/index/store/mocks.dart
@@ -6,7 +6,6 @@
 
 import 'package:analysis_server/src/services/index/index.dart';
 import 'package:analysis_server/src/services/index/store/codec.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:typed_mock/typed_mock.dart';
 
 
@@ -20,12 +19,6 @@
 }
 
 
-class MockInstrumentedAnalysisContextImpl extends TypedMock implements
-    InstrumentedAnalysisContextImpl {
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-}
-
-
 class MockLocation extends TypedMock implements Location {
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
diff --git a/pkg/analysis_server/test/services/index/store/split_store_test.dart b/pkg/analysis_server/test/services/index/store/split_store_test.dart
index ba994ac..d824cf5 100644
--- a/pkg/analysis_server/test/services/index/store/split_store_test.dart
+++ b/pkg/analysis_server/test/services/index/store/split_store_test.dart
@@ -571,14 +571,6 @@
     expect(store.aboutToIndexDart(contextA, unitElementA), isFalse);
   }
 
-  void test_aboutToIndexDart_disposedContext_wrapped() {
-    when(contextA.isDisposed).thenReturn(true);
-    InstrumentedAnalysisContextImpl instrumentedContext =
-        new MockInstrumentedAnalysisContextImpl();
-    when(instrumentedContext.basis).thenReturn(contextA);
-    expect(store.aboutToIndexDart(instrumentedContext, unitElementA), isFalse);
-  }
-
   Future test_aboutToIndexDart_library_first() {
     when(
         libraryElement.parts).thenReturn(
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index bc52d0d..87f5eb5 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -218,14 +218,16 @@
     {
       ClassElement classA = findElement('A');
       List<Element> members = getMembers(classA);
-      expect(members.map((e) => e.name), unorderedEquals(['ma1', 'ma2', '==']));
+      expect(
+          members.map((e) => e.name),
+          unorderedEquals(['ma1', 'ma2', '==', 'toString', 'hashCode']));
     }
     {
       ClassElement classB = findElement('B');
       List<Element> members = getMembers(classB);
       expect(
           members.map((e) => e.name),
-          unorderedEquals(['mb1', 'mb2', 'ma1', 'ma2', '==']));
+          unorderedEquals(['mb1', 'mb2', 'ma1', 'ma2', '==', 'toString', 'hashCode']));
     }
   }
 
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index aa1a312..047a1c8 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_test.dart
@@ -36,7 +36,7 @@
     SocketServer server = new SocketServer(
         new AnalysisServerOptions(),
         DirectoryBasedDartSdk.defaultSdk,
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
     MockServerChannel channel1 = new MockServerChannel();
     MockServerChannel channel2 = new MockServerChannel();
     server.createAnalysisServer(channel1);
@@ -64,7 +64,7 @@
     SocketServer server = new SocketServer(
         new AnalysisServerOptions(),
         DirectoryBasedDartSdk.defaultSdk,
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
     MockServerChannel channel = new MockServerChannel();
     server.createAnalysisServer(channel);
     channel.expectMsgCount(notificationCount: 1);
@@ -81,7 +81,7 @@
     SocketServer server = new SocketServer(
         new AnalysisServerOptions(),
         DirectoryBasedDartSdk.defaultSdk,
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
     MockServerChannel channel = new MockServerChannel();
     server.createAnalysisServer(channel);
     channel.expectMsgCount(notificationCount: 1);
@@ -95,7 +95,7 @@
       expect(response.error.code, equals(RequestErrorCode.SERVER_ERROR));
       expect(response.error.message, equals('mock request exception'));
       expect(response.error.stackTrace, isNotNull);
-      expect(response.error.stackTrace, isNot(isEmpty));
+      expect(response.error.stackTrace, isNotEmpty);
       channel.expectMsgCount(responseCount: 1, notificationCount: 1);
     });
   }
@@ -104,7 +104,7 @@
     SocketServer server = new SocketServer(
         new AnalysisServerOptions(),
         DirectoryBasedDartSdk.defaultSdk,
-        new NullInstrumentationServer());
+        InstrumentationService.NULL_SERVICE);
     MockServerChannel channel = new MockServerChannel();
     server.createAnalysisServer(channel);
     _MockRequestHandler handler = new _MockRequestHandler(true);
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 69f4542..e09c9e3 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -248,6 +248,13 @@
               analyzed.
             </p>
           </field>
+          <field name="pub" optional="true">
+            <ref>PubStatus</ref>
+            <p>
+              The current status of pub execution, indicating whether we are
+              currently running pub.
+            </p>
+          </field>
         </params>
       </notification>
     </domain>
@@ -2698,6 +2705,20 @@
           </field>
         </object>
       </type>
+      <type name="PubStatus">
+        <p>
+          An indication of the current state of pub execution.
+        </p>
+        <object>
+          <field name="isListingPackageDirs">
+            <ref>bool</ref>
+            <p>
+              True if the server is currently running pub to produce a list of
+              package directories.
+            </p>
+          </field>
+        </object>
+      </type>
       <type name="RefactoringKind">
         <p>
           An enumeration of the kinds of refactorings that can be
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 7557ecd..f435fab6 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -12,10 +12,21 @@
   /**
    * Pass the given [message] to the instrumentation server so that it will be
    * logged with other messages.
+   *
+   * This method should be used for most logging.
    */
   void log(String message);
 
   /**
+   * Pass the given [message] to the instrumentation server so that it will be
+   * logged with other messages.
+   *
+   * This method should only be used for logging high priority messages, such as
+   * exceptions that cause the server to shutdown.
+   */
+  void logWithPriority(String message);
+
+  /**
    * Signal that the client is done communicating with the instrumentation
    * server. This method should be invoked exactly one time and no other methods
    * should be invoked on this instance after this method has been invoked.
@@ -24,21 +35,77 @@
 }
 
 /**
- * An [InstrumentationServer] that ignores all instrumentation requests sent to
- * it. It can be used when no instrumentation data is to be collected as a way
- * to avoid needing to check for null values.
+ * The interface used by client code to communicate with an instrumentation
+ * server by wrapping an [InstrumentationServer].
  */
-class NullInstrumentationServer implements InstrumentationServer {
+class InstrumentationService {
   /**
-   * Initialize a newly created instance of this class.
+   * An instrumentation service that will not log any instrumentation data.
    */
-  const NullInstrumentationServer();
+  static final InstrumentationService NULL_SERVICE =
+      new InstrumentationService(null);
 
-  @override
-  void log(String message) {
+  static const String TAG_NOTIFICATION = 'Noti';
+  static const String TAG_REQUEST = 'Req';
+  static const String TAG_RESPONSE = 'Res';
+  static const String TAG_VERSION = 'Ver';
+
+  /**
+   * The instrumentation server used to communicate with the server, or `null`
+   * if instrumentation data should not be logged.
+   */
+  InstrumentationServer _instrumentationServer;
+
+  /**
+   * Initialize a newly created instrumentation service to comunicate with the
+   * given [instrumentationServer].
+   */
+  InstrumentationService(this._instrumentationServer);
+
+  /**
+   * The current time, expressed as a decimal encoded number of milliseconds.
+   */
+  String get _timestamp => new DateTime.now().millisecond.toString();
+
+  /**
+   * Log that a notification has been sent to the client.
+   */
+  void logNotification(String notification) {
+    _log(TAG_NOTIFICATION, notification);
   }
 
-  @override
+  /**
+   * Log that a request has been sent to the client.
+   */
+  void logRequest(String request) {
+    _log(TAG_REQUEST, request);
+  }
+
+  /**
+   * Log that a response has been sent to the client.
+   */
+  void logResponse(String response) {
+    _log(TAG_RESPONSE, response);
+  }
+
+  /**
+   * Signal that the client is done communicating with the instrumentation
+   * server. This method should be invoked exactly one time and no other methods
+   * should be invoked on this instance after this method has been invoked.
+   */
   void shutdown() {
+    if (_instrumentationServer != null) {
+      _instrumentationServer.shutdown();
+      _instrumentationServer = null;
+    }
+  }
+
+  /**
+   * Log the given message with the given tag.
+   */
+  void _log(String tag, String message) {
+    if (_instrumentationServer != null) {
+      _instrumentationServer.log('$_timestamp:$tag:$message');
+    }
   }
 }
diff --git a/pkg/analyzer/lib/src/analyzer_impl.dart b/pkg/analyzer/lib/src/analyzer_impl.dart
index 879a7d9..20a965a 100644
--- a/pkg/analyzer/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer/lib/src/analyzer_impl.dart
@@ -8,6 +8,7 @@
 import 'dart:collection';
 import 'dart:io';
 
+import 'package:analyzer/file_system/file_system.dart' show Folder;
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/source/package_map_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
@@ -151,10 +152,13 @@
             new PubPackageMapProvider(PhysicalResourceProvider.INSTANCE, sdk);
         PackageMapInfo packageMapInfo = pubPackageMapProvider.computePackageMap(
             PhysicalResourceProvider.INSTANCE.getResource('.'));
-        resolvers.add(
-            new PackageMapUriResolver(
-                PhysicalResourceProvider.INSTANCE,
-                packageMapInfo.packageMap));
+        Map<String, List<Folder>> packageMap = packageMapInfo.packageMap;
+        if (packageMap != null) {
+          resolvers.add(
+              new PackageMapUriResolver(
+                  PhysicalResourceProvider.INSTANCE,
+                  packageMap));
+        }
       }
     }
     sourceFactory = new SourceFactory(resolvers);
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
new file mode 100644
index 0000000..c52b94b
--- /dev/null
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -0,0 +1,302 @@
+// 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 cancelable_future;
+
+import 'dart:async';
+
+/**
+ * Type of callback called when the future returned by a CancelableCompleter
+ * is canceled.
+ */
+typedef void CancelHandler();
+
+/**
+ * A way to produce [CancelableFuture] objects and to complete them later with
+ * a value or error.
+ *
+ * This class behaves like the standard library [Completer] class, except that
+ * its [future] getter returns a [CancelableFuture].
+ *
+ * If the future is canceled before being completed, the [CancelHandler] which
+ * was passed to the constructor is invoked, and any further attempt to
+ * complete the future has no effect.  For example, in the following code:
+ *
+ *     main() {
+ *       var cc = new CancelableCompleter(() {
+ *         print('cancelled'); // (2)
+ *       });
+ *       cc.future.then((value) {
+ *         print('completed with value $value');
+ *       }, onError: (error) {
+ *         print('completed with error $error'); // (3)
+ *       });
+ *       cc.future.cancel(); // (1)
+ *     }
+ *
+ * The call at (1) causes (2) to be invoked immediately.  (3) will be invoked
+ * later (on a microtask), with an error that is an instance of
+ * [FutureCanceledError].
+ *
+ * Note that since the closure passed to then() is executed on a microtask,
+ * there is a short window of time between the call to [complete] and the
+ * client being informed that the future has completed.  During this window,
+ * any attempt to cancel the future will have no effect.  For example, in the
+ * following code:
+ *
+ *     main() {
+ *       var cc = new CancelableCompleter(() {
+ *         print('cancelled'); // (3)
+ *       });
+ *       cc.future.then((value) {
+ *         print('completed with value $value'); // (4)
+ *       }, onError: (error) {
+ *         print('completed with error $error');
+ *       });
+ *       cc.complete(100); // (1)
+ *       cc.future.cancel(); // (2)
+ *     }
+ *
+ * The call at (1) will place the completer in the "completed" state, so the
+ * call at (2) will have no effect (in particular, (3) won't ever execute).
+ * Later, (4) will be invoked on a microtask.
+ */
+class CancelableCompleter<T> implements Completer<T> {
+  /**
+   * The completer which holds the state of the computation.  If the
+   * computation is canceled, this completer will remain in the non-completed
+   * state.
+   */
+  final Completer<T> _innerCompleter = new Completer<T>.sync();
+
+  /**
+   * The completer which holds the future that is exposed to the client
+   * through [future].  If the computation is canceled, this completer will
+   * be completed with a FutureCanceledError.
+   */
+  final Completer<T> _outerCompleter = new Completer<T>();
+
+  /**
+   * The callback to invoke if the 'cancel' method is called on the future
+   * returned by [future].  This callback will only be invoked if the future
+   * is canceled before being completed.
+   */
+  final CancelHandler _onCancel;
+
+  _CancelableCompleterFuture<T> _future;
+
+  /**
+   * Create a CancelableCompleter that will invoke the given callback
+   * synchronously if its future is canceled.  The callback will not be
+   * invoked if the future is completed before being canceled.
+   */
+  CancelableCompleter(this._onCancel) {
+    _future = new _CancelableCompleterFuture<T>(this);
+
+    // When the client completes the inner completer, we need to check whether
+    // the outer completer has been completed.  If it has, then the operation
+    // was canceled before it finished, and it's too late to un-cancel it, so
+    // we just ignore the result from the inner completer.  If it hasn't, then
+    // we simply pass along the result from the inner completer to the outer
+    // completer.
+    //
+    // Note that the reason it is safe for the inner completer to be
+    // synchronous is that we don't expose its future to client code, and we
+    // only use it to complete the outer completer (which is asynchronous).
+    _innerCompleter.future.then((T value) {
+      if (!_outerCompleter.isCompleted) {
+        _outerCompleter.complete(value);
+      }
+    }, onError: (Object error, StackTrace stackTrace) {
+      if (!_outerCompleter.isCompleted) {
+        _outerCompleter.completeError(error, stackTrace);
+      }
+    });
+  }
+
+  /**
+   * The [CancelableFuture] that will contain the result provided to this
+   * completer.
+   */
+  @override
+  CancelableFuture<T> get future => _future;
+
+  /**
+   * Whether the future has been completed.  This is independent of whether
+   * the future has been canceled.
+   */
+  @override
+  bool get isCompleted => _innerCompleter.isCompleted;
+
+  /**
+   * Complete [future] with the supplied value.  If the future has previously
+   * been canceled, this will have no effect on [future], however it will
+   * still set [isCompleted] to true.
+   */
+  @override
+  void complete([value]) {
+    _innerCompleter.complete(value);
+  }
+
+  /**
+   * Complete [future] with an error.  If the future has previously been
+   * canceled, this will have no effect on [future], however it will still set
+   * [isCompleted] to true.
+   */
+  @override
+  void completeError(Object error, [StackTrace stackTrace]) {
+    _innerCompleter.completeError(error, stackTrace);
+  }
+
+  void _cancel() {
+    if (!_outerCompleter.isCompleted) {
+      _outerCompleter.completeError(new FutureCanceledError());
+      _onCancel();
+    }
+  }
+}
+
+/**
+ * An object representing a delayed computation that can be canceled.
+ */
+abstract class CancelableFuture<T> implements Future<T> {
+  /**
+   * A CancelableFuture containing the result of calling [computation]
+   * asynchronously.  Since the computation is started without delay, calling
+   * the future's cancel method will have no effect.
+   */
+  factory CancelableFuture(computation()) =>
+      new _WrappedFuture<T>(new Future<T>(computation));
+
+  /**
+   * A CancelableFuture containing the result of calling [computation] after
+   * [duration] has passed.
+   *
+   * TODO(paulberry): if the future is canceled before the duration has
+   * elapsed, the computation should not be performed.
+   */
+  factory CancelableFuture.delayed(Duration duration, [computation()]) =>
+      new _WrappedFuture<T>(new Future<T>.delayed(duration, computation));
+
+  /**
+   * A CancelableFuture that completes with error.  Since the future is
+   * completed without delay, calling the future's cancel method will have no
+   * effect.
+   */
+  factory CancelableFuture.error(Object error, [StackTrace stackTrace]) =>
+      new _WrappedFuture<T>(new Future<T>.error(error, stackTrace));
+
+  /**
+   * A CancelableFuture containing the result of calling [computation]
+   * asynchronously with scheduleMicrotask.  Since the computation is started
+   * without delay, calling the future's cancel method will have no effect.
+   */
+  factory CancelableFuture.microtask(computation()) =>
+      new _WrappedFuture<T>(new Future<T>.microtask(computation));
+
+  /**
+   * A CancelableFuture containing the result of immediately calling
+   * [computation].  Since the computation is started without delay, calling
+   * the future's cancel method will have no effect.
+   */
+  factory CancelableFuture.sync(computation()) =>
+      new _WrappedFuture<T>(new Future<T>.sync(computation));
+
+  /**
+   * A CancelableFuture whose value is available in the next event-loop
+   * iteration.  Since the value is available without delay, calling the
+   * future's cancel method will have no effect.
+   */
+  factory CancelableFuture.value([value]) =>
+      new _WrappedFuture<T>(new Future<T>.value(value));
+
+  /**
+   * If the delayed computation has not yet completed, attempt to cancel it.
+   * Note that the cancellation is not always possible.  If the computation
+   * could be canceled, the future is completed with a FutureCanceledError.
+   * Otherwise it will behave as though cancel() was not called.
+   *
+   * Note that attempting to cancel a future that has already completed will
+   * never succeed--futures that have already completed retain their final
+   * state forever.
+   */
+  void cancel();
+}
+
+/**
+ * Error which is used to complete any [CancelableFuture] which has been
+ * successfully canceled by calling its 'cancel' method.
+ */
+class FutureCanceledError {
+}
+
+class _CancelableCompleterFuture<T> implements CancelableFuture<T> {
+  final CancelableCompleter<T> _completer;
+
+  _CancelableCompleterFuture(this._completer);
+
+  @override
+  Stream<T> asStream() {
+    // TODO(paulberry): Implement this in such a way that
+    // StreamSubscription.cancel() cancels the future.
+    return _completer._outerCompleter.future.asStream();
+  }
+
+  @override
+  void cancel() {
+    _completer._cancel();
+  }
+
+  @override
+  Future catchError(Function onError, {bool test(Object error)}) =>
+      _completer._outerCompleter.future.catchError(onError, test: test);
+
+  @override
+  Future then(onValue(T value), {Function onError}) =>
+      _completer._outerCompleter.future.then(onValue, onError: onError);
+
+  @override
+  Future timeout(Duration timeLimit, {onTimeout()}) {
+    // TODO(paulberry): Implement this in such a way that a timeout cancels
+    // the future.
+    return _completer._outerCompleter.future.timeout(
+        timeLimit,
+        onTimeout: onTimeout);
+  }
+
+  @override
+  Future<T> whenComplete(action()) =>
+      _completer._outerCompleter.future.whenComplete(action);
+}
+
+/**
+ * A CancelableFuture that wraps an ordinary Future.  Attempting to cancel a
+ * _WrappedFuture has no effect.
+ */
+class _WrappedFuture<T> implements CancelableFuture<T> {
+  final Future<T> _future;
+
+  _WrappedFuture(this._future);
+
+  @override
+  Stream asStream() => _future.asStream();
+
+  @override
+  void cancel() {}
+
+  @override
+  Future catchError(Function onError, {bool test(Object error)}) =>
+      _future.catchError(onError, test: test);
+
+  @override
+  Future then(onValue(value), {Function onError}) =>
+      _future.then(onValue, onError: onError);
+
+  @override
+  Future timeout(Duration timeLimit, {onTimeout()}) =>
+      _future.timeout(timeLimit, onTimeout: onTimeout);
+
+  @override
+  Future whenComplete(action()) => _future.whenComplete(action);
+}
diff --git a/pkg/analyzer/lib/src/generated/element.dart b/pkg/analyzer/lib/src/generated/element.dart
index c4f3470..b102383 100644
--- a/pkg/analyzer/lib/src/generated/element.dart
+++ b/pkg/analyzer/lib/src/generated/element.dart
@@ -4854,6 +4854,12 @@
  */
 abstract class FieldElement implements ClassMemberElement,
     PropertyInducingElement {
+  /**
+   * Return {@code true} if this element is an enum constant.
+   * 
+   * @return {@code true} if this an enum constant
+   */
+  bool get isEnumConstant;
 }
 
 /**
@@ -4902,6 +4908,10 @@
 
   @override
   accept(ElementVisitor visitor) => visitor.visitFieldElement(this);
+
+  @override
+  bool get isEnumConstant =>
+      enclosingElement != null ? enclosingElement.isEnum : false;
 }
 
 /**
@@ -5074,6 +5084,9 @@
     }
     return false;
   }
+
+  @override
+  bool get isEnumConstant => baseElement.isEnumConstant;
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/element_handle.dart b/pkg/analyzer/lib/src/generated/element_handle.dart
index 5276ce8..9e36518 100644
--- a/pkg/analyzer/lib/src/generated/element_handle.dart
+++ b/pkg/analyzer/lib/src/generated/element_handle.dart
@@ -606,6 +606,9 @@
 
   @override
   ElementKind get kind => ElementKind.FIELD;
+
+  @override
+  bool get isEnumConstant => actualElement.isEnumConstant;
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 9d50042..038ace0 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -11,8 +11,10 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/task/task_dart.dart';
 
+import '../../instrumentation/instrumentation.dart';
 import 'ast.dart';
 import 'constant.dart';
 import 'element.dart';
@@ -22,7 +24,6 @@
 import 'incremental_resolver.dart' show IncrementalResolver,
     PoorMansIncrementalResolver;
 import 'incremental_scanner.dart';
-import 'instrumentation.dart';
 import 'java_core.dart';
 import 'java_engine.dart';
 import 'parser.dart' show Parser, IncrementalParser;
@@ -34,6 +35,21 @@
 import 'utilities_general.dart';
 
 /**
+ * Type of callback functions used by PendingFuture.  Functions of this type
+ * should perform a computation based on the data in [sourceEntry] and return
+ * it.  If the computation can't be performed yet because more analysis is
+ * needed, null should be returned.
+ *
+ * The function may also throw an exception, in which case the corresponding
+ * future will be completed with failure.
+ *
+ * Since this function is called while the state of analysis is being updated,
+ * it should be free of side effects so that it doesn't cause reentrant
+ * changes to the analysis state.
+ */
+typedef T PendingFutureComputer<T>(SourceEntry sourceEntry);
+
+/**
  * Instances of the class `AnalysisCache` implement an LRU cache of information related to
  * analysis.
  */
@@ -533,6 +549,20 @@
   LineInfo computeLineInfo(Source source);
 
   /**
+   * Return a future which will be completed with the fully resolved AST for a
+   * single compilation unit within the given library, once that AST is up to
+   * date.
+   *
+   * If the resolved AST can't be computed for some reason, the future will be
+   * completed with an error.  One possible error is AnalysisNotScheduledError,
+   * which means that the resolved AST can't be computed because the given
+   * source file is not scheduled to be analyzed within the context of the
+   * given library.
+   */
+  CancelableFuture<CompilationUnit>
+      computeResolvedCompilationUnitAsync(Source source, Source librarySource);
+
+  /**
    * Notifies the context that the client is going to stop using this context.
    */
   void dispose();
@@ -951,6 +981,21 @@
   List<Source> _priorityOrder = Source.EMPTY_ARRAY;
 
   /**
+   * A map from all sources for which there are futures pending to a list of
+   * the corresponding PendingFuture objects.  These sources will be analyzed
+   * in the same way as priority sources, except with higher priority.
+   *
+   * TODO(paulberry): since the size of this map is not constrained (as it is
+   * for _priorityOrder), we run the risk of creating an analysis loop if
+   * re-caching one AST structure causes the AST structure for another source
+   * with pending futures to be flushed.  However, this is unlikely to happen
+   * in practice since sources are removed from this hash set as soon as their
+   * futures have completed.
+   */
+  HashMap<Source, List<PendingFuture>> _pendingFutureSources =
+      new HashMap<Source, List<PendingFuture>>();
+
+  /**
    * An array containing sources whose AST structure is needed in order to resolve the next library
    * to be resolved.
    */
@@ -1137,26 +1182,6 @@
     return sources;
   }
 
-  Element findElementById(int id) {
-    _ElementByIdFinder finder = new _ElementByIdFinder(id);
-    try {
-      MapIterator<Source, SourceEntry> iterator = _cache.iterator();
-      while (iterator.moveNext()) {
-        SourceEntry sourceEntry = iterator.value;
-        if (sourceEntry.kind == SourceKind.LIBRARY) {
-          DartEntry dartEntry = sourceEntry;
-          LibraryElement library = dartEntry.getValue(DartEntry.ELEMENT);
-          if (library != null) {
-            library.accept(finder);
-          }
-        }
-      }
-    } on _ElementByIdFinderException catch (e) {
-      return finder.result;
-    }
-    return null;
-  }
-
   @override
   List<Source> get librarySources => _getSources(SourceKind.LIBRARY);
 
@@ -1180,6 +1205,50 @@
       return task;
     }
     //
+    // Look for a source that needs to be analyzed because it has futures
+    // pending.
+    //
+    if (_pendingFutureSources.isNotEmpty) {
+      List<Source> sourcesToRemove = <Source>[];
+      AnalysisTask task;
+      for (Source source in _pendingFutureSources.keys) {
+        SourceEntry sourceEntry = _cache.get(source);
+        List<PendingFuture> pendingFutures = _pendingFutureSources[source];
+        for (int i = 0; i < pendingFutures.length; ) {
+          if (pendingFutures[i].evaluate(sourceEntry)) {
+            pendingFutures.removeAt(i);
+          } else {
+            i++;
+          }
+        }
+        if (pendingFutures.isEmpty) {
+          sourcesToRemove.add(source);
+          continue;
+        }
+        AnalysisContextImpl_TaskData taskData =
+            _getNextAnalysisTaskForSource(source, sourceEntry, true, hintsEnabled);
+        task = taskData.task;
+        if (task != null) {
+          break;
+        } else if (taskData.isBlocked) {
+          hasBlockedTask = true;
+        } else {
+          // There is no more work to do for this task, so forcibly complete
+          // all its pending futures.
+          for (PendingFuture pendingFuture in pendingFutures) {
+            pendingFuture.forciblyComplete();
+          }
+          sourcesToRemove.add(source);
+        }
+      }
+      for (Source source in sourcesToRemove) {
+        _pendingFutureSources.remove(source);
+      }
+      if (task != null) {
+        return task;
+      }
+    }
+    //
     // Look for a priority source that needs to be analyzed.
     //
     int priorityCount = _priorityOrder.length;
@@ -1258,6 +1327,12 @@
   Stream<SourcesChangedEvent> get onSourcesChanged =>
       _onSourcesChangedController.stream;
 
+  /**
+   * Make _pendingFutureSources available to unit tests.
+   */
+  HashMap<Source, List<PendingFuture>> get pendingFutureSources_forTesting =>
+      _pendingFutureSources;
+
   @override
   List<Source> get prioritySources => _priorityOrder;
 
@@ -1663,6 +1738,26 @@
     return unit;
   }
 
+  @override
+  CancelableFuture<CompilationUnit>
+      computeResolvedCompilationUnitAsync(Source unitSource, Source librarySource) {
+    return new _AnalysisFutureHelper<CompilationUnit>(
+        this).computeAsync(unitSource, (SourceEntry sourceEntry) {
+      if (sourceEntry is DartEntry) {
+        if (sourceEntry.getStateInLibrary(
+            DartEntry.RESOLVED_UNIT,
+            librarySource) ==
+            CacheState.ERROR) {
+          throw sourceEntry.exception;
+        }
+        return sourceEntry.getValueInLibrary(
+            DartEntry.RESOLVED_UNIT,
+            librarySource);
+      }
+      throw new AnalysisNotScheduledError();
+    });
+  }
+
   /**
    * Create an analysis cache based on the given source factory.
    *
@@ -1686,6 +1781,12 @@
   @override
   void dispose() {
     _disposed = true;
+    for (List<PendingFuture> pendingFutures in _pendingFutureSources.values) {
+      for (PendingFuture pendingFuture in pendingFutures) {
+        pendingFuture.forciblyComplete();
+      }
+    }
+    _pendingFutureSources.clear();
   }
 
   @override
@@ -1699,6 +1800,26 @@
     return source.exists();
   }
 
+  Element findElementById(int id) {
+    _ElementByIdFinder finder = new _ElementByIdFinder(id);
+    try {
+      MapIterator<Source, SourceEntry> iterator = _cache.iterator();
+      while (iterator.moveNext()) {
+        SourceEntry sourceEntry = iterator.value;
+        if (sourceEntry.kind == SourceKind.LIBRARY) {
+          DartEntry dartEntry = sourceEntry;
+          LibraryElement library = dartEntry.getValue(DartEntry.ELEMENT);
+          if (library != null) {
+            library.accept(finder);
+          }
+        }
+      }
+    } on _ElementByIdFinderException catch (e) {
+      return finder.result;
+    }
+    return null;
+  }
+
   @override
   AngularApplication getAngularApplicationWithHtml(Source htmlSource) {
     SourceEntry sourceEntry = getReadableSourceEntryOrNull(htmlSource);
@@ -2775,6 +2896,21 @@
   }
 
   /**
+   * Remove the given [pendingFuture] from [_pendingFutureSources], since the
+   * client has indicated its computation is not needed anymore.
+   */
+  void _cancelFuture(PendingFuture pendingFuture) {
+    List<PendingFuture> pendingFutures =
+        _pendingFutureSources[pendingFuture.source];
+    if (pendingFutures != null) {
+      pendingFutures.remove(pendingFuture);
+      if (pendingFutures.isEmpty) {
+        _pendingFutureSources.remove(pendingFuture.source);
+      }
+    }
+  }
+
+  /**
    * Compute the transitive closure of all libraries that depend on the given library by adding such
    * libraries to the given collection.
    *
@@ -5033,25 +5169,6 @@
   }
 }
 
-class _ElementByIdFinder extends GeneralizingElementVisitor {
-  final int _id;
-  Element result;
-
-  _ElementByIdFinder(this._id);
-
-  @override
-  visitElement(Element element) {
-    if (element.id == _id) {
-      result = element;
-      throw new _ElementByIdFinderException();
-    }
-    super.visitElement(element);
-  }
-}
-
-class _ElementByIdFinderException {
-}
-
 /**
  * An `AnalysisTaskResultRecorder` is used by an analysis context to record the
  * results of a task.
@@ -6023,8 +6140,8 @@
 }
 
 /**
- * The unique instance of the class `AnalysisEngine` serves as the entry point for the
- * functionality provided by the analysis engine.
+ * The unique instance of the class `AnalysisEngine` serves as the entry point
+ * for the functionality provided by the analysis engine.
  */
 class AnalysisEngine {
   /**
@@ -6060,6 +6177,12 @@
   Logger _logger = Logger.NULL;
 
   /**
+   * The instrumentation service that is to be used by this analysis engine.
+   */
+  InstrumentationService _instrumentationService =
+      InstrumentationService.NULL_SERVICE;
+
+  /**
    * The partition manager being used to manage the shared partitions.
    */
   final PartitionManager partitionManager = new PartitionManager();
@@ -6076,6 +6199,24 @@
   bool strictUnionTypes = false;
 
   /**
+   * Return the instrumentation service that is to be used by this analysis
+   * engine.
+   */
+  InstrumentationService get instrumentationService => _instrumentationService;
+
+  /**
+   * Set the instrumentation service that is to be used by this analysis engine
+   * to the given [service].
+   */
+  void set instrumentationService(InstrumentationService service) {
+    if (service == null) {
+      _instrumentationService = InstrumentationService.NULL_SERVICE;
+    } else {
+      _instrumentationService = service;
+    }
+  }
+
+  /**
    * Return the logger that should receive information about errors within the analysis engine.
    *
    * @return the logger that should receive information about errors within the analysis engine
@@ -6107,14 +6248,7 @@
    * @return the analysis context that was created
    */
   AnalysisContext createAnalysisContext() {
-    //
-    // If instrumentation is ignoring data, return an uninstrumented analysis
-    // context.
-    //
-    if (Instrumentation.isNullLogger) {
-      return new AnalysisContextImpl();
-    }
-    return new InstrumentedAnalysisContextImpl.con1(new AnalysisContextImpl());
+    return new AnalysisContextImpl();
   }
 
   /**
@@ -6305,6 +6439,16 @@
 }
 
 /**
+ * Futures returned by [AnalysisContext] for pending analysis results will
+ * complete with this error if it is determined that analysis results will
+ * never become available (e.g. because the requested source is not subject to
+ * analysis, or because the requested source is a part file which is not a part
+ * of any known library).
+ */
+class AnalysisNotScheduledError implements Exception {
+}
+
+/**
  * The interface `AnalysisOptions` defines the behavior of objects that provide access to a
  * set of analysis options used to control the behavior of an analysis context.
  */
@@ -9488,7 +9632,6 @@
   }
 }
 
-
 /**
  * Instances of the class `DataDescriptor` are immutable constants representing data that can
  * be stored in the cache.
@@ -9549,6 +9692,7 @@
   }
 }
 
+
 /**
  * Recursively visits [HtmlUnit] and every embedded [Expression].
  */
@@ -10579,849 +10723,6 @@
 }
 
 /**
- * Instances of the class `InstrumentedAnalysisContextImpl` implement an
- * [AnalysisContext] by recording instrumentation data and delegating to
- * another analysis context to do the non-instrumentation work.
- */
-class InstrumentedAnalysisContextImpl implements InternalAnalysisContext {
-  /**
-   * The unique identifier used to identify this analysis context in the instrumentation data.
-   */
-  String _contextId = UUID.randomUUID().toString();
-
-  /**
-   * The analysis context to which all of the non-instrumentation work is delegated.
-   */
-  InternalAnalysisContext _basis;
-
-  /**
-   * Create a new [InstrumentedAnalysisContextImpl] which wraps a new
-   * [AnalysisContextImpl] as the basis context.
-   */
-  InstrumentedAnalysisContextImpl() : this.con1(new AnalysisContextImpl());
-
-  /**
-   * Create a new [InstrumentedAnalysisContextImpl] with a specified basis context, aka the
-   * context to wrap and instrument.
-   *
-   * @param context some [InstrumentedAnalysisContext] to wrap and instrument
-   */
-  InstrumentedAnalysisContextImpl.con1(InternalAnalysisContext context) {
-    _basis = context;
-  }
-
-  @override
-  AnalysisOptions get analysisOptions {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getAnalysisOptions");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.analysisOptions;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  void set analysisOptions(AnalysisOptions options) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-setAnalysisOptions");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.analysisOptions = options;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  void set analysisPriorityOrder(List<Source> sources) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-setAnalysisPriorityOrder");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.analysisPriorityOrder = sources;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  /**
-   * @return the underlying [AnalysisContext].
-   */
-  AnalysisContext get basis => _basis;
-
-  @override
-  DeclaredVariables get declaredVariables => _basis.declaredVariables;
-
-  @override
-  List<Source> get htmlSources {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getHtmlSources");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<Source> ret = _basis.htmlSources;
-      if (ret != null) {
-        instrumentation.metric2("Source-count", ret.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  bool get isDisposed {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-isDisposed");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.isDisposed;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> get launchableClientLibrarySources {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLaunchableClientLibrarySources");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<Source> ret = _basis.launchableClientLibrarySources;
-      if (ret != null) {
-        instrumentation.metric2("Source-count", ret.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> get launchableServerLibrarySources {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLaunchableServerLibrarySources");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<Source> ret = _basis.launchableServerLibrarySources;
-      if (ret != null) {
-        instrumentation.metric2("Source-count", ret.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> get librarySources {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLibrarySources");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<Source> ret = _basis.librarySources;
-      if (ret != null) {
-        instrumentation.metric2("Source-count", ret.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  Stream<SourcesChangedEvent> get onSourcesChanged => _basis.onSourcesChanged;
-
-  @override
-  List<Source> get prioritySources {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getPrioritySources");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.prioritySources;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> get refactoringUnsafeSources {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getRefactoringUnsafeSources");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.refactoringUnsafeSources;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  SourceFactory get sourceFactory {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getSourceFactory");
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.sourceFactory;
-    } finally {
-      instrumentation.log2(2);
-      //Log if over 1ms
-    }
-  }
-
-  @override
-  void set sourceFactory(SourceFactory factory) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-setSourceFactory");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.sourceFactory = factory;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  AnalysisContextStatistics get statistics => _basis.statistics;
-
-  @override
-  TypeProvider get typeProvider => _basis.typeProvider;
-
-  @override
-  void addListener(AnalysisListener listener) {
-    _basis.addListener(listener);
-  }
-
-  @override
-  void addSourceInfo(Source source, SourceEntry info) {
-    _basis.addSourceInfo(source, info);
-  }
-
-  @override
-  void applyAnalysisDelta(AnalysisDelta delta) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-updateAnalysis");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.applyAnalysisDelta(delta);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  void applyChanges(ChangeSet changeSet) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-applyChanges");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.applyChanges(changeSet);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  String computeDocumentationComment(Element element) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-computeDocumentationComment");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.computeDocumentationComment(element);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<AnalysisError> computeErrors(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-computeErrors");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<AnalysisError> errors = _basis.computeErrors(source);
-      instrumentation.metric2("Errors-count", errors.length);
-      return errors;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> computeExportedLibraries(Source source) =>
-      _basis.computeExportedLibraries(source);
-
-  @override
-  HtmlElement computeHtmlElement(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-computeHtmlElement");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.computeHtmlElement(source);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> computeImportedLibraries(Source source) =>
-      _basis.computeImportedLibraries(source);
-
-  @override
-  SourceKind computeKindOf(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-computeKindOf");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.computeKindOf(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  LibraryElement computeLibraryElement(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-computeLibraryElement");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.computeLibraryElement(source);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  LineInfo computeLineInfo(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-computeLineInfo");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.computeLineInfo(source);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  CompilationUnit computeResolvableCompilationUnit(Source source) =>
-      _basis.computeResolvableCompilationUnit(source);
-
-  @override
-  void dispose() {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-dispose");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.dispose();
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  bool exists(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-exists");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.exists(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  AngularApplication getAngularApplicationWithHtml(Source htmlSource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getAngularApplication");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getAngularApplicationWithHtml(htmlSource);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  CompilationUnitElement getCompilationUnitElement(Source unitSource,
-      Source librarySource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getCompilationUnitElement");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getCompilationUnitElement(unitSource, librarySource);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  TimestampedData<String> getContents(Source source) =>
-      _basis.getContents(source);
-
-  @override
-  InternalAnalysisContext getContextFor(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getContextFor");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getContextFor(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  Element getElement(ElementLocation location) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getElement");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getElement(location);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  AnalysisErrorInfo getErrors(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getErrors");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      AnalysisErrorInfo ret = _basis.getErrors(source);
-      if (ret != null) {
-        instrumentation.metric2("Errors-count", ret.errors.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  HtmlElement getHtmlElement(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getHtmlElement");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getHtmlElement(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> getHtmlFilesReferencing(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getHtmlFilesReferencing");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<Source> ret = _basis.getHtmlFilesReferencing(source);
-      if (ret != null) {
-        instrumentation.metric2("Source-count", ret.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  SourceKind getKindOf(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getKindOf");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getKindOf(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> getLibrariesContaining(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLibrariesContaining");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<Source> ret = _basis.getLibrariesContaining(source);
-      if (ret != null) {
-        instrumentation.metric2("Source-count", ret.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log2(2);
-      //Log if 1ms
-    }
-  }
-
-  @override
-  List<Source> getLibrariesDependingOn(Source librarySource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLibrariesDependingOn");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      List<Source> ret = _basis.getLibrariesDependingOn(librarySource);
-      if (ret != null) {
-        instrumentation.metric2("Source-count", ret.length);
-      }
-      return ret;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  List<Source> getLibrariesReferencedFromHtml(Source htmlSource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLibrariesReferencedFromHtml");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getLibrariesReferencedFromHtml(htmlSource);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  LibraryElement getLibraryElement(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLibraryElement");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getLibraryElement(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  LineInfo getLineInfo(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getLineInfo");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getLineInfo(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  int getModificationStamp(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getModificationStamp");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getModificationStamp(source);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  Namespace getPublicNamespace(LibraryElement library) =>
-      _basis.getPublicNamespace(library);
-
-  @override
-  CompilationUnit getResolvedCompilationUnit(Source unitSource,
-      LibraryElement library) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getResolvedCompilationUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getResolvedCompilationUnit(unitSource, library);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  CompilationUnit getResolvedCompilationUnit2(Source unitSource,
-      Source librarySource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getResolvedCompilationUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getResolvedCompilationUnit2(unitSource, librarySource);
-    } finally {
-      instrumentation.log2(2);
-      //Log if over 1ms
-    }
-  }
-
-  @override
-  ht.HtmlUnit getResolvedHtmlUnit(Source htmlSource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-getResolvedHtmlUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.getResolvedHtmlUnit(htmlSource);
-    } finally {
-      instrumentation.log2(2);
-      //Log if over 1ms
-    }
-  }
-
-  @override
-  bool isClientLibrary(Source librarySource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-isClientLibrary");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.isClientLibrary(librarySource);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  bool isServerLibrary(Source librarySource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-isServerLibrary");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.isServerLibrary(librarySource);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  CompilationUnit parseCompilationUnit(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-parseCompilationUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.parseCompilationUnit(source);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  ht.HtmlUnit parseHtmlUnit(Source source) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-parseHtmlUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.parseHtmlUnit(source);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  AnalysisResult performAnalysisTask() {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-performAnalysisTask");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      AnalysisResult result = _basis.performAnalysisTask();
-      if (result.changeNotices != null) {
-        instrumentation.metric2(
-            "ChangeNotice-count",
-            result.changeNotices.length);
-      }
-      return result;
-    } finally {
-      instrumentation.log2(15);
-      //Log if >= 15ms
-    }
-  }
-
-  @override
-  void recordLibraryElements(Map<Source, LibraryElement> elementMap) {
-    _basis.recordLibraryElements(elementMap);
-  }
-
-  @override
-  void removeListener(AnalysisListener listener) {
-    _basis.removeListener(listener);
-  }
-
-  @override
-  CompilationUnit resolveCompilationUnit(Source unitSource,
-      LibraryElement library) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-resolveCompilationUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.resolveCompilationUnit(unitSource, library);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  CompilationUnit resolveCompilationUnit2(Source unitSource,
-      Source librarySource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-resolveCompilationUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.resolveCompilationUnit2(unitSource, librarySource);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  ht.HtmlUnit resolveHtmlUnit(Source htmlSource) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-resolveHtmlUnit");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      return _basis.resolveHtmlUnit(htmlSource);
-    } on AnalysisException catch (e, stackTrace) {
-      _recordAnalysisException(
-          instrumentation,
-          new CaughtException(e, stackTrace));
-      throw e;
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  void setChangedContents(Source source, String contents, int offset,
-      int oldLength, int newLength) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-setChangedContents");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.setChangedContents(source, contents, offset, oldLength, newLength);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  void setContents(Source source, String contents) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("Analysis-setContents");
-    _checkThread(instrumentation);
-    try {
-      instrumentation.metric3("contextId", _contextId);
-      _basis.setContents(source, contents);
-    } finally {
-      instrumentation.log();
-    }
-  }
-
-  @override
-  void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
-      DataDescriptor rowDesc, CacheState state)) {
-    _basis.visitCacheItems(callback);
-  }
-
-  /**
-   * If the current thread is the UI thread, then note this in the specified instrumentation and
-   * append this information to the log.
-   *
-   * @param instrumentation the instrumentation, not `null`
-   */
-  static void _checkThread(InstrumentationBuilder instrumentation) {
-  }
-
-  /**
-   * Record an exception that was thrown during analysis.
-   *
-   * @param instrumentation the instrumentation builder being used to record the exception
-   * @param exception the exception being reported
-   */
-  static void _recordAnalysisException(InstrumentationBuilder instrumentation,
-      CaughtException exception) {
-    instrumentation.record(exception);
-  }
-}
-
-/**
  * The interface `InternalAnalysisContext` defines additional behavior for an analysis context
  * that is required by internal users of the context.
  */
@@ -12362,6 +11663,87 @@
 }
 
 /**
+ * Representation of a pending computation which is based on the results of
+ * analysis that may or may not have been completed.
+ */
+class PendingFuture<T> {
+  /**
+   * The context in which this computation runs.
+   */
+  final AnalysisContextImpl _context;
+
+  /**
+   * The source used by this computation to compute its value.
+   */
+  final Source source;
+
+  /**
+   * The function which implements the computation.
+   */
+  final PendingFutureComputer<T> _computeValue;
+
+  /**
+   * The completer that should be completed once the computation has succeeded.
+   */
+  CancelableCompleter<T> _completer;
+
+  PendingFuture(this._context, this.source, this._computeValue) {
+    _completer = new CancelableCompleter<T>(_onCancel);
+  }
+
+  /**
+   * Retrieve the future which will be completed when this object is
+   * successfully evaluated.
+   */
+  CancelableFuture<T> get future => _completer.future;
+
+  /**
+   * Execute [_computeValue], passing it the given [sourceEntry], and complete
+   * the pending future if it's appropriate to do so.  If the pending future is
+   * completed by this call, true is returned; otherwise false is returned.
+   *
+   * Once this function has returned true, it should not be called again.
+   *
+   * Other than completing the future, this method is free of side effects.
+   * Note that any code the client has attached to the future will be executed
+   * in a microtask, so there is no danger of side effects occurring due to
+   * client callbacks.
+   */
+  bool evaluate(SourceEntry sourceEntry) {
+    assert(!_completer.isCompleted);
+    try {
+      T result = _computeValue(sourceEntry);
+      if (result == null) {
+        return false;
+      } else {
+        _completer.complete(result);
+        return true;
+      }
+    } catch (exception, stackTrace) {
+      _completer.completeError(exception, stackTrace);
+      return true;
+    }
+  }
+
+  /**
+   * No further analysis updates are expected which affect this future, so
+   * complete it with an AnalysisNotScheduledError in order to avoid
+   * deadlocking the client.
+   */
+  void forciblyComplete() {
+    try {
+      throw new AnalysisNotScheduledError();
+    } catch (exception, stackTrace) {
+      _completer.completeError(exception, stackTrace);
+    }
+  }
+
+  void _onCancel() {
+    _context._cancelFuture(this);
+  }
+}
+
+/**
  * Container with global [AnalysisContext] performance statistics.
  */
 class PerformanceStatistics {
@@ -14483,20 +13865,21 @@
    * discover the underlying cause of a long-standing bug.
    */
   void _validateStateChange(DataDescriptor descriptor, CacheState newState) {
-    if (descriptor != CONTENT) {
-      return;
-    }
-    CachedResult result = resultMap[CONTENT];
-    if (result != null && result.state == CacheState.ERROR) {
-      String message =
-          "contentState changing from ${result.state} to $newState";
-      InstrumentationBuilder builder =
-          Instrumentation.builder2("SourceEntry-validateStateChange");
-      builder.data3("message", message);
-      //builder.data("source", source.getFullName());
-      builder.record(new CaughtException(new AnalysisException(message), null));
-      builder.log();
-    }
+    // TODO(brianwilkerson) Decide whether we still want to capture this data.
+//    if (descriptor != CONTENT) {
+//      return;
+//    }
+//    CachedResult result = resultMap[CONTENT];
+//    if (result != null && result.state == CacheState.ERROR) {
+//      String message =
+//          "contentState changing from ${result.state} to $newState";
+//      InstrumentationBuilder builder =
+//          Instrumentation.builder2("SourceEntry-validateStateChange");
+//      builder.data3("message", message);
+//      //builder.data("source", source.getFullName());
+//      builder.record(new CaughtException(new AnalysisException(message), null));
+//      builder.log();
+//    }
   }
 
   /**
@@ -14950,6 +14333,53 @@
   }
 }
 
+/**
+ * Helper class used to create futures for AnalysisContextImpl.  Using a helper
+ * class allows us to preserve the generic parameter T.
+ */
+class _AnalysisFutureHelper<T> {
+  final AnalysisContextImpl _context;
+
+  _AnalysisFutureHelper(this._context);
+
+  /**
+   * Return a future that will be completed with the result of calling
+   * [computeValue].  If [computeValue] returns non-null, the future will be
+   * completed immediately with the resulting value.  If it returns null, then
+   * it will be re-executed in the future, after the next time the cached
+   * information for [source] has changed.  If [computeValue] throws an
+   * exception, the future will fail with that exception.
+   *
+   * If the [computeValue] still returns null after there is no further
+   * analysis to be done for [source], then the future will be completed with
+   * the error AnalysisNotScheduledError.
+   *
+   * Since [computeValue] will be called while the state of analysis is being
+   * updated, it should be free of side effects so that it doesn't cause
+   * reentrant changes to the analysis state.
+   */
+  CancelableFuture<T> computeAsync(Source source, T
+      computeValue(SourceEntry sourceEntry)) {
+    if (_context.isDisposed) {
+      // No further analysis is expected, so return a future that completes
+      // immediately with AnalysisNotScheduledError.
+      return new CancelableFuture.error(new AnalysisNotScheduledError());
+    }
+    SourceEntry sourceEntry = _context.getReadableSourceEntryOrNull(source);
+    if (sourceEntry == null) {
+      return new CancelableFuture.error(new AnalysisNotScheduledError());
+    }
+    PendingFuture pendingFuture =
+        new PendingFuture<T>(_context, source, computeValue);
+    if (!pendingFuture.evaluate(sourceEntry)) {
+      _context._pendingFutureSources.putIfAbsent(
+          source,
+          () => <PendingFuture>[]).add(pendingFuture);
+    }
+    return pendingFuture.future;
+  }
+}
+
 class _AngularHtmlUnitResolver_visitModelDirectives extends
     ht.RecursiveXmlVisitor<Object> {
   final AngularHtmlUnitResolver resolver;
@@ -14967,6 +14397,25 @@
   }
 }
 
+class _ElementByIdFinder extends GeneralizingElementVisitor {
+  final int _id;
+  Element result;
+
+  _ElementByIdFinder(this._id);
+
+  @override
+  visitElement(Element element) {
+    if (element.id == _id) {
+      result = element;
+      throw new _ElementByIdFinderException();
+    }
+    super.visitElement(element);
+  }
+}
+
+class _ElementByIdFinderException {
+}
+
 class _PolymerHtmlUnitBuilder_findTagDartElement extends
     RecursiveElementVisitor<Object> {
   final PolymerHtmlUnitBuilder PolymerHtmlUnitBuilder_this;
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 6a559e2..2271cf5 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -189,7 +189,6 @@
     ExecutableElement newElement = node.element;
     node.element = element;
     _setLocalElements(element, newElement);
-    _setParameterElements(node.parameters, element.parameters);
   }
 
   @override
@@ -267,9 +266,6 @@
     node.name.staticElement = element;
     node.functionExpression.element = element;
     _setLocalElements(element, newElement);
-    _setParameterElements(
-        node.functionExpression.parameters,
-        element.parameters);
   }
 
   @override
@@ -341,7 +337,6 @@
       // matches, update the existing element
       node.name.staticElement = element;
       _setLocalElements(element, newElement);
-      _setParameterElements(node.parameters, element.parameters);
     } on _DeclarationMismatchException catch (e) {
       _addedElements.add(newElement);
       // remove old element
@@ -674,20 +669,7 @@
     to.functions = from.functions;
     to.labels = from.labels;
     to.localVariables = from.localVariables;
-  }
-
-  static void _setParameterElements(FormalParameterList nodes,
-      List<ParameterElement> elements) {
-    if (nodes != null) {
-      for (int i = 0; i < elements.length; i++) {
-        ParameterElement element = elements[i];
-        FormalParameter node = nodes.parameters[i];
-        ParameterElement newElement = node.element;
-        node.identifier.staticElement = element;
-        (element as ElementImpl).name = newElement.name;
-        (element as ElementImpl).nameOffset = newElement.nameOffset;
-      }
-    }
+    to.parameters = from.parameters;
   }
 }
 
@@ -824,6 +806,10 @@
     try {
       ElementHolder holder = new ElementHolder();
       ElementBuilder builder = new ElementBuilder(holder);
+      if (_resolutionContext.enclosingClassDeclaration != null) {
+        builder.visitClassDeclarationIncrementally(
+            _resolutionContext.enclosingClassDeclaration);
+      }
       node.accept(builder);
     } finally {
       timer.stop('build elements');
diff --git a/pkg/analyzer/lib/src/generated/instrumentation.dart b/pkg/analyzer/lib/src/generated/instrumentation.dart
deleted file mode 100644
index 54e4789..0000000
--- a/pkg/analyzer/lib/src/generated/instrumentation.dart
+++ /dev/null
@@ -1,341 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// 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 engine.instrumentation;
-
-import 'java_core.dart';
-
-/**
- * The class `Instrumentation` implements support for logging instrumentation information.
- *
- * Instrumentation information consists of information about specific operations. Those operations
- * can range from user-facing operations, such as saving the changes to a file, to internal
- * operations, such as tokenizing source code. The information to be logged is gathered by
- * [InstrumentationBuilder], created by one of the static methods on
- * this class such as [builder] or [builder].
- *
- * Note, however, that until an instrumentation logger is installed using the method
- * [setLogger], all instrumentation data will be lost.
- *
- * <b>Example</b>
- *
- * To collect metrics about how long it took to save a file, you would write something like the
- * following:
- *
- * <pre>
- * InstrumentationBuilder instrumentation = Instrumentation.builder(this.getClass());
- * // save the file
- * instrumentation.metric("chars", fileLength).log();
- * </pre>
- * The `Instrumentation.builder` method creates a new [InstrumentationBuilder]
- * and records the time at which it was created. The
- * [InstrumentationBuilder.metric] appends the information specified by the
- * arguments and records the time at which the method is called so that the time to complete the
- * save operation can be calculated. The `log` method tells the builder that all of the data
- * has been collected and that the resulting information should be logged.
- */
-class Instrumentation {
-  /**
-   * A builder that will silently ignore all data and logging requests.
-   */
-  static InstrumentationBuilder _NULL_INSTRUMENTATION_BUILDER =
-      new InstrumentationBuilder_Instrumentation_NULL_INSTRUMENTATION_BUILDER();
-
-  /**
-   * An instrumentation logger that can be used when no other instrumentation logger has been
-   * configured. This logger will silently ignore all data and logging requests.
-   */
-  static InstrumentationLogger _NULL_LOGGER =
-      new InstrumentationLogger_Instrumentation_NULL_LOGGER();
-
-  /**
-   * The current instrumentation logger.
-   */
-  static InstrumentationLogger _CURRENT_LOGGER = _NULL_LOGGER;
-
-  /**
-   * Is this instrumentation system currently configured to drop instrumentation data provided to
-   * it?
-   *
-   * @return
-   */
-  static bool get isNullLogger => identical(_CURRENT_LOGGER, _NULL_LOGGER);
-
-  /**
-   * Get the currently active instrumentation logger
-   */
-  static InstrumentationLogger get logger => _CURRENT_LOGGER;
-
-  /**
-   * Set the logger that should receive instrumentation information to the given logger.
-   *
-   * @param logger the logger that should receive instrumentation information
-   */
-  static void set logger(InstrumentationLogger logger) {
-    _CURRENT_LOGGER = logger == null ? _NULL_LOGGER : logger;
-  }
-
-  /**
-   * Return a builder that will silently ignore all data and logging requests.
-   *
-   * @return the builder (not `null`)
-   */
-  static InstrumentationBuilder get nullBuilder =>
-      _NULL_INSTRUMENTATION_BUILDER;
-
-  /**
-   * Create a builder that can collect the data associated with an operation.
-   *
-   * @param clazz the class performing the operation (not `null`)
-   * @return the builder that was created (not `null`)
-   */
-  static InstrumentationBuilder builder(Type clazz) =>
-      _CURRENT_LOGGER.createBuilder(clazz.toString());
-
-  /**
-   * Create a builder that can collect the data associated with an operation.
-   *
-   * @param name the name used to uniquely identify the operation (not `null`)
-   * @return the builder that was created (not `null`)
-   */
-  static InstrumentationBuilder builder2(String name) =>
-      _CURRENT_LOGGER.createBuilder(name);
-}
-
-/**
- * The interface `InstrumentationBuilder` defines the behavior of objects used to collect data
- * about an operation that has occurred and record that data through an instrumentation logger.
- *
- * For an example of using objects that implement this interface, see [Instrumentation].
- */
-abstract class InstrumentationBuilder {
-  /**
-   * Answer the [InstrumentationLevel] of this `InstrumentationBuilder`.
-   *
-   * @return one of [InstrumentationLevel.EVERYTHING], [InstrumentationLevel.METRICS],
-   *         [InstrumentationLevel.OFF]
-   */
-  InstrumentationLevel get instrumentationLevel;
-
-  /**
-   * Append the given data to the data being collected by this builder. The information is declared
-   * to potentially contain data that is either user identifiable or contains user intellectual
-   * property (but is not guaranteed to contain either).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder data(String name, bool value);
-
-  /**
-   * Append the given data to the data being collected by this builder. The information is declared
-   * to potentially contain data that is either user identifiable or contains user intellectual
-   * property (but is not guaranteed to contain either).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder data2(String name, int value);
-
-  /**
-   * Append the given data to the data being collected by this builder. The information is declared
-   * to potentially contain data that is either user identifiable or contains user intellectual
-   * property (but is not guaranteed to contain either).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder data3(String name, String value);
-
-  /**
-   * Append the given data to the data being collected by this builder. The information is declared
-   * to potentially contain data that is either user identifiable or contains user intellectual
-   * property (but is not guaranteed to contain either).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder data4(String name, List<String> value);
-
-  /**
-   * Log the data that has been collected. The instrumentation builder should not be used after this
-   * method is invoked. The behavior of any method defined on this interface that is used after this
-   * method is invoked is undefined.
-   */
-  void log();
-
-  /**
-   * Log the data that has been collected. The instrumentation builder should not be used after this
-   * method is invoked. The behavior of any method defined on this interface that is used after this
-   * method is invoked is undefined.
-   *
-   * @param minTimeToLog if the total elapsed time is less than this, do not record
-   */
-  void log2(int minTimeToLog);
-
-  /**
-   * Append the given metric to the data being collected by this builder. The information is
-   * declared to contain only metrics data (data that is not user identifiable and does not contain
-   * user intellectual property).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder metric(String name, bool value);
-
-  /**
-   * Append the given metric to the data being collected by this builder. The information is
-   * declared to contain only metrics data (data that is not user identifiable and does not contain
-   * user intellectual property).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder metric2(String name, int value);
-
-  /**
-   * Append the given metric to the data being collected by this builder. The information is
-   * declared to contain only metrics data (data that is not user identifiable and does not contain
-   * user intellectual property).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder metric3(String name, String value);
-
-  /**
-   * Append the given metric to the data being collected by this builder. The information is
-   * declared to contain only metrics data (data that is not user identifiable and does not contain
-   * user intellectual property).
-   *
-   * @param name the name used to identify the data
-   * @param value the value of the data to be collected
-   * @return this builder
-   */
-  InstrumentationBuilder metric4(String name, List<String> value);
-
-  /**
-   * Append the given exception to the information being collected by this builder. The exception's
-   * class name is captured using [metric]. Other aspects of the exception
-   * may contain either user identifiable or contains user intellectual property (but is not
-   * guaranteed to contain either) and thus are captured using the various data methods such as
-   * [data].
-   *
-   * @param exception the exception (may be `null`)
-   */
-  InstrumentationBuilder record(Exception exception);
-}
-
-class InstrumentationBuilder_Instrumentation_NULL_INSTRUMENTATION_BUILDER
-    implements InstrumentationBuilder {
-  @override
-  InstrumentationLevel get instrumentationLevel => InstrumentationLevel.OFF;
-
-  @override
-  InstrumentationBuilder data(String name, bool value) => this;
-
-  @override
-  InstrumentationBuilder data2(String name, int value) => this;
-
-  @override
-  InstrumentationBuilder data3(String name, String value) => this;
-
-  @override
-  InstrumentationBuilder data4(String name, List<String> value) => this;
-
-  @override
-  void log() {
-  }
-
-  @override
-  void log2(int minTimeToLong) {
-  }
-
-  @override
-  InstrumentationBuilder metric(String name, bool value) => this;
-
-  @override
-  InstrumentationBuilder metric2(String name, int value) => this;
-
-  @override
-  InstrumentationBuilder metric3(String name, String value) => this;
-
-  @override
-  InstrumentationBuilder metric4(String name, List<String> value) => this;
-
-  @override
-  InstrumentationBuilder record(Exception exception) => this;
-}
-
-/**
- * The instrumentation recording level representing (1) recording [EVERYTHING] recording of
- * all instrumentation data, (2) recording only [METRICS] information, or (3) recording
- * turned [OFF] in which case nothing is recorded.
- */
-class InstrumentationLevel extends Enum<InstrumentationLevel> {
-  /** Recording all instrumented information */
-  static const InstrumentationLevel EVERYTHING =
-      const InstrumentationLevel('EVERYTHING', 0);
-
-  /** Recording only metrics */
-  static const InstrumentationLevel METRICS =
-      const InstrumentationLevel('METRICS', 1);
-
-  /** Nothing recorded */
-  static const InstrumentationLevel OFF = const InstrumentationLevel('OFF', 2);
-
-  static const List<InstrumentationLevel> values = const [
-      EVERYTHING,
-      METRICS,
-      OFF];
-
-  const InstrumentationLevel(String name, int ordinal) : super(name, ordinal);
-
-  static InstrumentationLevel fromString(String str) {
-    if (str == "EVERYTHING") {
-      return InstrumentationLevel.EVERYTHING;
-    }
-    if (str == "METRICS") {
-      return InstrumentationLevel.METRICS;
-    }
-    if (str == "OFF") {
-      return InstrumentationLevel.OFF;
-    }
-    throw new IllegalArgumentException("Unrecognised InstrumentationLevel");
-  }
-}
-
-/**
- * The interface `InstrumentationLogger` defines the behavior of objects that are used to log
- * instrumentation data.
- *
- * For an example of using objects that implement this interface, see [Instrumentation].
- */
-abstract class InstrumentationLogger {
-  /**
-   * Create a builder that can collect the data associated with an operation identified by the given
-   * name.
-   *
-   * @param name the name used to uniquely identify the operation
-   * @return the builder that was created
-   */
-  InstrumentationBuilder createBuilder(String name);
-}
-
-class InstrumentationLogger_Instrumentation_NULL_LOGGER implements
-    InstrumentationLogger {
-  @override
-  InstrumentationBuilder createBuilder(String name) =>
-      Instrumentation._NULL_INSTRUMENTATION_BUILDER;
-}
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 3641626c..ed6c1ad 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -13,7 +13,6 @@
 import 'ast.dart';
 import 'engine.dart' show AnalysisEngine, AnalysisOptionsImpl;
 import 'error.dart';
-import 'instrumentation.dart';
 import 'java_core.dart';
 import 'java_engine.dart';
 import 'scanner.dart';
@@ -2682,7 +2681,8 @@
         // class that was parsed.
         _parseClassDeclaration(commentAndMetadata, null);
         return null;
-      } else if (_matchesKeyword(Keyword.ABSTRACT) && _tokenMatchesKeyword(_peek(), Keyword.CLASS)) {
+      } else if (_matchesKeyword(Keyword.ABSTRACT) &&
+          _tokenMatchesKeyword(_peek(), Keyword.CLASS)) {
         _reportErrorForToken(ParserErrorCode.CLASS_IN_CLASS, _peek());
         // TODO(brianwilkerson) We don't currently have any way to capture the
         // class that was parsed.
@@ -2940,15 +2940,8 @@
    * @return the compilation unit that was parsed
    */
   CompilationUnit parseCompilationUnit(Token token) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.Parser.parseCompilationUnit");
-    try {
-      _currentToken = token;
-      return parseCompilationUnit2();
-    } finally {
-      instrumentation.log2(2);
-      //Record if >= 2ms
-    }
+    _currentToken = token;
+    return parseCompilationUnit2();
   }
 
   /**
@@ -3144,15 +3137,8 @@
    * @return the compilation unit that was parsed
    */
   CompilationUnit parseDirectives(Token token) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.Parser.parseDirectives");
-    try {
-      _currentToken = token;
-      return _parseDirectives();
-    } finally {
-      instrumentation.log2(2);
-      //Record if >= 2ms
-    }
+    _currentToken = token;
+    return _parseDirectives();
   }
 
   /**
@@ -3163,15 +3149,8 @@
    *         recognizable expression
    */
   Expression parseExpression(Token token) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.Parser.parseExpression");
-    try {
-      _currentToken = token;
-      return parseExpression2();
-    } finally {
-      instrumentation.log2(2);
-      //Record if >= 2ms
-    }
+    _currentToken = token;
+    return parseExpression2();
   }
 
   /**
@@ -3725,15 +3704,8 @@
    *         recognizable statement
    */
   Statement parseStatement(Token token) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.Parser.parseStatement");
-    try {
-      _currentToken = token;
-      return parseStatement2();
-    } finally {
-      instrumentation.log2(2);
-      //Record if >= 2ms
-    }
+    _currentToken = token;
+    return parseStatement2();
   }
 
   /**
@@ -3766,15 +3738,8 @@
    *         recognizable sequence of statements
    */
   List<Statement> parseStatements(Token token) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.Parser.parseStatements");
-    try {
-      _currentToken = token;
-      return _parseStatementList();
-    } finally {
-      instrumentation.log2(2);
-      //Record if >= 2ms
-    }
+    _currentToken = token;
+    return _parseStatementList();
   }
 
   /**
@@ -4799,7 +4764,9 @@
    */
   Expression _parseAssignableExpression(bool primaryAllowed) {
     if (_matchesKeyword(Keyword.SUPER)) {
-      return _parseAssignableSelector(new SuperExpression(getAndAdvance()), false);
+      return _parseAssignableSelector(
+          new SuperExpression(getAndAdvance()),
+          false);
     }
     //
     // A primary expression can start with an identifier. We resolve the
@@ -6392,7 +6359,9 @@
       Expression initialization = null;
       if (!_matches(TokenType.SEMICOLON)) {
         CommentAndMetadata commentAndMetadata = _parseCommentAndMetadata();
-        if (_matchesIdentifier() && (_tokenMatchesKeyword(_peek(), Keyword.IN) || _tokenMatches(_peek(), TokenType.COLON))) {
+        if (_matchesIdentifier() &&
+            (_tokenMatchesKeyword(_peek(), Keyword.IN) ||
+                _tokenMatches(_peek(), TokenType.COLON))) {
           List<VariableDeclaration> variables = new List<VariableDeclaration>();
           SimpleIdentifier variableName = parseSimpleIdentifier();
           variables.add(
@@ -7905,7 +7874,9 @@
     if (_matchesKeyword(Keyword.THIS)) {
       return new ThisExpression(getAndAdvance());
     } else if (_matchesKeyword(Keyword.SUPER)) {
-      return _parseAssignableSelector(new SuperExpression(getAndAdvance()), false);
+      return _parseAssignableSelector(
+          new SuperExpression(getAndAdvance()),
+          false);
     } else if (_matchesKeyword(Keyword.NULL)) {
       return new NullLiteral(getAndAdvance());
     } else if (_matchesKeyword(Keyword.FALSE)) {
@@ -8624,7 +8595,9 @@
           // --> "prefixOperator 'super' assignableSelector selector*"
           return new PrefixExpression(operator, _parseUnaryExpression());
         }
-        return new PrefixExpression(operator, new SuperExpression(getAndAdvance()));
+        return new PrefixExpression(
+            operator,
+            new SuperExpression(getAndAdvance()));
       }
       return new PrefixExpression(operator, _parseUnaryExpression());
     } else if (_currentToken.type.isIncrementOperator) {
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 8584a6f..d8106f6 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -17,7 +17,6 @@
 import 'error.dart';
 import 'error_verifier.dart';
 import 'html.dart' as ht;
-import 'instrumentation.dart';
 import 'java_core.dart';
 import 'java_engine.dart';
 import 'scanner.dart' as sc;
@@ -1297,18 +1296,39 @@
    * See [HintCode.UNNECESSARY_CAST].
    */
   bool _checkForUnnecessaryCast(AsExpression node) {
-    Expression expression = node.expression;
-    TypeName typeName = node.type;
-    DartType lhsType = expression.staticType;
-    DartType rhsType = typeName.type;
     // TODO(jwren) After dartbug.com/13732, revisit this, we should be able to
-    // remove the !(x instanceof TypeParameterType) checks.
+    // remove the (x is! TypeParameterType) checks.
+    AstNode parent = node.parent;
+    if (parent is ConditionalExpression && (node == parent.thenExpression || node == parent.elseExpression)) {
+      Expression thenExpression = parent.thenExpression;
+      DartType thenType;
+      if (thenExpression is AsExpression) {
+        thenType = thenExpression.expression.staticType;
+      } else {
+        thenType = thenExpression.staticType;
+      }
+      Expression elseExpression = parent.elseExpression;
+      DartType elseType;
+      if (elseExpression is AsExpression) {
+        elseType = elseExpression.expression.staticType;
+      } else {
+        elseType = elseExpression.staticType;
+      }
+      if (thenType != null &&
+          elseType != null &&
+          !thenType.isDynamic &&
+          !elseType.isDynamic &&
+          !thenType.isMoreSpecificThan(elseType) &&
+          !elseType.isMoreSpecificThan(thenType)) {
+        return false;
+      }
+    }
+    DartType lhsType = node.expression.staticType;
+    DartType rhsType = node.type.type;
     if (lhsType != null &&
         rhsType != null &&
         !lhsType.isDynamic &&
         !rhsType.isDynamic &&
-        lhsType is! TypeParameterType &&
-        rhsType is! TypeParameterType &&
         lhsType.isMoreSpecificThan(rhsType)) {
       _errorReporter.reportErrorForNode(HintCode.UNNECESSARY_CAST, node);
       return true;
@@ -3162,6 +3182,19 @@
     return null;
   }
 
+  /**
+   * Implementation of this method should be synchronized with
+   * [visitClassDeclaration].
+   */
+  void visitClassDeclarationIncrementally(ClassDeclaration node) {
+    //
+    // Process field declarations before constructors and methods so that field
+    // formal parameters can be correctly resolved to their fields.
+    //
+    ClassElement classElement = node.element;
+    _buildFieldMap(classElement.fields);
+  }
+
   @override
   Object visitClassTypeAlias(ClassTypeAlias node) {
     ElementHolder holder = new ElementHolder();
@@ -8396,84 +8429,70 @@
    */
   LibraryElement resolveEmbeddedLibrary(Source librarySource,
       CompilationUnit unit, bool fullAnalysis) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.LibraryResolver.resolveEmbeddedLibrary");
-    try {
-      instrumentation.metric("fullAnalysis", fullAnalysis);
-      instrumentation.data3("fullName", librarySource.fullName);
-      //
-      // Create the objects representing the library being resolved and the core
+    //
+    // Create the objects representing the library being resolved and the core
+    // library.
+    //
+    Library targetLibrary = _createLibraryWithUnit(librarySource, unit);
+    _coreLibrary = _libraryMap[_coreLibrarySource];
+    if (_coreLibrary == null) {
+      // This will be true unless the library being analyzed is the core
       // library.
-      //
-      Library targetLibrary = _createLibraryWithUnit(librarySource, unit);
-      _coreLibrary = _libraryMap[_coreLibrarySource];
+      _coreLibrary = createLibrary(_coreLibrarySource);
       if (_coreLibrary == null) {
-        // This will be true unless the library being analyzed is the core
-        // library.
-        _coreLibrary = createLibrary(_coreLibrarySource);
-        if (_coreLibrary == null) {
-          LibraryResolver2.missingCoreLibrary(
-              analysisContext,
-              _coreLibrarySource);
-        }
+        LibraryResolver2.missingCoreLibrary(
+            analysisContext,
+            _coreLibrarySource);
       }
-      instrumentation.metric3("createLibrary", "complete");
-      //
-      // Compute the set of libraries that need to be resolved together.
-      //
-      _computeEmbeddedLibraryDependencies(targetLibrary, unit);
-      _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
-      //
-      // Build the element models representing the libraries being resolved.
-      // This is done in three steps:
-      //
-      // 1. Build the basic element models without making any connections
-      //    between elements other than the basic parent/child relationships.
-      //    This includes building the elements representing the libraries.
-      // 2. Build the elements for the import and export directives. This
-      //    requires that we have the elements built for the referenced
-      //    libraries, but because of the possibility of circular references
-      //    needs to happen after all of the library elements have been created.
-      // 3. Build the rest of the type model by connecting superclasses, mixins,
-      //    and interfaces. This requires that we be able to compute the names
-      //    visible in the libraries being resolved, which in turn requires that
-      //    we have resolved the import directives.
-      //
-      _buildElementModels();
-      instrumentation.metric3("buildElementModels", "complete");
-      LibraryElement coreElement = _coreLibrary.libraryElement;
-      if (coreElement == null) {
-        throw new AnalysisException("Could not resolve dart:core");
-      }
-      _buildDirectiveModels();
-      instrumentation.metric3("buildDirectiveModels", "complete");
-      _typeProvider = new TypeProviderImpl(coreElement);
-      _buildTypeAliases();
-      _buildTypeHierarchies();
-      instrumentation.metric3("buildTypeHierarchies", "complete");
-      //
-      // Perform resolution and type analysis.
-      //
-      // TODO(brianwilkerson) Decide whether we want to resolve all of the
-      // libraries or whether we want to only resolve the target library.
-      // The advantage to resolving everything is that we have already done part
-      // of the work so we'll avoid duplicated effort. The disadvantage of
-      // resolving everything is that we might do extra work that we don't
-      // really care about. Another possibility is to add a parameter to this
-      // method and punt the decision to the clients.
-      //
-      //if (analyzeAll) {
-      _resolveReferencesAndTypes();
-      instrumentation.metric3("resolveReferencesAndTypes", "complete");
-      //} else {
-      //  resolveReferencesAndTypes(targetLibrary);
-      //}
-      _performConstantEvaluation();
-      instrumentation.metric3("performConstantEvaluation", "complete");
-      return targetLibrary.libraryElement;
-    } finally {
-      instrumentation.log();
     }
+    //
+    // Compute the set of libraries that need to be resolved together.
+    //
+    _computeEmbeddedLibraryDependencies(targetLibrary, unit);
+    _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
+    //
+    // Build the element models representing the libraries being resolved.
+    // This is done in three steps:
+    //
+    // 1. Build the basic element models without making any connections
+    //    between elements other than the basic parent/child relationships.
+    //    This includes building the elements representing the libraries.
+    // 2. Build the elements for the import and export directives. This
+    //    requires that we have the elements built for the referenced
+    //    libraries, but because of the possibility of circular references
+    //    needs to happen after all of the library elements have been created.
+    // 3. Build the rest of the type model by connecting superclasses, mixins,
+    //    and interfaces. This requires that we be able to compute the names
+    //    visible in the libraries being resolved, which in turn requires that
+    //    we have resolved the import directives.
+    //
+    _buildElementModels();
+    LibraryElement coreElement = _coreLibrary.libraryElement;
+    if (coreElement == null) {
+      throw new AnalysisException("Could not resolve dart:core");
+    }
+    _buildDirectiveModels();
+    _typeProvider = new TypeProviderImpl(coreElement);
+    _buildTypeAliases();
+    _buildTypeHierarchies();
+    //
+    // Perform resolution and type analysis.
+    //
+    // TODO(brianwilkerson) Decide whether we want to resolve all of the
+    // libraries or whether we want to only resolve the target library.
+    // The advantage to resolving everything is that we have already done part
+    // of the work so we'll avoid duplicated effort. The disadvantage of
+    // resolving everything is that we might do extra work that we don't
+    // really care about. Another possibility is to add a parameter to this
+    // method and punt the decision to the clients.
+    //
+    //if (analyzeAll) {
+    _resolveReferencesAndTypes();
+    //} else {
+    //  resolveReferencesAndTypes(targetLibrary);
+    //}
+    _performConstantEvaluation();
+    return targetLibrary.libraryElement;
   }
 
   /**
@@ -8490,95 +8509,74 @@
    * @throws AnalysisException if the library could not be resolved for some reason
    */
   LibraryElement resolveLibrary(Source librarySource, bool fullAnalysis) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.LibraryResolver.resolveLibrary");
-    try {
-      instrumentation.metric("fullAnalysis", fullAnalysis);
-      instrumentation.data3("fullName", librarySource.fullName);
-      //
-      // Create the objects representing the library being resolved and the core
+    //
+    // Create the objects representing the library being resolved and the core
+    // library.
+    //
+    Library targetLibrary = createLibrary(librarySource);
+    _coreLibrary = _libraryMap[_coreLibrarySource];
+    if (_coreLibrary == null) {
+      // This will be true unless the library being analyzed is the core
       // library.
-      //
-      Library targetLibrary = createLibrary(librarySource);
-      _coreLibrary = _libraryMap[_coreLibrarySource];
+      _coreLibrary = _createLibraryOrNull(_coreLibrarySource);
       if (_coreLibrary == null) {
-        // This will be true unless the library being analyzed is the core
-        // library.
-        _coreLibrary = _createLibraryOrNull(_coreLibrarySource);
-        if (_coreLibrary == null) {
-          LibraryResolver2.missingCoreLibrary(
-              analysisContext,
-              _coreLibrarySource);
-        }
+        LibraryResolver2.missingCoreLibrary(
+            analysisContext,
+            _coreLibrarySource);
       }
-      instrumentation.metric3("createLibrary", "complete");
-      //
-      // Compute the set of libraries that need to be resolved together.
-      //
-      _computeLibraryDependencies(targetLibrary);
-      _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
-      //
-      // Build the element models representing the libraries being resolved.
-      // This is done in three steps:
-      //
-      // 1. Build the basic element models without making any connections
-      //    between elements other than the basic parent/child relationships.
-      //    This includes building the elements representing the libraries, but
-      //    excludes members defined in enums.
-      // 2. Build the elements for the import and export directives. This
-      //    requires that we have the elements built for the referenced
-      //    libraries, but because of the possibility of circular references
-      //    needs to happen after all of the library elements have been created.
-      // 3. Build the members in enum declarations.
-      // 4. Build the rest of the type model by connecting superclasses, mixins,
-      //    and interfaces. This requires that we be able to compute the names
-      //    visible in the libraries being resolved, which in turn requires that
-      //    we have resolved the import directives.
-      //
-      _buildElementModels();
-      instrumentation.metric3("buildElementModels", "complete");
-      LibraryElement coreElement = _coreLibrary.libraryElement;
-      if (coreElement == null) {
-        throw new AnalysisException("Could not resolve dart:core");
-      }
-      _buildDirectiveModels();
-      instrumentation.metric3("buildDirectiveModels", "complete");
-      _typeProvider = new TypeProviderImpl(coreElement);
-      _buildEnumMembers();
-      _buildTypeAliases();
-      _buildTypeHierarchies();
-      _buildImplicitConstructors();
-      instrumentation.metric3("buildTypeHierarchies", "complete");
-      //
-      // Perform resolution and type analysis.
-      //
-      // TODO(brianwilkerson) Decide whether we want to resolve all of the
-      // libraries or whether we want to only resolve the target library. The
-      // advantage to resolving everything is that we have already done part of
-      // the work so we'll avoid duplicated effort. The disadvantage of
-      // resolving everything is that we might do extra work that we don't
-      // really care about. Another possibility is to add a parameter to this
-      // method and punt the decision to the clients.
-      //
-      //if (analyzeAll) {
-      _resolveReferencesAndTypes();
-      instrumentation.metric3("resolveReferencesAndTypes", "complete");
-      //} else {
-      //  resolveReferencesAndTypes(targetLibrary);
-      //}
-      _performConstantEvaluation();
-      instrumentation.metric3("performConstantEvaluation", "complete");
-      instrumentation.metric2("librariesInCycles", _librariesInCycles.length);
-      for (Library lib in _librariesInCycles) {
-        instrumentation.metric2(
-            "librariesInCycles-CompilationUnitSources-Size",
-            lib.compilationUnitSources.length);
-      }
-      return targetLibrary.libraryElement;
-    } finally {
-      instrumentation.log2(15);
-      //Log if >= than 15ms
     }
+    //
+    // Compute the set of libraries that need to be resolved together.
+    //
+    _computeLibraryDependencies(targetLibrary);
+    _librariesInCycles = _computeLibrariesInCycles(targetLibrary);
+    //
+    // Build the element models representing the libraries being resolved.
+    // This is done in three steps:
+    //
+    // 1. Build the basic element models without making any connections
+    //    between elements other than the basic parent/child relationships.
+    //    This includes building the elements representing the libraries, but
+    //    excludes members defined in enums.
+    // 2. Build the elements for the import and export directives. This
+    //    requires that we have the elements built for the referenced
+    //    libraries, but because of the possibility of circular references
+    //    needs to happen after all of the library elements have been created.
+    // 3. Build the members in enum declarations.
+    // 4. Build the rest of the type model by connecting superclasses, mixins,
+    //    and interfaces. This requires that we be able to compute the names
+    //    visible in the libraries being resolved, which in turn requires that
+    //    we have resolved the import directives.
+    //
+    _buildElementModels();
+    LibraryElement coreElement = _coreLibrary.libraryElement;
+    if (coreElement == null) {
+      throw new AnalysisException("Could not resolve dart:core");
+    }
+    _buildDirectiveModels();
+    _typeProvider = new TypeProviderImpl(coreElement);
+    _buildEnumMembers();
+    _buildTypeAliases();
+    _buildTypeHierarchies();
+    _buildImplicitConstructors();
+    //
+    // Perform resolution and type analysis.
+    //
+    // TODO(brianwilkerson) Decide whether we want to resolve all of the
+    // libraries or whether we want to only resolve the target library. The
+    // advantage to resolving everything is that we have already done part of
+    // the work so we'll avoid duplicated effort. The disadvantage of
+    // resolving everything is that we might do extra work that we don't
+    // really care about. Another possibility is to add a parameter to this
+    // method and punt the decision to the clients.
+    //
+    //if (analyzeAll) {
+    _resolveReferencesAndTypes();
+    //} else {
+    //  resolveReferencesAndTypes(targetLibrary);
+    //}
+    _performConstantEvaluation();
+    return targetLibrary.libraryElement;
   }
 
   /**
@@ -9309,79 +9307,60 @@
    */
   LibraryElement resolveLibrary(Source librarySource,
       List<ResolvableLibrary> librariesInCycle) {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.LibraryResolver.resolveLibrary");
-    try {
-      instrumentation.data3("fullName", librarySource.fullName);
-      //
-      // Build the map of libraries that are known.
-      //
-      this._librariesInCycle = librariesInCycle;
-      _libraryMap = _buildLibraryMap();
-      ResolvableLibrary targetLibrary = _libraryMap[librarySource];
-      _coreLibrary = _libraryMap[_coreLibrarySource];
-      instrumentation.metric3("buildLibraryMap", "complete");
-      //
-      // Build the element models representing the libraries being resolved.
-      // This is done in three steps:
-      //
-      // 1. Build the basic element models without making any connections
-      //    between elements other than the basic parent/child relationships.
-      //    This includes building the elements representing the libraries, but
-      //    excludes members defined in enums.
-      // 2. Build the elements for the import and export directives. This
-      //    requires that we have the elements built for the referenced
-      //    libraries, but because of the possibility of circular references
-      //    needs to happen after all of the library elements have been created.
-      // 3. Build the members in enum declarations.
-      // 4. Build the rest of the type model by connecting superclasses, mixins,
-      //    and interfaces. This requires that we be able to compute the names
-      //    visible in the libraries being resolved, which in turn requires that
-      //    we have resolved the import directives.
-      //
-      _buildElementModels();
-      instrumentation.metric3("buildElementModels", "complete");
-      LibraryElement coreElement = _coreLibrary.libraryElement;
-      if (coreElement == null) {
-        missingCoreLibrary(analysisContext, _coreLibrarySource);
-      }
-      _buildDirectiveModels();
-      instrumentation.metric3("buildDirectiveModels", "complete");
-      _typeProvider = new TypeProviderImpl(coreElement);
-      _buildEnumMembers();
-      _buildTypeAliases();
-      _buildTypeHierarchies();
-      _buildImplicitConstructors();
-      instrumentation.metric3("buildTypeHierarchies", "complete");
-      //
-      // Perform resolution and type analysis.
-      //
-      // TODO(brianwilkerson) Decide whether we want to resolve all of the
-      // libraries or whether we want to only resolve the target library. The
-      // advantage to resolving everything is that we have already done part of
-      // the work so we'll avoid duplicated effort. The disadvantage of
-      // resolving everything is that we might do extra work that we don't
-      // really care about. Another possibility is to add a parameter to this
-      // method and punt the decision to the clients.
-      //
-      //if (analyzeAll) {
-      _resolveReferencesAndTypes();
-      instrumentation.metric3("resolveReferencesAndTypes", "complete");
-      //} else {
-      //  resolveReferencesAndTypes(targetLibrary);
-      //}
-      _performConstantEvaluation();
-      instrumentation.metric3("performConstantEvaluation", "complete");
-      instrumentation.metric2("librariesInCycles", librariesInCycle.length);
-      for (ResolvableLibrary lib in librariesInCycle) {
-        instrumentation.metric2(
-            "librariesInCycles-CompilationUnitSources-Size",
-            lib.compilationUnitSources.length);
-      }
-      return targetLibrary.libraryElement;
-    } finally {
-      instrumentation.log();
+    //
+    // Build the map of libraries that are known.
+    //
+    this._librariesInCycle = librariesInCycle;
+    _libraryMap = _buildLibraryMap();
+    ResolvableLibrary targetLibrary = _libraryMap[librarySource];
+    _coreLibrary = _libraryMap[_coreLibrarySource];
+    //
+    // Build the element models representing the libraries being resolved.
+    // This is done in three steps:
+    //
+    // 1. Build the basic element models without making any connections
+    //    between elements other than the basic parent/child relationships.
+    //    This includes building the elements representing the libraries, but
+    //    excludes members defined in enums.
+    // 2. Build the elements for the import and export directives. This
+    //    requires that we have the elements built for the referenced
+    //    libraries, but because of the possibility of circular references
+    //    needs to happen after all of the library elements have been created.
+    // 3. Build the members in enum declarations.
+    // 4. Build the rest of the type model by connecting superclasses, mixins,
+    //    and interfaces. This requires that we be able to compute the names
+    //    visible in the libraries being resolved, which in turn requires that
+    //    we have resolved the import directives.
+    //
+    _buildElementModels();
+    LibraryElement coreElement = _coreLibrary.libraryElement;
+    if (coreElement == null) {
+      missingCoreLibrary(analysisContext, _coreLibrarySource);
     }
+    _buildDirectiveModels();
+    _typeProvider = new TypeProviderImpl(coreElement);
+    _buildEnumMembers();
+    _buildTypeAliases();
+    _buildTypeHierarchies();
+    _buildImplicitConstructors();
+    //
+    // Perform resolution and type analysis.
+    //
+    // TODO(brianwilkerson) Decide whether we want to resolve all of the
+    // libraries or whether we want to only resolve the target library. The
+    // advantage to resolving everything is that we have already done part of
+    // the work so we'll avoid duplicated effort. The disadvantage of
+    // resolving everything is that we might do extra work that we don't
+    // really care about. Another possibility is to add a parameter to this
+    // method and punt the decision to the clients.
+    //
+    //if (analyzeAll) {
+    _resolveReferencesAndTypes();
+    //} else {
+    //  resolveReferencesAndTypes(targetLibrary);
+    //}
+    _performConstantEvaluation();
+    return targetLibrary.libraryElement;
   }
 
   /**
@@ -10265,6 +10244,9 @@
     for (PropertyAccessorElement element in compilationUnit.accessors) {
       _addIfPublic(definedNames, element);
     }
+    for (ClassElement element in compilationUnit.enums) {
+      _addIfPublic(definedNames, element);
+    }
     for (FunctionElement element in compilationUnit.functions) {
       _addIfPublic(definedNames, element);
     }
@@ -11384,6 +11366,13 @@
   }
 
   /**
+   * Prepares this [ResolverVisitor] to using it for incremental resolution.
+   */
+  void initForIncrementalResolution() {
+    _overrideManager.enterScope();
+  }
+
+  /**
    * If it is appropriate to do so, override the current type of the static and propagated elements
    * associated with the given expression with the given type. Generally speaking, it is appropriate
    * if the given type is more specific than the current type.
@@ -11630,13 +11619,6 @@
     return null;
   }
 
-  /**
-   * Prepares this [ResolverVisitor] to using it for incremental resolution.
-   */
-  void initForIncrementalResolution() {
-    _overrideManager.enterScope();
-  }
-
   @override
   Object visitCompilationUnit(CompilationUnit node) {
     //
diff --git a/pkg/analyzer/lib/src/generated/scanner.dart b/pkg/analyzer/lib/src/generated/scanner.dart
index 893ab39..436a5bb 100644
--- a/pkg/analyzer/lib/src/generated/scanner.dart
+++ b/pkg/analyzer/lib/src/generated/scanner.dart
@@ -7,7 +7,6 @@
 import 'dart:collection';
 
 import 'error.dart';
-import 'instrumentation.dart';
 import 'java_engine.dart';
 import 'source.dart';
 
@@ -973,22 +972,12 @@
    * and return the first token in the list of tokens that were produced.
    */
   Token tokenize() {
-    InstrumentationBuilder instrumentation =
-        Instrumentation.builder2("dart.engine.AbstractScanner.tokenize");
-    int tokenCounter = 0;
-    try {
-      int next = _reader.advance();
-      while (next != -1) {
-        tokenCounter++;
-        next = bigSwitch(next);
-      }
-      _appendEofToken();
-      instrumentation.metric2("tokensCount", tokenCounter);
-      return firstToken;
-    } finally {
-      instrumentation.log2(2);
-      //Log if over 1ms
+    int next = _reader.advance();
+    while (next != -1) {
+      next = bigSwitch(next);
     }
+    _appendEofToken();
+    return firstToken;
   }
 
   void _appendBeginToken(TokenType type) {
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 4918519..58aee24 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -8,7 +8,6 @@
 library engine.source.io;
 
 import 'engine.dart';
-import 'instrumentation.dart';
 import 'java_core.dart';
 import 'java_engine.dart';
 import 'java_io.dart';
@@ -236,16 +235,17 @@
    * Record the time the IO took if it was slow
    */
   void _reportIfSlowIO(int nanos) {
-    //If slower than 10ms
-    if (nanos > 10 * TimeCounter.NANOS_PER_MILLI) {
-      InstrumentationBuilder builder = Instrumentation.builder2("SlowIO");
-      try {
-        builder.data3("fileName", fullName);
-        builder.metric2("IO-Time-Nanos", nanos);
-      } finally {
-        builder.log();
-      }
-    }
+    // TODO(brianwilkerson) Decide whether we still want to capture this data.
+//    //If slower than 10ms
+//    if (nanos > 10 * TimeCounter.NANOS_PER_MILLI) {
+//      InstrumentationBuilder builder = Instrumentation.builder2("SlowIO");
+//      try {
+//        builder.data3("fileName", fullName);
+//        builder.metric2("IO-Time-Nanos", nanos);
+//      } finally {
+//        builder.log();
+//      }
+//    }
   }
 }
 
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index c198284..ba009ad 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -115,6 +115,7 @@
     InterfaceTypeImpl enumType = new InterfaceTypeImpl.con1(enumElement);
     enumElement.type = enumType;
     enumElement.supertype = objectType;
+    enumElement.enum2 = true;
     //
     // Populate the fields.
     //
@@ -164,6 +165,7 @@
     //
     enumElement.fields = fields;
 
+
         // Client code isn't allowed to invoke the constructor, so we do not model it.
     return enumElement;
   }
diff --git a/pkg/analyzer/test/cancelable_future_test.dart b/pkg/analyzer/test/cancelable_future_test.dart
new file mode 100644
index 0000000..ed0e9af
--- /dev/null
+++ b/pkg/analyzer/test/cancelable_future_test.dart
@@ -0,0 +1,397 @@
+// 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.cancelable_future;
+
+import 'reflective_tests.dart';
+import 'package:analyzer/src/cancelable_future.dart';
+import 'dart:async';
+import 'package:unittest/unittest.dart';
+import 'package:watcher/src/utils.dart';
+
+void main() {
+  groupSep = ' | ';
+  runReflectiveTests(CancelableCompleterTests);
+  runReflectiveTests(CancelableFutureTests);
+}
+
+@ReflectiveTestCase()
+class CancelableFutureTests {
+  Future test_defaultConstructor_returnValue() {
+    Object obj = new Object();
+    bool callbackInvoked = false;
+    new CancelableFuture(() => obj).then((result) {
+      expect(callbackInvoked, isFalse);
+      expect(result, same(obj));
+      callbackInvoked = true;
+    }, onError: (error) {
+      fail('Expected successful completion');
+    });
+    expect(callbackInvoked, isFalse);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+    });
+  }
+
+  Future test_defaultConstructor_returnFuture() {
+    Object obj = new Object();
+    bool callbackInvoked = false;
+    new CancelableFuture(() => new Future(() => obj)).then((result) {
+      expect(callbackInvoked, isFalse);
+      expect(result, same(obj));
+      callbackInvoked = true;
+    }, onError: (error) {
+      fail('Expected successful completion');
+    });
+    expect(callbackInvoked, isFalse);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+    });
+  }
+
+  Future test_defaultConstructor_throwException() {
+    Object obj = new Object();
+    bool callbackInvoked = false;
+    new CancelableFuture(() {
+      throw obj;
+    }).then((result) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(callbackInvoked, isFalse);
+      expect(error, same(obj));
+      callbackInvoked = true;
+    });
+    expect(callbackInvoked, isFalse);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+    });
+  }
+
+  Future test_delayed_noCallback() {
+    DateTime start = new DateTime.now();
+    return new CancelableFuture.delayed(new Duration(seconds: 1)).then((result) {
+      DateTime end = new DateTime.now();
+      expect(result, isNull);
+      expect(end.difference(start).inMilliseconds > 900, isTrue);
+    });
+  }
+
+  Future test_delayed_withCallback() {
+    Object obj = new Object();
+    DateTime start = new DateTime.now();
+    return new CancelableFuture.delayed(new Duration(seconds: 1), () {
+      DateTime end = new DateTime.now();
+      expect(end.difference(start).inMilliseconds > 900, isTrue);
+      return obj;
+    }).then((result) {
+      expect(result, same(obj));
+    });
+  }
+
+  Future test_error() {
+    Object obj = new Object();
+    return new CancelableFuture.error(obj).then((result) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(error, same(obj));
+    });
+  }
+
+  Future test_microtask() {
+    Object obj = new Object();
+    bool callbackInvoked = false;
+    new CancelableFuture.microtask(() => obj).then((result) {
+      expect(callbackInvoked, isFalse);
+      expect(result, same(obj));
+      callbackInvoked = true;
+    }, onError: (error) {
+      fail('Expected successful completion');
+    });
+    expect(callbackInvoked, isFalse);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+    });
+  }
+
+  Future test_sync() {
+    Object obj = new Object();
+    bool callbackInvoked = false;
+    new CancelableFuture.sync(() => obj).then((result) {
+      expect(callbackInvoked, isFalse);
+      expect(result, same(obj));
+      callbackInvoked = true;
+    }, onError: (error) {
+      fail('Expected successful completion');
+    });
+    expect(callbackInvoked, isFalse);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+    });
+  }
+
+  Future test_value() {
+    Object obj = new Object();
+    return new CancelableFuture.value(obj).then((result) {
+      expect(result, same(obj));
+    }, onError: (error) {
+      fail('Expected successful completion');
+    });
+  }
+}
+
+@ReflectiveTestCase()
+class CancelableCompleterTests {
+  CancelableCompleter<Object> completer;
+  int cancelCount = 0;
+
+  void setUp() {
+    completer = new CancelableCompleter<Object>(() { cancelCount++; });
+  }
+
+  void test_initialState() {
+    expect(completer.isCompleted, isFalse);
+    expect(cancelCount, 0);
+  }
+
+  void test_complete_after_complete() {
+    // As with an ordinary Completer, calling complete() (or completeError)
+    // after calling complete() should throw an exception.
+    completer.complete();
+    expect(() { completer.complete(); }, throws);
+    expect(() { completer.completeError(new Object()); }, throws);
+  }
+
+  void test_complete_after_completeError() {
+    // As with an ordinary Completer, calling complete() (or completeError)
+    // after calling completeError() should throw an exception.
+    completer.completeError(new Object());
+    expect(() { completer.complete(); }, throws);
+    expect(() { completer.completeError(new Object()); }, throws);
+    // Now absorb the error that's in the completer's future.
+    completer.future.catchError((_) => null);
+  }
+
+  Future test_complete_before_chaining() {
+    Object obj = new Object();
+    completer.complete(obj);
+    expect(completer.isCompleted, isTrue);
+    bool callbackInvoked = false;
+    completer.future.then((result) {
+      expect(callbackInvoked, isFalse);
+      expect(result, same(obj));
+      callbackInvoked = true;
+    }, onError: (error) {
+      fail('Expected successful completion');
+    });
+    // The callback should be deferred to a microtask.
+    expect(callbackInvoked, isFalse);
+    expect(completer.isCompleted, isTrue);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+      expect(completer.isCompleted, isTrue);
+      expect(cancelCount, 0);
+    });
+  }
+
+  Future test_completeError_before_chaining() {
+    Object obj = new Object();
+    completer.completeError(obj);
+    expect(completer.isCompleted, isTrue);
+    bool callbackInvoked = false;
+    completer.future.then((_) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(callbackInvoked, isFalse);
+      expect(error, same(obj));
+      callbackInvoked = true;
+    });
+    // The callback should be deferred to a microtask.
+    expect(callbackInvoked, isFalse);
+    expect(completer.isCompleted, isTrue);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+      expect(completer.isCompleted, isTrue);
+      expect(cancelCount, 0);
+    });
+  }
+
+  Future test_complete_after_chaining() {
+    Object obj = new Object();
+    bool callbackInvoked = false;
+    completer.future.then((result) {
+      expect(callbackInvoked, isFalse);
+      expect(result, same(obj));
+      callbackInvoked = true;
+    }, onError: (error) {
+      fail('Expected successful completion');
+    });
+    expect(completer.isCompleted, isFalse);
+    // Running the event loop should have no effect since the completer hasn't
+    // been completed yet.
+    return pumpEventQueue().then((_) {
+      completer.complete(obj);
+      expect(completer.isCompleted, isTrue);
+      // The callback should be deferred to a microtask.
+      expect(callbackInvoked, isFalse);
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(callbackInvoked, isTrue);
+      expect(completer.isCompleted, isTrue);
+      expect(cancelCount, 0);
+    });
+  }
+
+  Future test_completeError_after_chaining() {
+    Object obj = new Object();
+    bool callbackInvoked = false;
+    completer.future.then((_) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(callbackInvoked, isFalse);
+      expect(error, same(obj));
+      callbackInvoked = true;
+    });
+    expect(completer.isCompleted, isFalse);
+    // Running the event loop should have no effect since the completer hasn't
+    // been completed yet.
+    return pumpEventQueue().then((_) {
+      completer.completeError(obj);
+      expect(completer.isCompleted, isTrue);
+      // The callback should be deferred to a microtask.
+      expect(callbackInvoked, isFalse);
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(callbackInvoked, isTrue);
+      expect(completer.isCompleted, isTrue);
+      expect(cancelCount, 0);
+    });
+  }
+
+  Future test_cancel_before_chaining() {
+    completer.future.cancel();
+    // The cancel callback should have been invoked immediately.
+    expect(cancelCount, 1);
+    // But the completer should remain in the "not completed" state.
+    expect(completer.isCompleted, isFalse);
+    bool callbackInvoked = false;
+    completer.future.then((_) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(callbackInvoked, isFalse);
+      expect(error, new isInstanceOf<FutureCanceledError>());
+      callbackInvoked = true;
+    });
+    // The callback should be deferred to a microtask.
+    expect(callbackInvoked, isFalse);
+    expect(completer.isCompleted, isFalse);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+      expect(completer.isCompleted, isFalse);
+      expect(cancelCount, 1);
+    });
+  }
+
+  Future test_cancel_after_chaining() {
+    bool callbackInvoked = false;
+    completer.future.then((_) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(callbackInvoked, isFalse);
+      expect(error, new isInstanceOf<FutureCanceledError>());
+      callbackInvoked = true;
+    });
+    expect(cancelCount, 0);
+    completer.future.cancel();
+    // The cancel callback should have been invoked immediately.
+    expect(cancelCount, 1);
+    // But the completer should remain in the "not completed" state.
+    expect(completer.isCompleted, isFalse);
+    // The callback should be deferred to a microtask.
+    expect(callbackInvoked, isFalse);
+    return pumpEventQueue().then((_) {
+      expect(callbackInvoked, isTrue);
+      expect(completer.isCompleted, isFalse);
+      expect(cancelCount, 1);
+    });
+  }
+
+  Future test_cancel_after_complete() {
+    Object obj = new Object();
+    completer.complete(obj);
+    completer.future.cancel();
+    // The cancel callback should not have been invoked, because it was too
+    // late to cancel.
+    expect(cancelCount, 0);
+    // Make sure the future still completes with the object.
+    return completer.future.then((result) {
+      expect(result, same(obj));
+      // And make sure nothing else happens.
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(completer.isCompleted, isTrue);
+      expect(cancelCount, 0);
+    });
+  }
+
+  Future test_complete_after_cancel() {
+    completer.future.cancel();
+    // The cancel callback should have been invoked immediately.
+    expect(cancelCount, 1);
+    // Completing should have no effect other than to set the isCompleted
+    // flag.
+    expect(completer.isCompleted, isFalse);
+    Object obj = new Object();
+    completer.complete(obj);
+    expect(completer.isCompleted, isTrue);
+    // Make sure the future still completer with error.
+    return completer.future.then((_) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(error, new isInstanceOf<FutureCanceledError>());
+      // And make sure nothing else happens.
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(completer.isCompleted, isTrue);
+      expect(cancelCount, 1);
+    });
+  }
+
+  Future test_completeError_after_cancel() {
+    completer.future.cancel();
+    // The cancel callback should have been invoked immediately.
+    expect(cancelCount, 1);
+    // Completing should have no effect other than to set the isCompleted
+    // flag.
+    expect(completer.isCompleted, isFalse);
+    Object obj = new Object();
+    completer.completeError(obj);
+    expect(completer.isCompleted, isTrue);
+    // Make sure the future still completes with error.
+    return completer.future.then((_) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(error, new isInstanceOf<FutureCanceledError>());
+      // And make sure nothing else happens.
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(completer.isCompleted, isTrue);
+      expect(cancelCount, 1);
+    });
+  }
+
+  Future test_cancel_after_cancel() {
+    // It is permissible to cancel multiple times, but only the first
+    // cancellation has any effect.
+    expect(cancelCount, 0);
+    completer.future.cancel();
+    expect(cancelCount, 1);
+    completer.future.cancel();
+    expect(cancelCount, 1);
+    // Make sure the future still completes with error.
+    return completer.future.then((_) {
+      fail('Expected error completion');
+    }, onError: (error) {
+      expect(error, new isInstanceOf<FutureCanceledError>());
+      // And make sure nothing else happens.
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(completer.isCompleted, isFalse);
+      expect(cancelCount, 1);
+    });
+  }
+}
\ No newline at end of file
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
index 13d3782..89d258e 100644
--- a/pkg/analyzer/test/enum_test.dart
+++ b/pkg/analyzer/test/enum_test.dart
@@ -10,7 +10,6 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/html.dart' as html;
-import 'package:analyzer/src/generated/instrumentation.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -88,12 +87,6 @@
         ..check_explicit_values();
   }
 
-  void test_InstrumentationLevel() {
-    new EnumTester<InstrumentationLevel>()
-        ..check_getters()
-        ..check_explicit_values();
-  }
-
   void test_Modifier() {
     new EnumTester<Modifier>()
         ..check_getters()
diff --git a/pkg/analyzer/test/generated/element_test.dart b/pkg/analyzer/test/generated/element_test.dart
index 61633db..145f8ea 100644
--- a/pkg/analyzer/test/generated/element_test.dart
+++ b/pkg/analyzer/test/generated/element_test.dart
@@ -126,6 +126,7 @@
         ElementFactory.fieldElement(fieldName, false, false, false, null);
     classA.fields = <FieldElement>[field];
     expect(classA.getField(fieldName), same(field));
+    expect(field.isEnumConstant, false);
     // no such field
     expect(classA.getField("noSuchField"), same(null));
   }
@@ -259,6 +260,22 @@
     expect(classA.hasStaticMember, isTrue);
   }
 
+  void test_isEnum() {
+    String firstConst = "A";
+    String secondConst = "B";
+    ClassElementImpl enumE = ElementFactory.enumElement(
+        new TestTypeProvider(),
+        "E",
+        [firstConst, secondConst]);
+
+    // E is an enum
+    expect(enumE.isEnum, true);
+
+    // A and B are static members
+    expect(enumE.getField(firstConst).isEnumConstant, true);
+    expect(enumE.getField(secondConst).isEnumConstant, true);
+  }
+
   void test_lookUpConcreteMethod_declared() {
     // class A {
     //   m() {}
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index ad8a21d..9b68e79 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -10,6 +10,7 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/src/cancelable_future.dart';
 import 'package:analyzer/src/generated/ast.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element.dart';
@@ -52,7 +53,6 @@
   runReflectiveTests(GetContentTaskTest);
   runReflectiveTests(HtmlEntryTest);
   runReflectiveTests(IncrementalAnalysisCacheTest);
-  runReflectiveTests(InstrumentedAnalysisContextImplTest);
   runReflectiveTests(IncrementalAnalysisTaskTest);
   runReflectiveTests(ParseDartTaskTest);
   runReflectiveTests(ParseHtmlTaskTest);
@@ -669,6 +669,137 @@
     expect(resolvedUnit, same(parsedUnit));
   }
 
+  Future test_computeResolvedCompilationUnitAsync() {
+    _context = AnalysisContextFactory.contextWithCore();
+    _sourceFactory = _context.sourceFactory;
+    Source source = _addSource("/lib.dart", "library lib;");
+    // Complete all pending analysis tasks and flush the AST so that it won't
+    // be available immediately.
+    _performPendingAnalysisTasks();
+    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
+    dartEntry.flushAstStructures();
+    bool completed = false;
+    _context.computeResolvedCompilationUnitAsync(
+        source,
+        source).then((CompilationUnit unit) {
+      expect(unit, isNotNull);
+      completed = true;
+    });
+    return pumpEventQueue().then((_) {
+      expect(completed, isFalse);
+      _performPendingAnalysisTasks();
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(completed, isTrue);
+    });
+  }
+
+  Future test_computeResolvedCompilationUnitAsync_afterDispose() {
+    _context = AnalysisContextFactory.contextWithCore();
+    _sourceFactory = _context.sourceFactory;
+    Source source = _addSource("/lib.dart", "library lib;");
+    // Complete all pending analysis tasks and flush the AST so that it won't
+    // be available immediately.
+    _performPendingAnalysisTasks();
+    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
+    dartEntry.flushAstStructures();
+    // Dispose of the context.
+    _context.dispose();
+    // Any attempt to start an asynchronous computation should return a future
+    // which completes with error.
+    CancelableFuture<CompilationUnit> future =
+        _context.computeResolvedCompilationUnitAsync(source, source);
+    bool completed = false;
+    future.then((CompilationUnit unit) {
+      fail('Future should have completed with error');
+    }, onError: (error) {
+      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
+      completed = true;
+    });
+    return pumpEventQueue().then((_) {
+      expect(completed, isTrue);
+    });
+  }
+
+  Future test_computeResolvedCompilationUnitAsync_cancel() {
+    _context = AnalysisContextFactory.contextWithCore();
+    _sourceFactory = _context.sourceFactory;
+    Source source = _addSource("/lib.dart", "library lib;");
+    // Complete all pending analysis tasks and flush the AST so that it won't
+    // be available immediately.
+    _performPendingAnalysisTasks();
+    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
+    dartEntry.flushAstStructures();
+    CancelableFuture<CompilationUnit> future =
+        _context.computeResolvedCompilationUnitAsync(source, source);
+    bool completed = false;
+    future.then((CompilationUnit unit) {
+      fail('Future should have been canceled');
+    }, onError: (error) {
+      expect(error, new isInstanceOf<FutureCanceledError>());
+      completed = true;
+    });
+    expect(completed, isFalse);
+    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
+    future.cancel();
+    expect(_context.pendingFutureSources_forTesting, isEmpty);
+    return pumpEventQueue().then((_) {
+      expect(completed, isTrue);
+      expect(_context.pendingFutureSources_forTesting, isEmpty);
+    });
+  }
+
+  Future test_computeResolvedCompilationUnitAsync_dispose() {
+    _context = AnalysisContextFactory.contextWithCore();
+    _sourceFactory = _context.sourceFactory;
+    Source source = _addSource("/lib.dart", "library lib;");
+    // Complete all pending analysis tasks and flush the AST so that it won't
+    // be available immediately.
+    _performPendingAnalysisTasks();
+    DartEntry dartEntry = _context.getReadableSourceEntryOrNull(source);
+    dartEntry.flushAstStructures();
+    CancelableFuture<CompilationUnit> future =
+        _context.computeResolvedCompilationUnitAsync(source, source);
+    bool completed = false;
+    future.then((CompilationUnit unit) {
+      fail('Future should have completed with error');
+    }, onError: (error) {
+      expect(error, new isInstanceOf<AnalysisNotScheduledError>());
+      completed = true;
+    });
+    expect(completed, isFalse);
+    expect(_context.pendingFutureSources_forTesting, isNotEmpty);
+    // Disposing of the context should cause all pending futures to complete
+    // with AnalysisNotScheduled, so that no clients are left hanging.
+    _context.dispose();
+    expect(_context.pendingFutureSources_forTesting, isEmpty);
+    return pumpEventQueue().then((_) {
+      expect(completed, isTrue);
+      expect(_context.pendingFutureSources_forTesting, isEmpty);
+    });
+  }
+
+  Future test_computeResolvedCompilationUnitAsync_unrelatedLibrary() {
+    _context = AnalysisContextFactory.contextWithCore();
+    _sourceFactory = _context.sourceFactory;
+    Source librarySource = _addSource("/lib.dart", "library lib;");
+    Source partSource = _addSource("/part.dart", "part of foo;");
+    bool completed = false;
+    _context.computeResolvedCompilationUnitAsync(
+        partSource,
+        librarySource).then((_) {
+      fail('Expected resolution to fail');
+    }, onError: (e) {
+      expect(e, new isInstanceOf<AnalysisNotScheduledError>());
+      completed = true;
+    });
+    return pumpEventQueue().then((_) {
+      expect(completed, isFalse);
+      _performPendingAnalysisTasks();
+    }).then((_) => pumpEventQueue()).then((_) {
+      expect(completed, isTrue);
+    });
+  }
+
   void test_dispose() {
     expect(_context.isDisposed, isFalse);
     _context.dispose();
@@ -2052,6 +2183,14 @@
     return context2.test_priorityOrder;
   }
 
+  void _performPendingAnalysisTasks([int maxTasks = 20]) {
+    for (int i = 0; _context.performAnalysisTask().hasMoreWork; i++) {
+      if (i > maxTasks) {
+        fail('Analysis did not terminate.');
+      }
+    }
+  }
+
   void _removeSource(Source source) {
     ChangeSet changeSet = new ChangeSet();
     changeSet.removedSource(source);
@@ -3893,6 +4032,7 @@
   }
 }
 
+
 @ReflectiveTestCase()
 class GenerateDartHintsTaskTest extends EngineTestCase {
   void test_accept() {
@@ -3955,7 +4095,6 @@
   bool visitGenerateDartHintsTask(GenerateDartHintsTask task) => true;
 }
 
-
 class GenerateDartHintsTaskTestTV_perform extends TestTaskVisitor<bool> {
   Source librarySource;
   Source partSource;
@@ -4828,7 +4967,6 @@
 }
 
 
-
 @ReflectiveTestCase()
 class IncrementalAnalysisTaskTest extends EngineTestCase {
   void test_accept() {
@@ -4894,6 +5032,7 @@
 }
 
 
+
 class IncrementalAnalysisTaskTestTV_assertTask extends
     TestTaskVisitor<CompilationUnit> {
   IncrementalAnalysisTask task;
@@ -4906,517 +5045,6 @@
 
 
 @ReflectiveTestCase()
-class InstrumentedAnalysisContextImplTest extends EngineTestCase {
-  void test_addSourceInfo() {
-    TestAnalysisContext_test_addSourceInfo innerContext =
-        new TestAnalysisContext_test_addSourceInfo();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.addSourceInfo(null, null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_applyChanges() {
-    TestAnalysisContext_test_applyChanges innerContext =
-        new TestAnalysisContext_test_applyChanges();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.applyChanges(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeDocumentationComment() {
-    TestAnalysisContext_test_computeDocumentationComment innerContext =
-        new TestAnalysisContext_test_computeDocumentationComment();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeDocumentationComment(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeErrors() {
-    TestAnalysisContext_test_computeErrors innerContext =
-        new TestAnalysisContext_test_computeErrors();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeErrors(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeExportedLibraries() {
-    TestAnalysisContext_test_computeExportedLibraries innerContext =
-        new TestAnalysisContext_test_computeExportedLibraries();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeExportedLibraries(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeHtmlElement() {
-    TestAnalysisContext_test_computeHtmlElement innerContext =
-        new TestAnalysisContext_test_computeHtmlElement();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeHtmlElement(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeImportedLibraries() {
-    TestAnalysisContext_test_computeImportedLibraries innerContext =
-        new TestAnalysisContext_test_computeImportedLibraries();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeImportedLibraries(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeKindOf() {
-    TestAnalysisContext_test_computeKindOf innerContext =
-        new TestAnalysisContext_test_computeKindOf();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeKindOf(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeLibraryElement() {
-    TestAnalysisContext_test_computeLibraryElement innerContext =
-        new TestAnalysisContext_test_computeLibraryElement();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeLibraryElement(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeLineInfo() {
-    TestAnalysisContext_test_computeLineInfo innerContext =
-        new TestAnalysisContext_test_computeLineInfo();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeLineInfo(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_computeResolvableCompilationUnit() {
-    TestAnalysisContext_test_computeResolvableCompilationUnit innerContext =
-        new TestAnalysisContext_test_computeResolvableCompilationUnit();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.computeResolvableCompilationUnit(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_creation() {
-    expect(new InstrumentedAnalysisContextImpl(), isNotNull);
-  }
-
-  void test_dispose() {
-    TestAnalysisContext_test_dispose innerContext =
-        new TestAnalysisContext_test_dispose();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.dispose();
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_exists() {
-    TestAnalysisContext_test_exists innerContext =
-        new TestAnalysisContext_test_exists();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.exists(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getAnalysisOptions() {
-    TestAnalysisContext_test_getAnalysisOptions innerContext =
-        new TestAnalysisContext_test_getAnalysisOptions();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.analysisOptions;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getAngularApplicationWithHtml() {
-    TestAnalysisContext_test_getAngularApplicationWithHtml innerContext =
-        new TestAnalysisContext_test_getAngularApplicationWithHtml();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getAngularApplicationWithHtml(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getCompilationUnitElement() {
-    TestAnalysisContext_test_getCompilationUnitElement innerContext =
-        new TestAnalysisContext_test_getCompilationUnitElement();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getCompilationUnitElement(null, null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getContents() {
-    TestAnalysisContext_test_getContents innerContext =
-        new TestAnalysisContext_test_getContents();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getContents(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-//  void test_getContentsToReceiver() {
-//    TestAnalysisContext_test_getContentsToReceiver innerContext = new TestAnalysisContext_test_getContentsToReceiver();
-//    InstrumentedAnalysisContextImpl context
-//        = new InstrumentedAnalysisContextImpl.con1(innerContext);
-//    context.getContentsToReceiver(null, null);
-//    expect(innerContext.invoked, isTrue);
-//  }
-
-  void test_getElement() {
-    TestAnalysisContext_test_getElement innerContext =
-        new TestAnalysisContext_test_getElement();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getElement(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getErrors() {
-    TestAnalysisContext_test_getErrors innerContext =
-        new TestAnalysisContext_test_getErrors();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getErrors(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getHtmlElement() {
-    TestAnalysisContext_test_getHtmlElement innerContext =
-        new TestAnalysisContext_test_getHtmlElement();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getHtmlElement(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getHtmlFilesReferencing() {
-    TestAnalysisContext_test_getHtmlFilesReferencing innerContext =
-        new TestAnalysisContext_test_getHtmlFilesReferencing();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getHtmlFilesReferencing(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getHtmlSources() {
-    TestAnalysisContext_test_getHtmlSources innerContext =
-        new TestAnalysisContext_test_getHtmlSources();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.htmlSources;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getKindOf() {
-    TestAnalysisContext_test_getKindOf innerContext =
-        new TestAnalysisContext_test_getKindOf();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getKindOf(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLaunchableClientLibrarySources() {
-    TestAnalysisContext_test_getLaunchableClientLibrarySources innerContext =
-        new TestAnalysisContext_test_getLaunchableClientLibrarySources();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.launchableClientLibrarySources;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLaunchableServerLibrarySources() {
-    TestAnalysisContext_test_getLaunchableServerLibrarySources innerContext =
-        new TestAnalysisContext_test_getLaunchableServerLibrarySources();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.launchableServerLibrarySources;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLibrariesContaining() {
-    TestAnalysisContext_test_getLibrariesContaining innerContext =
-        new TestAnalysisContext_test_getLibrariesContaining();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getLibrariesContaining(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLibrariesDependingOn() {
-    TestAnalysisContext_test_getLibrariesDependingOn innerContext =
-        new TestAnalysisContext_test_getLibrariesDependingOn();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getLibrariesDependingOn(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLibrariesReferencedFromHtml() {
-    TestAnalysisContext_test_getLibrariesReferencedFromHtml innerContext =
-        new TestAnalysisContext_test_getLibrariesReferencedFromHtml();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getLibrariesReferencedFromHtml(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLibraryElement() {
-    TestAnalysisContext_test_getLibraryElement innerContext =
-        new TestAnalysisContext_test_getLibraryElement();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getLibraryElement(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLibrarySources() {
-    TestAnalysisContext_test_getLibrarySources innerContext =
-        new TestAnalysisContext_test_getLibrarySources();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.librarySources;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getLineInfo() {
-    TestAnalysisContext_test_getLineInfo innerContext =
-        new TestAnalysisContext_test_getLineInfo();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getLineInfo(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getModificationStamp() {
-    TestAnalysisContext_test_getModificationStamp innerContext =
-        new TestAnalysisContext_test_getModificationStamp();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getModificationStamp(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getPublicNamespace() {
-    TestAnalysisContext_test_getPublicNamespace innerContext =
-        new TestAnalysisContext_test_getPublicNamespace();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getPublicNamespace(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getRefactoringUnsafeSources() {
-    TestAnalysisContext_test_getRefactoringUnsafeSources innerContext =
-        new TestAnalysisContext_test_getRefactoringUnsafeSources();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.refactoringUnsafeSources;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getResolvedCompilationUnit_element() {
-    TestAnalysisContext_test_getResolvedCompilationUnit_element innerContext =
-        new TestAnalysisContext_test_getResolvedCompilationUnit_element();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getResolvedCompilationUnit(null, null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getResolvedCompilationUnit_source() {
-    TestAnalysisContext_test_getResolvedCompilationUnit_source innerContext =
-        new TestAnalysisContext_test_getResolvedCompilationUnit_source();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getResolvedCompilationUnit2(null, null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getResolvedHtmlUnit() {
-    TestAnalysisContext_test_getResolvedHtmlUnit innerContext =
-        new TestAnalysisContext_test_getResolvedHtmlUnit();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.getResolvedHtmlUnit(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getSourceFactory() {
-    TestAnalysisContext_test_getSourceFactory innerContext =
-        new TestAnalysisContext_test_getSourceFactory();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.sourceFactory;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getStatistics() {
-    TestAnalysisContext_test_getStatistics innerContext =
-        new TestAnalysisContext_test_getStatistics();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.statistics;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_getTypeProvider() {
-    TestAnalysisContext_test_getTypeProvider innerContext =
-        new TestAnalysisContext_test_getTypeProvider();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.typeProvider;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_isClientLibrary() {
-    TestAnalysisContext_test_isClientLibrary innerContext =
-        new TestAnalysisContext_test_isClientLibrary();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.isClientLibrary(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_isDisposed() {
-    TestAnalysisContext_test_isDisposed innerContext =
-        new TestAnalysisContext_test_isDisposed();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.isDisposed;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_isServerLibrary() {
-    TestAnalysisContext_test_isServerLibrary innerContext =
-        new TestAnalysisContext_test_isServerLibrary();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.isServerLibrary(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_parseCompilationUnit() {
-    TestAnalysisContext_test_parseCompilationUnit innerContext =
-        new TestAnalysisContext_test_parseCompilationUnit();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.parseCompilationUnit(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_parseHtmlUnit() {
-    TestAnalysisContext_test_parseHtmlUnit innerContext =
-        new TestAnalysisContext_test_parseHtmlUnit();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.parseHtmlUnit(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_performAnalysisTask() {
-    TestAnalysisContext_test_performAnalysisTask innerContext =
-        new TestAnalysisContext_test_performAnalysisTask();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.performAnalysisTask();
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_recordLibraryElements() {
-    TestAnalysisContext_test_recordLibraryElements innerContext =
-        new TestAnalysisContext_test_recordLibraryElements();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.recordLibraryElements(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_resolveCompilationUnit() {
-    TestAnalysisContext_test_resolveCompilationUnit innerContext =
-        new TestAnalysisContext_test_resolveCompilationUnit();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.resolveCompilationUnit2(null, null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_resolveCompilationUnit_element() {
-    TestAnalysisContext_test_resolveCompilationUnit_element innerContext =
-        new TestAnalysisContext_test_resolveCompilationUnit_element();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.resolveCompilationUnit(null, null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_resolveHtmlUnit() {
-    TestAnalysisContext_test_resolveHtmlUnit innerContext =
-        new TestAnalysisContext_test_resolveHtmlUnit();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.resolveHtmlUnit(null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_setAnalysisOptions() {
-    TestAnalysisContext_test_setAnalysisOptions innerContext =
-        new TestAnalysisContext_test_setAnalysisOptions();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.analysisOptions = null;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_setAnalysisPriorityOrder() {
-    TestAnalysisContext_test_setAnalysisPriorityOrder innerContext =
-        new TestAnalysisContext_test_setAnalysisPriorityOrder();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.analysisPriorityOrder = null;
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_setChangedContents() {
-    TestAnalysisContext_test_setChangedContents innerContext =
-        new TestAnalysisContext_test_setChangedContents();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.setChangedContents(null, null, 0, 0, 0);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_setContents() {
-    TestAnalysisContext_test_setContents innerContext =
-        new TestAnalysisContext_test_setContents();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.setContents(null, null);
-    expect(innerContext.invoked, isTrue);
-  }
-
-  void test_setSourceFactory() {
-    TestAnalysisContext_test_setSourceFactory innerContext =
-        new TestAnalysisContext_test_setSourceFactory();
-    InstrumentedAnalysisContextImpl context =
-        new InstrumentedAnalysisContextImpl.con1(innerContext);
-    context.sourceFactory = null;
-    expect(innerContext.invoked, isTrue);
-  }
-}
-
-
-@ReflectiveTestCase()
 class ParseDartTaskTest extends EngineTestCase {
   void test_accept() {
     ParseDartTask task = new ParseDartTask(null, null, null, null);
@@ -6445,6 +6073,12 @@
     return null;
   }
   @override
+  Future<CompilationUnit> computeResolvedCompilationUnitAsync(Source source,
+      Source librarySource) {
+    fail("Unexpected invocation of getResolvedCompilationUnitFuture");
+    return null;
+  }
+  @override
   void dispose() {
     fail("Unexpected invocation of dispose");
   }
@@ -6610,6 +6244,7 @@
   void setContents(Source source, String contents) {
     fail("Unexpected invocation of setContents");
   }
+
   @override
   void visitCacheItems(void callback(Source source, SourceEntry dartEntry,
       DataDescriptor rowDesc, CacheState state)) {
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index fe62b17..89b1411 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -1939,6 +1939,15 @@
     _resolve(_editString('+', '*'), _isFunctionBody);
   }
 
+  void test_constructor_fieldFormalParameter() {
+    _resolveUnit(r'''
+class A {
+  int xy;
+  A(this.x);
+}''');
+    _resolve(_editString('this.x', 'this.xy'), _isDeclaration);
+  }
+
   void test_constructor_fieldInitializer_add() {
     _resolveUnit(r'''
 class A {
@@ -2147,6 +2156,14 @@
     _resolve(_editString('int res = a * b;', ''), _isBlock);
   }
 
+  void test_topLevelFunction_parameter_inFunctionTyped_rename() {
+    _resolveUnit(r'''
+test(f(int a, int b)) {
+}
+''');
+    _resolve(_editString('test(f(int a', 'test(f2(int a2'), _isDeclaration);
+  }
+
   void test_topLevelFunction_parameter_rename() {
     _resolveUnit(r'''
 int main(int a, int b) {
@@ -4036,6 +4053,8 @@
 
   void _verifyElement(Element a, Element b) {
     if (a != b) {
+      print(a.location);
+      print(b.location);
       fail('Expected: $b\n  Actual: $a');
     }
     if (a == null && b == null) {
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 01f5197..d311cc7 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -7041,6 +7041,19 @@
     verify([source]);
   }
 
+  void test_unnecessaryCast_conditionalExpression() {
+    Source source = addSource(r'''
+abstract class I {}
+class A implements I {}
+class B implements I {}
+I m(A a, B b) {
+  return a == null ? b as I : a as I;
+}''');
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_unnecessaryCast_dynamic_type() {
     Source source = addSource(r'''
 m(v) {
@@ -8659,6 +8672,21 @@
     verify([source]);
   }
 
+  void test_enum_externalLibrary() {
+    resetWithEnum();
+    addNamedSource("/my_lib.dart", r'''
+library my_lib;
+enum EEE {A, B, C}''');
+    Source source = addSource(r'''
+import 'my_lib.dart';
+main() {
+  EEE e = null;
+}''');
+    resolve(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_extractedMethodAsConstant() {
     Source source = addSource(r'''
 abstract class Comparable<T> {
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index 5aa9922..b8f60d4 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -14,12 +14,14 @@
 import 'parse_compilation_unit_test.dart' as parse_compilation_unit;
 import 'source/test_all.dart' as source;
 import 'task/test_all.dart' as task;
+import 'cancelable_future_test.dart' as cancelable_future_test;
 
 
 /// Utility for manually running all tests.
 main() {
   groupSep = ' | ';
   group('analysis engine', () {
+    cancelable_future_test.main();
     enum_test.main();
     error.main();
     file_system.main();
diff --git a/pkg/analyzer2dart/test/sexpr_data.dart b/pkg/analyzer2dart/test/sexpr_data.dart
index d6117c1..a34c5a2 100644
--- a/pkg/analyzer2dart/test/sexpr_data.dart
+++ b/pkg/analyzer2dart/test/sexpr_data.dart
@@ -23,8 +23,8 @@
     const TestSpec('''
 main() {}
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Null)))
   (InvokeContinuation return v0))
 '''),
 
@@ -34,9 +34,9 @@
   foo();
 }
 ''', '''
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetCont (k0 v0)
-    (LetPrim v1 (Constant NullConstant))
+    (LetPrim v1 (Constant (Null)))
     (InvokeContinuation return v1))
   (InvokeStatic foo  k0))
 ''')
@@ -48,8 +48,8 @@
   return 0;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (InvokeContinuation return v0))
 '''),
 
@@ -58,8 +58,8 @@
   return 1.5;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant DoubleConstant(1.5)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Double 1.5)))
   (InvokeContinuation return v0))
 '''),
 
@@ -68,8 +68,8 @@
   return true;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant BoolConstant(true)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Bool true)))
   (InvokeContinuation return v0))
 '''),
 
@@ -78,8 +78,8 @@
   return false;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant BoolConstant(false)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Bool false)))
   (InvokeContinuation return v0))
 '''),
 
@@ -88,8 +88,8 @@
   return "a";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant StringConstant("a")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (String "a")))
   (InvokeContinuation return v0))
 '''),
   ]),
@@ -98,16 +98,16 @@
     const TestSpec('''
 main(args) {}
 ''', '''
-(FunctionDefinition main (args return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main (args) return ()
+  (LetPrim v0 (Constant (Null)))
   (InvokeContinuation return v0))
 '''),
 
     const TestSpec('''
 main(a, b) {}
 ''', '''
-(FunctionDefinition main (a b return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main (a b) return ()
+  (LetPrim v0 (Constant (Null)))
   (InvokeContinuation return v0))
 '''),
   ]),
@@ -119,10 +119,10 @@
   foo(null);
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Null)))
   (LetCont (k0 v1)
-    (LetPrim v2 (Constant NullConstant))
+    (LetPrim v2 (Constant (Null)))
     (InvokeContinuation return v2))
   (InvokeStatic foo v0 k0))
 '''),
@@ -135,13 +135,13 @@
   bar(0, "");
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Null)))
   (LetCont (k0 v1)
-    (LetPrim v2 (Constant IntConstant(0)))
-    (LetPrim v3 (Constant StringConstant("")))
+    (LetPrim v2 (Constant (Int 0)))
+    (LetPrim v3 (Constant (String "")))
     (LetCont (k1 v4)
-      (LetPrim v5 (Constant NullConstant))
+      (LetPrim v5 (Constant (Null)))
       (InvokeContinuation return v5))
     (InvokeStatic bar v2 v3 k1))
   (InvokeStatic foo v0 k0))
@@ -153,8 +153,8 @@
   return foo(null);
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Null)))
   (LetCont (k0 v1)
     (InvokeContinuation return v1))
   (InvokeStatic foo v0 k0))
@@ -168,8 +168,8 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Null)))
   (InvokeContinuation return v0))
 '''),
 
@@ -179,8 +179,8 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (InvokeContinuation return v0))
 '''),
 
@@ -189,7 +189,7 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (InvokeContinuation return a))
 '''),
     ]),
@@ -202,9 +202,9 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant NullConstant))
-  (LetPrim v1 (Constant IntConstant(10)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Null)))
+  (LetPrim v1 (Constant (Int 10)))
   (InvokeContinuation return v1))
 '''),
 
@@ -215,9 +215,9 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant IntConstant(10)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (Int 10)))
   (InvokeContinuation return v1))
 '''),
 
@@ -230,10 +230,10 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
-    (LetPrim v2 (Constant StringConstant("")))
+    (LetPrim v2 (Constant (String "")))
     (LetCont (k1 v3)
       (InvokeContinuation return v2))
     (InvokeStatic print v2 k1))
@@ -248,9 +248,9 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
-    (LetPrim v1 (Constant StringConstant("")))
+    (LetPrim v1 (Constant (String "")))
     (LetCont (k1 v2)
       (InvokeContinuation return v1))
     (InvokeStatic print v1 k1))
@@ -266,13 +266,13 @@
   return a;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (LetCont (k1 v1)
       (InvokeContinuation return v0))
     (InvokeStatic print v0 k1))
   (LetCont (k2)
-    (LetPrim v2 (Constant StringConstant("")))
+    (LetPrim v2 (Constant (String "")))
     (InvokeContinuation k0 v2))
   (LetCont (k3)
     (InvokeContinuation k0 a))
@@ -286,7 +286,7 @@
   return a.foo;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (InvokeMethod a foo  k0))
@@ -298,8 +298,8 @@
   return a.foo;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (String "")))
   (LetCont (k0 v1)
     (InvokeContinuation return v1))
   (InvokeMethod v0 foo  k0))
@@ -312,8 +312,8 @@
   return a.foo(0);
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
     (InvokeContinuation return v1))
   (InvokeMethod a foo v0 k0))
@@ -325,10 +325,10 @@
   return a.foo(0, 1);
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant StringConstant("")))
-  (LetPrim v1 (Constant IntConstant(0)))
-  (LetPrim v2 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (String "")))
+  (LetPrim v1 (Constant (Int 0)))
+  (LetPrim v2 (Constant (Int 1)))
   (LetCont (k0 v3)
     (InvokeContinuation return v3))
   (InvokeMethod v0 foo v1 v2 k0))
@@ -341,9 +341,9 @@
   return 0 + "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 + v1 k0))
@@ -354,9 +354,9 @@
   return 0 - "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 - v1 k0))
@@ -367,9 +367,9 @@
   return 0 * "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 * v1 k0))
@@ -380,9 +380,9 @@
   return 0 / "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 / v1 k0))
@@ -393,9 +393,9 @@
   return 0 ~/ "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 ~/ v1 k0))
@@ -406,9 +406,9 @@
   return 0 < "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 < v1 k0))
@@ -419,9 +419,9 @@
   return 0 <= "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 <= v1 k0))
@@ -432,9 +432,9 @@
   return 0 > "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 > v1 k0))
@@ -445,9 +445,9 @@
   return 0 >= "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 >= v1 k0))
@@ -458,9 +458,9 @@
   return 0 << "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 << v1 k0))
@@ -471,9 +471,9 @@
   return 0 >> "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 >> v1 k0))
@@ -484,9 +484,9 @@
   return 0 & "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 & v1 k0))
@@ -497,9 +497,9 @@
   return 0 | "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 | v1 k0))
@@ -510,9 +510,9 @@
   return 0 ^ "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 ^ v1 k0))
@@ -523,9 +523,9 @@
   return 0 == "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
   (InvokeMethod v0 == v1 k0))
@@ -536,17 +536,17 @@
   return 0 != "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
     (LetCont (k1 v3)
       (InvokeContinuation return v3))
     (LetCont (k2)
-      (LetPrim v4 (Constant BoolConstant(false)))
+      (LetPrim v4 (Constant (Bool false)))
       (InvokeContinuation k1 v4))
     (LetCont (k3)
-      (LetPrim v5 (Constant BoolConstant(true)))
+      (LetPrim v5 (Constant (Bool true)))
       (InvokeContinuation k1 v5))
     (Branch (IsTrue v2) k2 k3))
   (InvokeMethod v0 == v1 k0))
@@ -557,21 +557,21 @@
   return 0 && "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
     (InvokeContinuation return v1))
   (LetCont (k1)
-    (LetPrim v2 (Constant StringConstant("")))
+    (LetPrim v2 (Constant (String "")))
     (LetCont (k2)
-      (LetPrim v3 (Constant BoolConstant(true)))
+      (LetPrim v3 (Constant (Bool true)))
       (InvokeContinuation k0 v3))
     (LetCont (k3)
-      (LetPrim v4 (Constant BoolConstant(false)))
+      (LetPrim v4 (Constant (Bool false)))
       (InvokeContinuation k0 v4))
     (Branch (IsTrue v2) k2 k3))
   (LetCont (k4)
-    (LetPrim v5 (Constant BoolConstant(false)))
+    (LetPrim v5 (Constant (Bool false)))
     (InvokeContinuation k0 v5))
   (Branch (IsTrue v0) k1 k4))
 '''),
@@ -581,20 +581,20 @@
   return 0 || "";
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
     (InvokeContinuation return v1))
   (LetCont (k1)
-    (LetPrim v2 (Constant BoolConstant(true)))
+    (LetPrim v2 (Constant (Bool true)))
     (InvokeContinuation k0 v2))
   (LetCont (k2)
-    (LetPrim v3 (Constant StringConstant("")))
+    (LetPrim v3 (Constant (String "")))
     (LetCont (k3)
-      (LetPrim v4 (Constant BoolConstant(true)))
+      (LetPrim v4 (Constant (Bool true)))
       (InvokeContinuation k0 v4))
     (LetCont (k4)
-      (LetPrim v5 (Constant BoolConstant(false)))
+      (LetPrim v5 (Constant (Bool false)))
       (InvokeContinuation k0 v5))
     (Branch (IsTrue v3) k3 k4))
   (Branch (IsTrue v0) k1 k2))
@@ -605,10 +605,10 @@
   return 0 + "" * 2;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
-  (LetPrim v2 (Constant IntConstant(2)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
+  (LetPrim v2 (Constant (Int 2)))
   (LetCont (k0 v3)
     (LetCont (k1 v4)
       (InvokeContinuation return v4))
@@ -621,11 +621,11 @@
   return 0 * "" + 2;
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "")))
   (LetCont (k0 v2)
-    (LetPrim v3 (Constant IntConstant(2)))
+    (LetPrim v3 (Constant (Int 2)))
     (LetCont (k1 v4)
       (InvokeContinuation return v4))
     (InvokeMethod v2 + v3 k1))
@@ -641,12 +641,12 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0)
-    (LetPrim v0 (Constant NullConstant))
+    (LetPrim v0 (Constant (Null)))
     (InvokeContinuation return v0))
   (LetCont (k1)
-    (LetPrim v1 (Constant IntConstant(0)))
+    (LetPrim v1 (Constant (Int 0)))
     (LetCont (k2 v2)
       (InvokeContinuation k0 ))
     (InvokeStatic print v1 k2))
@@ -664,17 +664,17 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0)
-    (LetPrim v0 (Constant NullConstant))
+    (LetPrim v0 (Constant (Null)))
     (InvokeContinuation return v0))
   (LetCont (k1)
-    (LetPrim v1 (Constant IntConstant(0)))
+    (LetPrim v1 (Constant (Int 0)))
     (LetCont (k2 v2)
       (InvokeContinuation k0 ))
     (InvokeStatic print v1 k2))
   (LetCont (k3)
-    (LetPrim v3 (Constant IntConstant(1)))
+    (LetPrim v3 (Constant (Int 1)))
     (LetCont (k4 v4)
       (InvokeContinuation k0 ))
     (InvokeStatic print v3 k4))
@@ -691,19 +691,19 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0)
-    (LetPrim v0 (Constant NullConstant))
+    (LetPrim v0 (Constant (Null)))
     (InvokeContinuation return v0))
   (LetCont (k1)
-    (LetPrim v1 (Constant IntConstant(0)))
+    (LetPrim v1 (Constant (Int 0)))
     (LetCont (k2 v2)
       (InvokeContinuation k0 ))
     (InvokeStatic print v1 k2))
   (LetCont (k3)
-    (LetPrim v3 (Constant IntConstant(1)))
+    (LetPrim v3 (Constant (Int 1)))
     (LetCont (k4 v4)
-      (LetPrim v5 (Constant IntConstant(2)))
+      (LetPrim v5 (Constant (Int 2)))
       (LetCont (k5 v6)
         (InvokeContinuation k0 ))
       (InvokeStatic print v5 k5))
@@ -718,16 +718,16 @@
   return a ? print(0) : print(1);
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (LetCont (k1)
-    (LetPrim v1 (Constant IntConstant(0)))
+    (LetPrim v1 (Constant (Int 0)))
     (LetCont (k2 v2)
       (InvokeContinuation k0 v2))
     (InvokeStatic print v1 k2))
   (LetCont (k3)
-    (LetPrim v3 (Constant IntConstant(1)))
+    (LetPrim v3 (Constant (Int 1)))
     (LetCont (k4 v4)
       (InvokeContinuation k0 v4))
     (InvokeStatic print v3 k4))
@@ -744,8 +744,8 @@
   return 1;
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (Int 0)))
   (InvokeContinuation return v0))
 '''),
 
@@ -760,12 +760,12 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0)
-    (LetPrim v0 (Constant IntConstant(0)))
+    (LetPrim v0 (Constant (Int 0)))
     (InvokeContinuation return v0))
   (LetCont (k1)
-    (LetPrim v1 (Constant IntConstant(2)))
+    (LetPrim v1 (Constant (Int 2)))
     (InvokeContinuation return v1))
   (Branch (IsTrue a) k0 k1))
 '''),
@@ -783,17 +783,17 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0)
-    (LetPrim v0 (Constant IntConstant(0)))
+    (LetPrim v0 (Constant (Int 0)))
     (LetCont (k1 v1)
-      (LetPrim v2 (Constant IntConstant(0)))
+      (LetPrim v2 (Constant (Int 0)))
       (InvokeContinuation return v2))
     (InvokeStatic print v0 k1))
   (LetCont (k2)
-    (LetPrim v3 (Constant IntConstant(2)))
+    (LetPrim v3 (Constant (Int 2)))
     (LetCont (k3 v4)
-      (LetPrim v5 (Constant IntConstant(2)))
+      (LetPrim v5 (Constant (Int 2)))
       (InvokeContinuation return v5))
     (InvokeStatic print v3 k3))
   (Branch (IsTrue a) k0 k2))
@@ -806,9 +806,9 @@
   new Object();
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
-    (LetPrim v1 (Constant NullConstant))
+    (LetPrim v1 (Constant (Null)))
     (InvokeContinuation return v1))
   (InvokeConstructor Object  k0))
 '''),
@@ -818,10 +818,10 @@
   new Deprecated("");
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant StringConstant("")))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (String "")))
   (LetCont (k0 v1)
-    (LetPrim v2 (Constant NullConstant))
+    (LetPrim v2 (Constant (Null)))
     (InvokeContinuation return v2))
   (InvokeConstructor Deprecated v0 k0))
 '''),
@@ -833,7 +833,7 @@
   return [];
 }
 ''', '''
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetPrim v0 (LiteralList ()))
   (InvokeContinuation return v0))
 '''),
@@ -843,8 +843,8 @@
   return [0];
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetPrim v1 (LiteralList (v0)))
   (InvokeContinuation return v1))
 '''),
@@ -854,9 +854,9 @@
   return [0, 1, a];
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant IntConstant(1)))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (Int 1)))
   (LetPrim v2 (LiteralList (v0 v1 a)))
   (InvokeContinuation return v2))
 '''),
@@ -866,11 +866,11 @@
   return [0, [1], [a, [3]]];
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant IntConstant(1)))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (Int 1)))
   (LetPrim v2 (LiteralList (v1)))
-  (LetPrim v3 (Constant IntConstant(3)))
+  (LetPrim v3 (Constant (Int 3)))
   (LetPrim v4 (LiteralList (v3)))
   (LetPrim v5 (LiteralList (a v4)))
   (LetPrim v6 (LiteralList (v0 v2 v5)))
@@ -884,7 +884,7 @@
   return {};
 }
 ''', '''
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetPrim v0 (LiteralMap () ()))
   (InvokeContinuation return v0))
 '''),
@@ -894,9 +894,9 @@
   return {"a": 0};
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant StringConstant("a")))
-  (LetPrim v1 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (String "a")))
+  (LetPrim v1 (Constant (Int 0)))
   (LetPrim v2 (LiteralMap (v0) (v1)))
   (InvokeContinuation return v2))
 '''),
@@ -906,12 +906,12 @@
   return {"a": 0, "b": 1, "c": a};
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant StringConstant("a")))
-  (LetPrim v1 (Constant IntConstant(0)))
-  (LetPrim v2 (Constant StringConstant("b")))
-  (LetPrim v3 (Constant IntConstant(1)))
-  (LetPrim v4 (Constant StringConstant("c")))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (String "a")))
+  (LetPrim v1 (Constant (Int 0)))
+  (LetPrim v2 (Constant (String "b")))
+  (LetPrim v3 (Constant (Int 1)))
+  (LetPrim v4 (Constant (String "c")))
   (LetPrim v5 (LiteralMap (v0 v2 v4) (v1 v3 a)))
   (InvokeContinuation return v5))
 '''),
@@ -921,15 +921,15 @@
   return {0: "a", 1: {2: "b"}, a: {3: "c"}};
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v1 (Constant StringConstant("a")))
-  (LetPrim v2 (Constant IntConstant(1)))
-  (LetPrim v3 (Constant IntConstant(2)))
-  (LetPrim v4 (Constant StringConstant("b")))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v1 (Constant (String "a")))
+  (LetPrim v2 (Constant (Int 1)))
+  (LetPrim v3 (Constant (Int 2)))
+  (LetPrim v4 (Constant (String "b")))
   (LetPrim v5 (LiteralMap (v3) (v4)))
-  (LetPrim v6 (Constant IntConstant(3)))
-  (LetPrim v7 (Constant StringConstant("c")))
+  (LetPrim v6 (Constant (Int 3)))
+  (LetPrim v7 (Constant (String "c")))
   (LetPrim v8 (LiteralMap (v6) (v7)))
   (LetPrim v9 (LiteralMap (v0 v2 a) (v1 v5 v8)))
   (InvokeContinuation return v9))
@@ -942,11 +942,11 @@
   for (;;) {}
 }
 ''', '''
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetCont* (k0)
-    (LetPrim v0 (Constant BoolConstant(true)))
+    (LetPrim v0 (Constant (Bool true)))
     (LetCont (k1)
-      (LetPrim v1 (Constant NullConstant))
+      (LetPrim v1 (Constant (Null)))
       (InvokeContinuation return v1))
     (LetCont (k2)
       (InvokeContinuation* k0 ))
@@ -961,17 +961,17 @@
   }
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont* (k0 v1)
-    (LetPrim v2 (Constant IntConstant(10)))
+    (LetPrim v2 (Constant (Int 10)))
     (LetCont (k1 v3)
       (LetCont (k2)
-        (LetPrim v4 (Constant NullConstant))
+        (LetPrim v4 (Constant (Null)))
         (InvokeContinuation return v4))
       (LetCont (k3)
         (LetCont (k4 v5)
-          (LetPrim v6 (Constant IntConstant(1)))
+          (LetPrim v6 (Constant (Int 1)))
           (LetCont (k5 v7)
             (InvokeContinuation* k0 v7))
           (InvokeMethod v1 + v6 k5))
@@ -988,17 +988,17 @@
   }
 }
 ''', '''
-(FunctionDefinition main (i return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main (i) return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont* (k0 v1)
-    (LetPrim v2 (Constant IntConstant(10)))
+    (LetPrim v2 (Constant (Int 10)))
     (LetCont (k1 v3)
       (LetCont (k2)
-        (LetPrim v4 (Constant NullConstant))
+        (LetPrim v4 (Constant (Null)))
         (InvokeContinuation return v4))
       (LetCont (k3)
         (LetCont (k4 v5)
-          (LetPrim v6 (Constant IntConstant(1)))
+          (LetPrim v6 (Constant (Int 1)))
           (LetCont (k5 v7)
             (InvokeContinuation* k0 v7))
           (InvokeMethod v1 + v6 k5))
@@ -1015,11 +1015,11 @@
   while (true) {}
 }
 ''', '''
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetCont* (k0)
-    (LetPrim v0 (Constant BoolConstant(true)))
+    (LetPrim v0 (Constant (Bool true)))
     (LetCont (k1)
-      (LetPrim v1 (Constant NullConstant))
+      (LetPrim v1 (Constant (Null)))
       (InvokeContinuation return v1))
     (LetCont (k2)
       (InvokeContinuation* k0 ))
@@ -1036,17 +1036,17 @@
   }
 }
 ''', '''
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont* (k0 v1)
-    (LetPrim v2 (Constant IntConstant(10)))
+    (LetPrim v2 (Constant (Int 10)))
     (LetCont (k1 v3)
       (LetCont (k2)
-        (LetPrim v4 (Constant NullConstant))
+        (LetPrim v4 (Constant (Null)))
         (InvokeContinuation return v4))
       (LetCont (k3)
         (LetCont (k4 v5)
-          (LetPrim v6 (Constant IntConstant(1)))
+          (LetPrim v6 (Constant (Int 1)))
           (LetCont (k5 v7)
             (InvokeContinuation* k0 v7))
           (InvokeMethod v1 + v6 k5))
@@ -1063,7 +1063,7 @@
   return a is String;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (TypeOperator is a String k0))
@@ -1074,7 +1074,7 @@
   return a is List<String>;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (TypeOperator is a List<String> k0))
@@ -1085,7 +1085,7 @@
   return a is Comparator<String>;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (TypeOperator is a Comparator<String> k0))
@@ -1096,15 +1096,15 @@
   return a is! String;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (LetCont (k1 v1)
       (InvokeContinuation return v1))
     (LetCont (k2)
-      (LetPrim v2 (Constant BoolConstant(false)))
+      (LetPrim v2 (Constant (Bool false)))
       (InvokeContinuation k1 v2))
     (LetCont (k3)
-      (LetPrim v3 (Constant BoolConstant(true)))
+      (LetPrim v3 (Constant (Bool true)))
       (InvokeContinuation k1 v3))
     (Branch (IsTrue v0) k2 k3))
   (TypeOperator is a String k0))
@@ -1115,7 +1115,7 @@
   return a as String;
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (TypeOperator as a String k0))
@@ -1132,15 +1132,15 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (LetCont* (k1 v1)
       (LetCont (k2 v2)
         (LetCont (k3)
-          (LetPrim v3 (Constant NullConstant))
+          (LetPrim v3 (Constant (Null)))
           (InvokeContinuation return v3))
         (LetCont (k4)
-          (LetPrim v4 (Constant NullConstant))
+          (LetPrim v4 (Constant (Null)))
           (LetCont (k5 v5)
             (LetCont (k6 v6)
               (InvokeContinuation* k1 v1))
@@ -1161,18 +1161,18 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (LetCont* (k1 v1)
       (LetCont (k2 v2)
         (LetCont (k3)
-          (LetPrim v3 (Constant NullConstant))
+          (LetPrim v3 (Constant (Null)))
           (InvokeContinuation return v3))
         (LetCont (k4)
-          (LetPrim v4 (Constant NullConstant))
+          (LetPrim v4 (Constant (Null)))
           (LetCont (k5 v5)
             (LetCont (k6 v6)
-              (LetPrim v7 (Constant IntConstant(0)))
+              (LetPrim v7 (Constant (Int 0)))
               (LetCont (k7 v8)
                 (InvokeContinuation* k1 v1))
               (InvokeStatic print v7 k7))
@@ -1192,13 +1192,13 @@
   }
 }
 ''', '''
-(FunctionDefinition main (a return)
-  (LetPrim v0 (Constant NullConstant))
+(FunctionDefinition main (a) return ()
+  (LetPrim v0 (Constant (Null)))
   (LetCont (k0 v1)
     (LetCont* (k1 v2 v3)
       (LetCont (k2 v4)
         (LetCont (k3)
-          (LetPrim v5 (Constant NullConstant))
+          (LetPrim v5 (Constant (Null)))
           (InvokeContinuation return v5))
         (LetCont (k4)
           (LetCont (k5 v6)
@@ -1220,10 +1220,10 @@
   return local();
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetPrim v0 (CreateFunction
-    (FunctionDefinition local ( return)
-      (LetPrim v1 (Constant NullConstant))
+    (FunctionDefinition local () return ()
+      (LetPrim v1 (Constant (Null)))
       (InvokeContinuation return v1))))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
@@ -1237,10 +1237,10 @@
   return l();
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetPrim v0 (CreateFunction
-    (FunctionDefinition local ( return)
-      (LetPrim v1 (Constant NullConstant))
+    (FunctionDefinition local () return ()
+      (LetPrim v1 (Constant (Null)))
       (InvokeContinuation return v1))))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
@@ -1252,10 +1252,10 @@
   return () {}();
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetPrim v0 (CreateFunction
-    (FunctionDefinition  ( return)
-      (LetPrim v1 (Constant NullConstant))
+    (FunctionDefinition  () return ()
+      (LetPrim v1 (Constant (Null)))
       (InvokeContinuation return v1))))
   (LetCont (k0 v2)
     (InvokeContinuation return v2))
@@ -1268,21 +1268,21 @@
   return c();
 }
 ''', '''
-(FunctionDefinition main (a return)
+(FunctionDefinition main (a) return ()
   (LetCont (k0 v0)
     (LetCont (k1 v1)
       (InvokeContinuation return v1))
     (InvokeMethod v0 call  k1))
   (LetCont (k2)
     (LetPrim v2 (CreateFunction
-      (FunctionDefinition  ( return)
-        (LetPrim v3 (Constant IntConstant(0)))
+      (FunctionDefinition  () return ()
+        (LetPrim v3 (Constant (Int 0)))
         (InvokeContinuation return v3))))
     (InvokeContinuation k0 v2))
   (LetCont (k3)
     (LetPrim v4 (CreateFunction
-      (FunctionDefinition  ( return)
-        (LetPrim v5 (Constant IntConstant(1)))
+      (FunctionDefinition  () return ()
+        (LetPrim v5 (Constant (Int 1)))
         (InvokeContinuation return v5))))
     (InvokeContinuation k0 v4))
   (Branch (IsTrue a) k2 k3))
@@ -1297,7 +1297,7 @@
 }
 ''', const {
       'main': '''
-(FunctionDefinition main (args return)
+(FunctionDefinition main (args) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (InvokeStatic field  k0))
@@ -1313,14 +1313,14 @@
 }
 ''', const {
       'main': '''
-(FunctionDefinition main (args return)
+(FunctionDefinition main (args) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (InvokeStatic field  k0))
 ''',
       'field': '''
 (FieldDefinition field (return)
-  (LetPrim v0 (Constant NullConstant))
+  (LetPrim v0 (Constant (Null)))
   (InvokeContinuation return v0))
 '''}),
 
@@ -1331,14 +1331,14 @@
 }
 ''', const {
       'main': '''
-(FunctionDefinition main (args return)
+(FunctionDefinition main (args) return ()
   (LetCont (k0 v0)
     (InvokeContinuation return v0))
   (InvokeStatic field  k0))
 ''',
       'field': '''
 (FieldDefinition field (return)
-  (LetPrim v0 (Constant IntConstant(0)))
+  (LetPrim v0 (Constant (Int 0)))
   (InvokeContinuation return v0))
 '''}),
 
@@ -1349,7 +1349,7 @@
   return field;
 }
 ''', '''
-(FunctionDefinition main (args return)
+(FunctionDefinition main (args) return ()
   (LetCont (k0 v0)
     (LetCont (k1 v1)
       (LetCont (k2 v2)
@@ -1368,15 +1368,15 @@
   print(getFoo());
 }
 ''', '''
-(FunctionDefinition main {foo} (x foo return)
+(FunctionDefinition main (x foo) return (foo)
   (LetCont (k0 v0)
     (LetPrim v1 (CreateFunction
-      (FunctionDefinition getFoo ( return)
+      (FunctionDefinition getFoo () return ()
         (LetPrim v2 (GetClosureVariable foo))
         (InvokeContinuation return v2))))
     (LetCont (k1 v3)
       (LetCont (k2 v4)
-        (LetPrim v5 (Constant NullConstant))
+        (LetPrim v5 (Constant (Null)))
         (InvokeContinuation return v5))
       (InvokeStatic print v3 k2))
     (InvokeMethod v1 call  k1))
diff --git a/pkg/args/CHANGELOG.md b/pkg/args/CHANGELOG.md
index 3759dc9..2e503b7 100644
--- a/pkg/args/CHANGELOG.md
+++ b/pkg/args/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 0.12.2+1
+
+* Fix the built-in `help` command for `CommandRunner`.
+
+## 0.12.2
+
+* Add `CommandRunner` and `Command` classes which make it easy to build a
+  command-based command-line application.
+
+* Add an `ArgResults.arguments` field, which contains the original argument list.
+
 ## 0.12.1
 
 * Replace `ArgParser.getUsage()` with `ArgParser.usage`, a getter.
diff --git a/pkg/args/README.md b/pkg/args/README.md
index 9baf1fb..d51f7cb 100644
--- a/pkg/args/README.md
+++ b/pkg/args/README.md
@@ -197,6 +197,65 @@
 `"-a"` appears after `"commit"`, it is applied to that command. If it appears to
 the left of `"commit"`, it is given to the top-level parser.
 
+## Dispatching Commands
+
+If you're writing a command-based application, you can use the [CommandRunner][]
+and [Command][] classes to help structure it. [CommandRunner][] has built-in
+support for dispatching to [Command][]s based on command-line arguments, as well
+as handling `--help` flags and invalid arguments. For example:
+
+    var runner = new CommandRunner("git", "Distributed version control.");
+    runner.addCommand(new CommitCommand());
+    runner.addCommand(new StashCommand());
+    runner.run(['commit', '-a']); // Calls [CommitCommand.run()]
+
+Custom commands are defined by extending the [Command][] class. For example:
+
+    class CommitCommand extends Command {
+      // The [name] and [description] properties must be defined by every
+      // subclass.
+      final name = "commit";
+      final description = "Record changes to the repository.";
+
+      CommitCommand() {
+        // [argParser] is automatically created by the parent class.
+        argParser.addFlag('all', abbr: 'a');
+      }
+
+      // [run] may also return a Future.
+      void run() {
+        // [options] is set before [run()] is called and contains the options
+        // passed to this command.
+        print(options['all']);
+      }
+    }
+
+Commands can also have subcommands, which are added with [addSubcommand][]. A
+command with subcommands can't run its own code, so [run][] doesn't need to be
+implemented. For example:
+
+    class StashCommand extends Command {
+      final String name = "stash";
+      final String description = "Stash changes in the working directory.";
+
+      StashCommand() {
+        addSubcommand(new StashSaveCommand());
+        addSubcommand(new StashListCommand());
+      }
+    }
+
+[CommandRunner][] automatically adds a `help` command that displays usage
+information for commands, as well as support for the `--help` flag for all
+commands. If it encounters an error parsing the arguments or processing a
+command, it throws a [UsageError][]; your `main()` method should catch these and
+print them appropriately. For example:
+
+    runner.run(arguments).catchError((error) {
+      if (error is! UsageError) throw error;
+      print(error);
+      exit(64); // Exit code 64 indicates a usage error.
+    });
+
 ## Displaying usage
 
 You can automatically generate nice help text, suitable for use as the output of
@@ -240,11 +299,16 @@
 
 [posix]: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html#tag_12_02
 [gnu]: http://www.gnu.org/prep/standards/standards.html#Command_002dLine-Interfaces
-[ArgParser]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgParser
-[ArgResults]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgResults
-[addOption]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgParser#id_addOption
-[addFlag]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgParser#id_addFlag
-[parse]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgParser#id_parse
-[rest]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgResults#id_rest
-[addCommand]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgParser#id_addCommand
-[getUsage]: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/args/args.ArgParser#id_getUsage
+[ArgParser]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgParser
+[ArgResults]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgResults
+[CommandRunner]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.CommandRunner
+[Command]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.Command
+[UsageError]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.UsageError
+[addOption]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgParser@id_addOption
+[addFlag]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgParser@id_addFlag
+[parse]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgParser@id_parse
+[rest]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgResults@id_rest
+[addCommand]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgParser@id_addCommand
+[getUsage]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.ArgParser@id_getUsage
+[addSubcommand]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.Command@id_addSubcommand
+[run]: http://www.dartdocs.org/documentation/args/latest/index.html#args/args.Command@id_run
diff --git a/pkg/args/lib/command_runner.dart b/pkg/args/lib/command_runner.dart
new file mode 100644
index 0000000..bbc19b2
--- /dev/null
+++ b/pkg/args/lib/command_runner.dart
@@ -0,0 +1,384 @@
+// 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 args.command_runner;
+
+import 'dart:async';
+import 'dart:collection';
+import 'dart:math' as math;
+
+import 'src/arg_parser.dart';
+import 'src/arg_results.dart';
+import 'src/help_command.dart';
+import 'src/usage_exception.dart';
+import 'src/utils.dart';
+
+export 'src/usage_exception.dart';
+
+/// A class for invoking [Commands] based on raw command-line arguments.
+class CommandRunner {
+  /// The name of the executable being run.
+  ///
+  /// Used for error reporting and [usage].
+  final String executableName;
+
+  /// A short description of this executable.
+  final String description;
+
+  /// A single-line template for how to invoke this executable.
+  ///
+  /// Defaults to "$executableName <command> [arguments]". Subclasses can
+  /// override this for a more specific template.
+  String get invocation => "$executableName <command> [arguments]";
+
+  /// Generates a string displaying usage information for the executable.
+  ///
+  /// This includes usage for the global arguments as well as a list of
+  /// top-level commands.
+  String get usage => "$description\n\n$_usageWithoutDescription";
+
+  /// An optional footer for [usage].
+  ///
+  /// If a subclass overrides this to return a string, it will automatically be
+  /// added to the end of [usage].
+  final String usageFooter = null;
+
+  /// Returns [usage] with [description] removed from the beginning.
+  String get _usageWithoutDescription {
+    var usage = '''
+Usage: $invocation
+
+Global options:
+${argParser.usage}
+
+${_getCommandUsage(_commands)}
+
+Run "$executableName help <command>" for more information about a command.''';
+
+    if (usageFooter != null) usage += "\n$usageFooter";
+    return usage;
+  }
+
+  /// An unmodifiable view of all top-level commands defined for this runner.
+  Map<String, Command> get commands =>
+      new UnmodifiableMapView(_commands);
+  final _commands = new Map<String, Command>();
+
+  /// The top-level argument parser.
+  ///
+  /// Global options should be registered with this parser; they'll end up
+  /// available via [Command.globalResults]. Commands should be registered with
+  /// [addCommand] rather than directly on the parser.
+  final argParser = new ArgParser();
+
+  CommandRunner(this.executableName, this.description) {
+    argParser.addFlag('help', abbr: 'h', negatable: false,
+        help: 'Print this usage information.');
+    addCommand(new HelpCommand());
+  }
+
+  /// Prints the usage information for this runner.
+  ///
+  /// This is called internally by [run] and can be overridden by subclasses to
+  /// control how output is displayed or integrate with a logging system.
+  void printUsage() => print(usage);
+
+  /// Throws a [UsageException] with [message].
+  void usageException(String message) =>
+      throw new UsageException(message, _usageWithoutDescription);
+
+  /// Adds [Command] as a top-level command to this runner.
+  void addCommand(Command command) {
+    var names = [command.name]..addAll(command.aliases);
+    for (var name in names) {
+      _commands[name] = command;
+      argParser.addCommand(name, command.argParser);
+    }
+    command._runner = this;
+  }
+
+  /// Parses [args] and invokes [Command.run] on the chosen command.
+  ///
+  /// This always returns a [Future] in case the command is asynchronous. The
+  /// [Future] will throw a [UsageError] if [args] was invalid.
+  Future run(Iterable<String> args) =>
+      new Future.sync(() => runCommand(parse(args)));
+
+  /// Parses [args] and returns the result, converting a [FormatException] to a
+  /// [UsageException].
+  ///
+  /// This is notionally a protected method. It may be overridden or called from
+  /// subclasses, but it shouldn't be called externally.
+  ArgResults parse(Iterable<String> args) {
+    try {
+      // TODO(nweiz): if arg parsing fails for a command, print that command's
+      // usage, not the global usage.
+      return argParser.parse(args);
+    } on FormatException catch (error) {
+      usageException(error.message);
+    }
+  }
+
+  /// Runs the command specified by [topLevelResults].
+  ///
+  /// This is notionally a protected method. It may be overridden or called from
+  /// subclasses, but it shouldn't be called externally.
+  ///
+  /// It's useful to override this to handle global flags and/or wrap the entire
+  /// command in a block. For example, you might handle the `--verbose` flag
+  /// here to enable verbose logging before running the command.
+  Future runCommand(ArgResults topLevelResults) {
+    return new Future.sync(() {
+      var argResults = topLevelResults;
+      var commands = _commands;
+      var command;
+      var commandString = executableName;
+
+      while (commands.isNotEmpty) {
+        if (argResults.command == null) {
+          if (argResults.rest.isEmpty) {
+            if (command == null) {
+              // No top-level command was chosen.
+              printUsage();
+              return new Future.value();
+            }
+
+            command.usageException('Missing subcommand for "$commandString".');
+          } else {
+            if (command == null) {
+              usageException(
+                  'Could not find a command named "${argResults.rest[0]}".');
+            }
+
+            command.usageException('Could not find a subcommand named '
+                '"${argResults.rest[0]}" for "$commandString".');
+          }
+        }
+
+        // Step into the command.
+        argResults = argResults.command;
+        command = commands[argResults.name];
+        command._globalResults = topLevelResults;
+        command._argResults = argResults;
+        commands = command._subcommands;
+        commandString += " ${argResults.name}";
+
+        if (argResults['help']) {
+          command.printUsage();
+          return new Future.value();
+        }
+      }
+
+      // Make sure there aren't unexpected arguments.
+      if (!command.takesArguments && argResults.rest.isNotEmpty) {
+        command.usageException(
+            'Command "${argResults.name}" does not take any arguments.');
+      }
+
+      return command.run();
+    });
+  }
+}
+
+/// A single command.
+///
+/// A command is known as a "leaf command" if it has no subcommands and is meant
+/// to be run. Leaf commands must override [run].
+///
+/// A command with subcommands is known as a "branch command" and cannot be run
+/// itself. It should call [addSubcommand] (often from the constructor) to
+/// register subcommands.
+abstract class Command {
+  /// The name of this command.
+  String get name;
+
+  /// A short description of this command.
+  String get description;
+
+  /// A single-line template for how to invoke this command (e.g. `"pub get
+  /// [package]"`).
+  String get invocation {
+    var parents = [name];
+    for (var command = parent; command != null; command = command.parent) {
+      parents.add(command.name);
+    }
+    parents.add(runner.executableName);
+
+    var invocation = parents.reversed.join(" ");
+    return _subcommands.isNotEmpty ?
+        "$invocation <subcommand> [arguments]" :
+        "$invocation [arguments]";
+  }
+
+  /// The command's parent command, if this is a subcommand.
+  ///
+  /// This will be `null` until [Command.addSubcommmand] has been called with
+  /// this command.
+  Command get parent => _parent;
+  Command _parent;
+
+  /// The command runner for this command.
+  ///
+  /// This will be `null` until [CommandRunner.addCommand] has been called with
+  /// this command or one of its parents.
+  CommandRunner get runner {
+    if (parent == null) return _runner;
+    return parent.runner;
+  }
+  CommandRunner _runner;
+
+  /// The parsed global argument results.
+  ///
+  /// This will be `null` until just before [Command.run] is called.
+  ArgResults get globalResults => _globalResults;
+  ArgResults _globalResults;
+
+  /// The parsed argument results for this command.
+  ///
+  /// This will be `null` until just before [Command.run] is called.
+  ArgResults get argResults => _argResults;
+  ArgResults _argResults;
+
+  /// The argument parser for this command.
+  ///
+  /// Options for this command should be registered with this parser (often in
+  /// the constructor); they'll end up available via [argResults]. Subcommands
+  /// should be registered with [addSubcommand] rather than directly on the
+  /// parser.
+  final argParser = new ArgParser();
+
+  /// Generates a string displaying usage information for this command.
+  ///
+  /// This includes usage for the command's arguments as well as a list of
+  /// subcommands, if there are any.
+  String get usage => "$description\n\n$_usageWithoutDescription";
+
+  /// An optional footer for [usage].
+  ///
+  /// If a subclass overrides this to return a string, it will automatically be
+  /// added to the end of [usage].
+  final String usageFooter = null;
+
+  /// Returns [usage] with [description] removed from the beginning.
+  String get _usageWithoutDescription {
+    var buffer = new StringBuffer()
+        ..writeln('Usage: $invocation')
+        ..writeln(argParser.usage);
+
+    if (_subcommands.isNotEmpty) {
+      buffer.writeln();
+      buffer.writeln(_getCommandUsage(_subcommands, isSubcommand: true));
+    }
+
+    buffer.writeln();
+    buffer.write('Run "${runner.executableName} help" to see global options.');
+
+    if (usageFooter != null) {
+      buffer.writeln();
+      buffer.write(usageFooter);
+    }
+
+    return buffer.toString();
+  }
+
+  /// An unmodifiable view of all sublevel commands of this command.
+  Map<String, Command> get subcommands =>
+      new UnmodifiableMapView(_subcommands);
+  final _subcommands = new Map<String, Command>();
+
+  /// Whether or not this command should be hidden from help listings.
+  ///
+  /// This is intended to be overridden by commands that want to mark themselves
+  /// hidden.
+  ///
+  /// By default, leaf commands are always visible. Branch commands are visible
+  /// as long as any of their leaf commands are visible.
+  bool get hidden {
+    // Leaf commands are visible by default.
+    if (_subcommands.isEmpty) return false;
+
+    // Otherwise, a command is hidden if all of its subcommands are.
+    return _subcommands.values.every((subcommand) => subcommand.hidden);
+  }
+
+  /// Whether or not this command takes positional arguments in addition to
+  /// options.
+  ///
+  /// If false, [CommandRunner.run] will throw a [UsageException] if arguments
+  /// are provided. Defaults to true.
+  ///
+  /// This is intended to be overridden by commands that don't want to receive
+  /// arguments. It has no effect for branch commands.
+  final takesArguments = true;
+
+  /// Alternate names for this command.
+  ///
+  /// These names won't be used in the documentation, but they will work when
+  /// invoked on the command line.
+  ///
+  /// This is intended to be overridden.
+  final aliases = const <String>[];
+
+  Command() {
+    argParser.addFlag('help', abbr: 'h', negatable: false,
+        help: 'Print this usage information.');
+  }
+
+  /// Runs this command.
+  ///
+  /// If this returns a [Future], [CommandRunner.run] won't complete until the
+  /// returned [Future] does. Otherwise, the return value is ignored.
+  run() {
+    throw new UnimplementedError("Leaf command $this must implement run().");
+  }
+
+  /// Adds [Command] as a subcommand of this.
+  void addSubcommand(Command command) {
+    var names = [command.name]..addAll(command.aliases);
+    for (var name in names) {
+      _subcommands[name] = command;
+      argParser.addCommand(name, command.argParser);
+    }
+    command._parent = this;
+  }
+
+  /// Prints the usage information for this command.
+  ///
+  /// This is called internally by [run] and can be overridden by subclasses to
+  /// control how output is displayed or integrate with a logging system.
+  void printUsage() => print(usage);
+
+  /// Throws a [UsageException] with [message].
+  void usageException(String message) =>
+      throw new UsageException(message, _usageWithoutDescription);
+}
+
+/// Returns a string representation of [commands] fit for use in a usage string.
+///
+/// [isSubcommand] indicates whether the commands should be called "commands" or
+/// "subcommands".
+String _getCommandUsage(Map<String, Command> commands,
+    {bool isSubcommand: false}) {
+  // Don't include aliases.
+  var names = commands.keys
+      .where((name) => !commands[name].aliases.contains(name));
+
+  // Filter out hidden ones, unless they are all hidden.
+  var visible = names.where((name) => !commands[name].hidden);
+  if (visible.isNotEmpty) names = visible;
+
+  // Show the commands alphabetically.
+  names = names.toList()..sort();
+  var length = names.map((name) => name.length).reduce(math.max);
+
+  var buffer = new StringBuffer(
+      'Available ${isSubcommand ? "sub" : ""}commands:');
+  for (var name in names) {
+    buffer.writeln();
+    buffer.write('  ${padRight(name, length)}   '
+        '${commands[name].description.split("\n").first}');
+  }
+
+  return buffer.toString();
+}
diff --git a/pkg/args/lib/src/arg_results.dart b/pkg/args/lib/src/arg_results.dart
index 2e47a8e..815d8dd 100644
--- a/pkg/args/lib/src/arg_results.dart
+++ b/pkg/args/lib/src/arg_results.dart
@@ -13,8 +13,9 @@
 /// Since [ArgResults] doesn't have a public constructor, this lets [Parser]
 /// get to it. This function isn't exported to the public API of the package.
 ArgResults newArgResults(ArgParser parser, Map<String, dynamic> parsed,
-      String name, ArgResults command, List<String> rest) {
-  return new ArgResults._(parser, parsed, name, command, rest);
+      String name, ArgResults command, List<String> rest,
+      List<String> arguments) {
+  return new ArgResults._(parser, parsed, name, command, rest, arguments);
 }
 
 /// The results of parsing a series of command line arguments using
@@ -46,10 +47,14 @@
   /// `--` was reached.
   final List<String> rest;
 
+  /// The original list of arguments that were parsed.
+  final List<String> arguments;
+
   /// Creates a new [ArgResults].
   ArgResults._(this._parser, this._parsed, this.name, this.command,
-      List<String> rest)
-      : this.rest = new UnmodifiableListView(rest);
+      List<String> rest, List<String> arguments)
+      : this.rest = new UnmodifiableListView(rest),
+        this.arguments = new UnmodifiableListView(arguments);
 
   /// Gets the parsed command-line option named [name].
   operator [](String name) {
diff --git a/pkg/args/lib/src/help_command.dart b/pkg/args/lib/src/help_command.dart
new file mode 100644
index 0000000..f477b47
--- /dev/null
+++ b/pkg/args/lib/src/help_command.dart
@@ -0,0 +1,53 @@
+// 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 args.help_command;
+
+import '../command_runner.dart';
+
+/// The built-in help command that's added to every [CommandRunner].
+///
+/// This command displays help information for the various subcommands.
+class HelpCommand extends Command {
+  final name = "help";
+  String get description =>
+      "Display help information for ${runner.executableName}.";
+  String get invocation => "${runner.executableName} help [command]";
+
+  void run() {
+    // Show the default help if no command was specified.
+    if (argResults.rest.isEmpty) {
+      runner.printUsage();
+      return;
+    }
+
+    // Walk the command tree to show help for the selected command or
+    // subcommand.
+    var commands = runner.commands;
+    var command = null;
+    var commandString = runner.executableName;
+
+    for (var name in argResults.rest) {
+      if (commands.isEmpty) {
+        command.usageException(
+            'Command "$commandString" does not expect a subcommand.');
+      }
+
+      if (commands[name] == null) {
+        if (command == null) {
+          runner.usageException('Could not find a command named "$name".');
+        }
+
+        command.usageException(
+            'Could not find a subcommand named "$name" for "$commandString".');
+      }
+
+      command = commands[name];
+      commands = command.subcommands;
+      commandString += " $name";
+    }
+
+    command.printUsage();
+  }
+}
diff --git a/pkg/args/lib/src/parser.dart b/pkg/args/lib/src/parser.dart
index 4d3417a..9cd141c 100644
--- a/pkg/args/lib/src/parser.dart
+++ b/pkg/args/lib/src/parser.dart
@@ -46,6 +46,7 @@
 
   /// Parses the arguments. This can only be called once.
   ArgResults parse() {
+    var arguments = args.toList();
     var commandResults = null;
 
     // Parse the args.
@@ -91,7 +92,8 @@
     // Add in the leftover arguments we didn't parse to the innermost command.
     rest.addAll(args);
     args.clear();
-    return newArgResults(grammar, results, commandName, commandResults, rest);
+    return newArgResults(grammar, results, commandName, commandResults, rest,
+        arguments);
   }
 
   /// Pulls the value for [option] from the second argument in [args].
diff --git a/pkg/args/lib/src/usage_exception.dart b/pkg/args/lib/src/usage_exception.dart
new file mode 100644
index 0000000..35cc744
--- /dev/null
+++ b/pkg/args/lib/src/usage_exception.dart
@@ -0,0 +1,14 @@
+// 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 args.usage_exception;
+
+class UsageException implements Exception {
+  final String message;
+  final String usage;
+
+  UsageException(this.message, this.usage);
+
+  String toString() => "$message\n\n$usage";
+}
diff --git a/pkg/args/lib/src/utils.dart b/pkg/args/lib/src/utils.dart
new file mode 100644
index 0000000..dc355df
--- /dev/null
+++ b/pkg/args/lib/src/utils.dart
@@ -0,0 +1,9 @@
+// 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 args.utils;
+
+/// Pads [source] to [length] by adding spaces at the end.
+String padRight(String source, int length) =>
+    source + ' ' * (length - source.length);
diff --git a/pkg/args/pubspec.yaml b/pkg/args/pubspec.yaml
index 4dd081d..275af81 100644
--- a/pkg/args/pubspec.yaml
+++ b/pkg/args/pubspec.yaml
@@ -1,5 +1,5 @@
 name: args
-version: 0.12.1
+version: 0.12.2+1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/args/test/args_test.dart b/pkg/args/test/args_test.dart
index 6792c95..77c23c3 100644
--- a/pkg/args/test/args_test.dart
+++ b/pkg/args/test/args_test.dart
@@ -228,6 +228,14 @@
       expect(() => results.rest.add('oops'), throwsUnsupportedError);
     });
 
+    test('.arguments returns the original argument list', () {
+      var parser = new ArgParser();
+      parser.addFlag('foo');
+
+      var results = parser.parse(['--foo']);
+      expect(results.arguments, equals(['--foo']));
+    });
+
     group('.wasParsed()', () {
       test('throws if the name is not an option', () {
         var results = new ArgParser().parse([]);
diff --git a/pkg/args/test/command_parse_test.dart b/pkg/args/test/command_parse_test.dart
new file mode 100644
index 0000000..ac53056
--- /dev/null
+++ b/pkg/args/test/command_parse_test.dart
@@ -0,0 +1,207 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library command_parse_test;
+
+import 'package:unittest/unittest.dart';
+import 'package:args/args.dart';
+import 'utils.dart';
+
+void main() {
+  group('ArgParser.addCommand()', () {
+    test('creates a new ArgParser if none is given', () {
+      var parser = new ArgParser();
+      var command = parser.addCommand('install');
+      expect(parser.commands['install'], equals(command));
+      expect(command is ArgParser, isTrue);
+    });
+
+    test('uses the command parser if given one', () {
+      var parser = new ArgParser();
+      var command = new ArgParser();
+      var result = parser.addCommand('install', command);
+      expect(parser.commands['install'], equals(command));
+      expect(result, equals(command));
+    });
+
+    test('throws on a duplicate command name', () {
+      var parser = new ArgParser();
+      parser.addCommand('install');
+      throwsIllegalArg(() => parser.addCommand('install'));
+    });
+  });
+
+  group('ArgParser.parse()', () {
+    test('parses a command', () {
+      var parser = new ArgParser();
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['install']);
+
+      expect(args.command.name, equals('install'));
+      expect(args.rest, isEmpty);
+    });
+
+    test('parses a command option', () {
+      var parser = new ArgParser();
+      var command = parser.addCommand('install');
+      command.addOption('path');
+
+      var args = parser.parse(['install', '--path', 'some/path']);
+      expect(args.command['path'], equals('some/path'));
+    });
+
+    test('parses a parent solo option before the command', () {
+      var parser = new ArgParser();
+      parser.addOption('mode', abbr: 'm');
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['-m', 'debug', 'install']);
+      expect(args['mode'], equals('debug'));
+      expect(args.command.name, equals('install'));
+    });
+
+    test('parses a parent solo option after the command', () {
+      var parser = new ArgParser();
+      parser.addOption('mode', abbr: 'm');
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['install', '-m', 'debug']);
+      expect(args['mode'], equals('debug'));
+      expect(args.command.name, equals('install'));
+    });
+
+    test('parses a parent option before the command', () {
+      var parser = new ArgParser();
+      parser.addFlag('verbose');
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['--verbose', 'install']);
+      expect(args['verbose'], isTrue);
+      expect(args.command.name, equals('install'));
+    });
+
+    test('parses a parent option after the command', () {
+      var parser = new ArgParser();
+      parser.addFlag('verbose');
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['install', '--verbose']);
+      expect(args['verbose'], isTrue);
+      expect(args.command.name, equals('install'));
+    });
+
+    test('parses a parent negated option before the command', () {
+      var parser = new ArgParser();
+      parser.addFlag('verbose', defaultsTo: true);
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['--no-verbose', 'install']);
+      expect(args['verbose'], isFalse);
+      expect(args.command.name, equals('install'));
+    });
+
+    test('parses a parent negated option after the command', () {
+      var parser = new ArgParser();
+      parser.addFlag('verbose', defaultsTo: true);
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['install', '--no-verbose']);
+      expect(args['verbose'], isFalse);
+      expect(args.command.name, equals('install'));
+    });
+
+    test('parses a parent abbreviation before the command', () {
+      var parser = new ArgParser();
+      parser.addFlag('debug', abbr: 'd');
+      parser.addFlag('verbose', abbr: 'v');
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['-dv', 'install']);
+      expect(args['debug'], isTrue);
+      expect(args['verbose'], isTrue);
+      expect(args.command.name, equals('install'));
+    });
+
+    test('parses a parent abbreviation after the command', () {
+      var parser = new ArgParser();
+      parser.addFlag('debug', abbr: 'd');
+      parser.addFlag('verbose', abbr: 'v');
+      var command = parser.addCommand('install');
+
+      var args = parser.parse(['install', '-dv']);
+      expect(args['debug'], isTrue);
+      expect(args['verbose'], isTrue);
+      expect(args.command.name, equals('install'));
+    });
+
+    test('does not parse a solo command option before the command', () {
+      var parser = new ArgParser();
+      var command = parser.addCommand('install');
+      command.addOption('path', abbr: 'p');
+
+      throwsFormat(parser, ['-p', 'foo', 'install']);
+    });
+
+    test('does not parse a command option before the command', () {
+      var parser = new ArgParser();
+      var command = parser.addCommand('install');
+      command.addOption('path');
+
+      throwsFormat(parser, ['--path', 'foo', 'install']);
+    });
+
+    test('does not parse a command abbreviation before the command', () {
+      var parser = new ArgParser();
+      var command = parser.addCommand('install');
+      command.addFlag('debug', abbr: 'd');
+      command.addFlag('verbose', abbr: 'v');
+
+      throwsFormat(parser, ['-dv', 'install']);
+    });
+
+    test('assigns collapsed options to the proper command', () {
+      var parser = new ArgParser();
+      parser.addFlag('apple', abbr: 'a');
+      var command = parser.addCommand('cmd');
+      command.addFlag('banana', abbr: 'b');
+      var subcommand = command.addCommand('subcmd');
+      subcommand.addFlag('cherry', abbr: 'c');
+
+      var args = parser.parse(['cmd', 'subcmd', '-abc']);
+      expect(args['apple'], isTrue);
+      expect(args.command.name, equals('cmd'));
+      expect(args.command['banana'], isTrue);
+      expect(args.command.command.name, equals('subcmd'));
+      expect(args.command.command['cherry'], isTrue);
+    });
+
+    test('option is given to innermost command that can take it', () {
+      var parser = new ArgParser();
+      parser.addFlag('verbose');
+      var command = parser.addCommand('cmd');
+      command.addFlag('verbose');
+      var subcommand = command.addCommand('subcmd');
+
+      var args = parser.parse(['cmd', 'subcmd', '--verbose']);
+      expect(args['verbose'], isFalse);
+      expect(args.command.name, equals('cmd'));
+      expect(args.command['verbose'], isTrue);
+      expect(args.command.command.name, equals('subcmd'));
+    });
+
+    test('remaining arguments are given to the innermost command', () {
+      var parser = new ArgParser();
+      var command = parser.addCommand('cmd');
+      var subcommand = command.addCommand('subcmd');
+
+      var args = parser.parse(['cmd', 'subcmd', 'other', 'stuff']);
+      expect(args.command.name, equals('cmd'));
+      expect(args.rest, isEmpty);
+      expect(args.command.command.name, equals('subcmd'));
+      expect(args.command.rest, isEmpty);
+      expect(args.command.command.rest, equals(['other', 'stuff']));
+    });
+  });
+}
diff --git a/pkg/args/test/command_runner_test.dart b/pkg/args/test/command_runner_test.dart
new file mode 100644
index 0000000..ba7faeb
--- /dev/null
+++ b/pkg/args/test/command_runner_test.dart
@@ -0,0 +1,295 @@
+// 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 command_runner_test;
+
+import 'package:args/args.dart';
+import 'package:args/command_runner.dart';
+import 'package:unittest/unittest.dart';
+
+import 'utils.dart';
+
+const _DEFAULT_USAGE = """
+Usage: test <command> [arguments]
+
+Global options:
+-h, --help    Print this usage information.
+
+Available commands:
+  help   Display help information for test.
+
+Run "test help <command>" for more information about a command.""";
+
+void main() {
+  var runner;
+  setUp(() {
+    runner = new CommandRunner("test", "A test command runner.");
+  });
+
+  test(".invocation has a sane default", () {
+    expect(runner.invocation,
+        equals("test <command> [arguments]"));
+  });
+
+  group(".usage", () {
+    test("returns the usage string", () {
+      expect(runner.usage, equals("""
+A test command runner.
+
+$_DEFAULT_USAGE"""));
+    });
+
+    test("contains custom commands", () {
+      runner.addCommand(new FooCommand());
+
+      expect(runner.usage, equals("""
+A test command runner.
+
+Usage: test <command> [arguments]
+
+Global options:
+-h, --help    Print this usage information.
+
+Available commands:
+  foo    Set a value.
+  help   Display help information for test.
+
+Run "test help <command>" for more information about a command."""));
+    });
+
+    test("contains custom options", () {
+      runner.argParser.addFlag("foo", help: "Do something.");
+
+      expect(runner.usage, equals("""
+A test command runner.
+
+Usage: test <command> [arguments]
+
+Global options:
+-h, --help        Print this usage information.
+    --[no-]foo    Do something.
+
+Available commands:
+  help   Display help information for test.
+
+Run "test help <command>" for more information about a command."""));
+    });
+
+    test("doesn't print hidden commands", () {
+      runner.addCommand(new HiddenCommand());
+
+      expect(runner.usage, equals("""
+A test command runner.
+
+$_DEFAULT_USAGE"""));
+    });
+
+    test("doesn't print aliases", () {
+      runner.addCommand(new AliasedCommand());
+
+      expect(runner.usage, equals("""
+A test command runner.
+
+Usage: test <command> [arguments]
+
+Global options:
+-h, --help    Print this usage information.
+
+Available commands:
+  aliased   Set a value.
+  help      Display help information for test.
+
+Run "test help <command>" for more information about a command."""));
+    });
+  });
+
+  test("usageException splits up the message and usage", () {
+    expect(() => runner.usageException("message"),
+        throwsUsageError("message", _DEFAULT_USAGE));
+  });
+
+  group("run()", () {
+    test("runs a command", () {
+      var command = new FooCommand();
+      runner.addCommand(command);
+
+      expect(runner.run(["foo"]).then((_) {
+        expect(command.hasRun, isTrue);
+      }), completes);
+    });
+
+    test("runs an asynchronous command", () {
+      var command = new AsyncCommand();
+      runner.addCommand(command);
+
+      expect(runner.run(["async"]).then((_) {
+        expect(command.hasRun, isTrue);
+      }), completes);
+    });
+
+    test("runs a hidden comand", () {
+      var command = new HiddenCommand();
+      runner.addCommand(command);
+
+      expect(runner.run(["hidden"]).then((_) {
+        expect(command.hasRun, isTrue);
+      }), completes);
+    });
+
+    test("runs an aliased comand", () {
+      var command = new AliasedCommand();
+      runner.addCommand(command);
+
+      expect(runner.run(["als"]).then((_) {
+        expect(command.hasRun, isTrue);
+      }), completes);
+    });
+
+    test("runs a subcommand", () {
+      var command = new AsyncCommand();
+      runner.addCommand(new FooCommand()..addSubcommand(command));
+
+      expect(runner.run(["foo", "async"]).then((_) {
+        expect(command.hasRun, isTrue);
+      }), completes);
+    });
+
+    group("with --help", () {
+      test("with no command prints the usage", () {
+        expect(() => runner.run(["--help"]), prints("""
+A test command runner.
+
+$_DEFAULT_USAGE
+"""));
+      });
+
+      test("with a command prints the usage for that command", () {
+        var command = new FooCommand();
+        runner.addCommand(command);
+
+        expect(() => runner.run(["foo", "--help"]), prints("""
+Set a value.
+
+Usage: test foo [arguments]
+-h, --help    Print this usage information.
+
+Run "test help" to see global options.
+"""));
+      });
+    });
+
+    group("with help command", () {
+      test("with no command prints the usage", () {
+        expect(() => runner.run(["help"]), prints("""
+A test command runner.
+
+$_DEFAULT_USAGE
+"""));
+      });
+
+      test("with a command prints the usage for that command", () {
+        var command = new FooCommand();
+        runner.addCommand(command);
+
+        expect(() => runner.run(["help", "foo"]), prints("""
+Set a value.
+
+Usage: test foo [arguments]
+-h, --help    Print this usage information.
+
+Run "test help" to see global options.
+"""));
+    });
+
+      test("prints its own usage", () {
+        expect(() => runner.run(["help", "help"]), prints("""
+Display help information for test.
+
+Usage: test help [command]
+-h, --help    Print this usage information.
+
+Run "test help" to see global options.
+"""));
+      });
+    });
+  });
+
+  group("with a footer", () {
+    setUp(() {
+      runner = new CommandRunnerWithFooter("test", "A test command runner.");
+    });
+
+    test("includes the footer in the usage string", () {
+      expect(runner.usage, equals("""
+A test command runner.
+
+$_DEFAULT_USAGE
+Also, footer!"""));
+    });
+
+    test("includes the footer in usage errors", () {
+      expect(runner.run(["--bad"]),
+          throwsUsageError('Could not find an option named "bad".',
+              "$_DEFAULT_USAGE\nAlso, footer!"));
+    });
+  });
+
+  group("throws a useful error when", () {
+    test("arg parsing fails", () {
+      expect(runner.run(["--bad"]),
+          throwsUsageError('Could not find an option named "bad".',
+              _DEFAULT_USAGE));
+    });
+
+    test("a top-level command doesn't exist", () {
+      expect(runner.run(["bad"]),
+          throwsUsageError('Could not find a command named "bad".',
+              _DEFAULT_USAGE));
+    });
+
+    test("a subcommand doesn't exist", () {
+      runner.addCommand(
+          new FooCommand()..addSubcommand(new AsyncCommand()));
+
+      expect(runner.run(["foo bad"]),
+          throwsUsageError('Could not find a command named "foo bad".', """
+Usage: test <command> [arguments]
+
+Global options:
+-h, --help    Print this usage information.
+
+Available commands:
+  foo    Set a value.
+  help   Display help information for test.
+
+Run "test help <command>" for more information about a command."""));
+    });
+
+    test("a subcommand wasn't passed", () {
+      runner.addCommand(
+          new FooCommand()..addSubcommand(new AsyncCommand()));
+
+      expect(runner.run(["foo"]),
+          throwsUsageError('Missing subcommand for "test foo".', """
+Usage: test foo <subcommand> [arguments]
+-h, --help    Print this usage information.
+
+Available subcommands:
+  async   Set a value asynchronously.
+
+Run "test help" to see global options."""));
+    });
+
+    test("a command that doesn't take arguments was given them", () {
+      runner.addCommand(new FooCommand());
+
+      expect(runner.run(["foo", "bar"]),
+          throwsUsageError('Command "foo" does not take any arguments.', """
+Usage: test foo [arguments]
+-h, --help    Print this usage information.
+
+Run "test help" to see global options."""));
+    });
+  });
+}
diff --git a/pkg/args/test/command_test.dart b/pkg/args/test/command_test.dart
index 1380e16..ae3594b 100644
--- a/pkg/args/test/command_test.dart
+++ b/pkg/args/test/command_test.dart
@@ -1,207 +1,110 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// 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 command_test;
 
-import 'package:unittest/unittest.dart';
 import 'package:args/args.dart';
+import 'package:args/command_runner.dart';
+import 'package:unittest/unittest.dart';
 import 'utils.dart';
 
 void main() {
-  group('ArgParser.addCommand()', () {
-    test('creates a new ArgParser if none is given', () {
-      var parser = new ArgParser();
-      var command = parser.addCommand('install');
-      expect(parser.commands['install'], equals(command));
-      expect(command is ArgParser, isTrue);
+  var foo;
+  setUp(() {
+    foo = new FooCommand();
+
+      // Make sure [Command.runner] is set up.
+    new CommandRunner("test", "A test command runner.").addCommand(foo);
+  });
+
+  group(".invocation has a sane default", () {
+    test("without subcommands", () {
+      expect(foo.invocation,
+          equals("test foo [arguments]"));
     });
 
-    test('uses the command parser if given one', () {
-      var parser = new ArgParser();
-      var command = new ArgParser();
-      var result = parser.addCommand('install', command);
-      expect(parser.commands['install'], equals(command));
-      expect(result, equals(command));
+    test("with subcommands", () {
+      foo.addSubcommand(new AsyncCommand());
+      expect(foo.invocation,
+          equals("test foo <subcommand> [arguments]"));
     });
 
-    test('throws on a duplicate command name', () {
-      var parser = new ArgParser();
-      parser.addCommand('install');
-      throwsIllegalArg(() => parser.addCommand('install'));
+    test("for a subcommand", () {
+      var async = new AsyncCommand();
+      foo.addSubcommand(async);
+
+      expect(async.invocation,
+          equals("test foo async [arguments]"));
     });
   });
 
-  group('ArgParser.parse()', () {
-    test('parses a command', () {
-      var parser = new ArgParser();
-      var command = parser.addCommand('install');
+  group(".usage", () {
+    test("returns the usage string", () {
+      expect(foo.usage, equals("""
+Set a value.
 
-      var args = parser.parse(['install']);
+Usage: test foo [arguments]
+-h, --help    Print this usage information.
 
-      expect(args.command.name, equals('install'));
-      expect(args.rest, isEmpty);
+Run "test help" to see global options."""));
     });
 
-    test('parses a command option', () {
-      var parser = new ArgParser();
-      var command = parser.addCommand('install');
-      command.addOption('path');
+    test("contains custom options", () {
+      foo.argParser.addFlag("flag", help: "Do something.");
 
-      var args = parser.parse(['install', '--path', 'some/path']);
-      expect(args.command['path'], equals('some/path'));
+      expect(foo.usage, equals("""
+Set a value.
+
+Usage: test foo [arguments]
+-h, --help         Print this usage information.
+    --[no-]flag    Do something.
+
+Run "test help" to see global options."""));
     });
 
-    test('parses a parent solo option before the command', () {
-      var parser = new ArgParser();
-      parser.addOption('mode', abbr: 'm');
-      var command = parser.addCommand('install');
+    test("doesn't print hidden subcommands", () {
+      foo.addSubcommand(new AsyncCommand());
+      foo.addSubcommand(new HiddenCommand());
 
-      var args = parser.parse(['-m', 'debug', 'install']);
-      expect(args['mode'], equals('debug'));
-      expect(args.command.name, equals('install'));
+      expect(foo.usage, equals("""
+Set a value.
+
+Usage: test foo <subcommand> [arguments]
+-h, --help    Print this usage information.
+
+Available subcommands:
+  async   Set a value asynchronously.
+
+Run "test help" to see global options."""));
     });
 
-    test('parses a parent solo option after the command', () {
-      var parser = new ArgParser();
-      parser.addOption('mode', abbr: 'm');
-      var command = parser.addCommand('install');
+    test("doesn't print subcommand aliases", () {
+      foo.addSubcommand(new AliasedCommand());
 
-      var args = parser.parse(['install', '-m', 'debug']);
-      expect(args['mode'], equals('debug'));
-      expect(args.command.name, equals('install'));
+      expect(foo.usage, equals("""
+Set a value.
+
+Usage: test foo <subcommand> [arguments]
+-h, --help    Print this usage information.
+
+Available subcommands:
+  aliased   Set a value.
+
+Run "test help" to see global options."""));
     });
+  });
 
-    test('parses a parent option before the command', () {
-      var parser = new ArgParser();
-      parser.addFlag('verbose');
-      var command = parser.addCommand('install');
+  test("usageException splits up the message and usage", () {
+    expect(() => foo.usageException("message"), throwsUsageError("message", """
+Usage: test foo [arguments]
+-h, --help    Print this usage information.
 
-      var args = parser.parse(['--verbose', 'install']);
-      expect(args['verbose'], isTrue);
-      expect(args.command.name, equals('install'));
-    });
+Run "test help" to see global options."""));
+  });
 
-    test('parses a parent option after the command', () {
-      var parser = new ArgParser();
-      parser.addFlag('verbose');
-      var command = parser.addCommand('install');
-
-      var args = parser.parse(['install', '--verbose']);
-      expect(args['verbose'], isTrue);
-      expect(args.command.name, equals('install'));
-    });
-
-    test('parses a parent negated option before the command', () {
-      var parser = new ArgParser();
-      parser.addFlag('verbose', defaultsTo: true);
-      var command = parser.addCommand('install');
-
-      var args = parser.parse(['--no-verbose', 'install']);
-      expect(args['verbose'], isFalse);
-      expect(args.command.name, equals('install'));
-    });
-
-    test('parses a parent negated option after the command', () {
-      var parser = new ArgParser();
-      parser.addFlag('verbose', defaultsTo: true);
-      var command = parser.addCommand('install');
-
-      var args = parser.parse(['install', '--no-verbose']);
-      expect(args['verbose'], isFalse);
-      expect(args.command.name, equals('install'));
-    });
-
-    test('parses a parent abbreviation before the command', () {
-      var parser = new ArgParser();
-      parser.addFlag('debug', abbr: 'd');
-      parser.addFlag('verbose', abbr: 'v');
-      var command = parser.addCommand('install');
-
-      var args = parser.parse(['-dv', 'install']);
-      expect(args['debug'], isTrue);
-      expect(args['verbose'], isTrue);
-      expect(args.command.name, equals('install'));
-    });
-
-    test('parses a parent abbreviation after the command', () {
-      var parser = new ArgParser();
-      parser.addFlag('debug', abbr: 'd');
-      parser.addFlag('verbose', abbr: 'v');
-      var command = parser.addCommand('install');
-
-      var args = parser.parse(['install', '-dv']);
-      expect(args['debug'], isTrue);
-      expect(args['verbose'], isTrue);
-      expect(args.command.name, equals('install'));
-    });
-
-    test('does not parse a solo command option before the command', () {
-      var parser = new ArgParser();
-      var command = parser.addCommand('install');
-      command.addOption('path', abbr: 'p');
-
-      throwsFormat(parser, ['-p', 'foo', 'install']);
-    });
-
-    test('does not parse a command option before the command', () {
-      var parser = new ArgParser();
-      var command = parser.addCommand('install');
-      command.addOption('path');
-
-      throwsFormat(parser, ['--path', 'foo', 'install']);
-    });
-
-    test('does not parse a command abbreviation before the command', () {
-      var parser = new ArgParser();
-      var command = parser.addCommand('install');
-      command.addFlag('debug', abbr: 'd');
-      command.addFlag('verbose', abbr: 'v');
-
-      throwsFormat(parser, ['-dv', 'install']);
-    });
-
-    test('assigns collapsed options to the proper command', () {
-      var parser = new ArgParser();
-      parser.addFlag('apple', abbr: 'a');
-      var command = parser.addCommand('cmd');
-      command.addFlag('banana', abbr: 'b');
-      var subcommand = command.addCommand('subcmd');
-      subcommand.addFlag('cherry', abbr: 'c');
-
-      var args = parser.parse(['cmd', 'subcmd', '-abc']);
-      expect(args['apple'], isTrue);
-      expect(args.command.name, equals('cmd'));
-      expect(args.command['banana'], isTrue);
-      expect(args.command.command.name, equals('subcmd'));
-      expect(args.command.command['cherry'], isTrue);
-    });
-
-    test('option is given to innermost command that can take it', () {
-      var parser = new ArgParser();
-      parser.addFlag('verbose');
-      var command = parser.addCommand('cmd');
-      command.addFlag('verbose');
-      var subcommand = command.addCommand('subcmd');
-
-      var args = parser.parse(['cmd', 'subcmd', '--verbose']);
-      expect(args['verbose'], isFalse);
-      expect(args.command.name, equals('cmd'));
-      expect(args.command['verbose'], isTrue);
-      expect(args.command.command.name, equals('subcmd'));
-    });
-
-    test('remaining arguments are given to the innermost command', () {
-      var parser = new ArgParser();
-      var command = parser.addCommand('cmd');
-      var subcommand = command.addCommand('subcmd');
-
-      var args = parser.parse(['cmd', 'subcmd', 'other', 'stuff']);
-      expect(args.command.name, equals('cmd'));
-      expect(args.rest, isEmpty);
-      expect(args.command.command.name, equals('subcmd'));
-      expect(args.command.rest, isEmpty);
-      expect(args.command.command.rest, equals(['other', 'stuff']));
-    });
+  test("considers a command hidden if all its subcommands are hidden", () {
+    foo.addSubcommand(new HiddenCommand());
+    expect(foo.hidden, isTrue);
   });
 }
diff --git a/pkg/args/test/utils.dart b/pkg/args/test/utils.dart
index 4586f57..9d85fb0 100644
--- a/pkg/args/test/utils.dart
+++ b/pkg/args/test/utils.dart
@@ -4,8 +4,66 @@
 
 library utils;
 
-import 'package:unittest/unittest.dart';
+import 'dart:async';
+
 import 'package:args/args.dart';
+import 'package:args/command_runner.dart';
+import 'package:unittest/unittest.dart';
+
+class CommandRunnerWithFooter extends CommandRunner {
+  final usageFooter = "Also, footer!";
+
+  CommandRunnerWithFooter(String executableName, String description)
+      : super(executableName, description);
+}
+
+class FooCommand extends Command {
+  var hasRun = false;
+
+  final name = "foo";
+  final description = "Set a value.";
+  final takesArguments = false;
+
+  void run() {
+    hasRun = true;
+  }
+}
+
+class HiddenCommand extends Command {
+  var hasRun = false;
+
+  final name = "hidden";
+  final description = "Set a value.";
+  final hidden = true;
+  final takesArguments = false;
+
+  void run() {
+    hasRun = true;
+  }
+}
+
+class AliasedCommand extends Command {
+  var hasRun = false;
+
+  final name = "aliased";
+  final description = "Set a value.";
+  final takesArguments = false;
+  final aliases = const ["alias", "als"];
+
+  void run() {
+    hasRun = true;
+  }
+}
+
+class AsyncCommand extends Command {
+  var hasRun = false;
+
+  final name = "async";
+  final description = "Set a value asynchronously.";
+  final takesArguments = false;
+
+  Future run() => new Future.value().then((_) => hasRun = true);
+}
 
 void throwsIllegalArg(function, {String reason: null}) {
   expect(function, throwsArgumentError, reason: reason);
@@ -14,3 +72,12 @@
 void throwsFormat(ArgParser parser, List<String> args) {
   expect(() => parser.parse(args), throwsFormatException);
 }
+
+Matcher throwsUsageError(message, usage) {
+  return throwsA(predicate((error) {
+    expect(error, new isInstanceOf<UsageException>());
+    expect(error.message, message);
+    expect(error.usage, usage);
+    return true;
+  }));
+}
diff --git a/pkg/code_transformers/CHANGELOG.md b/pkg/code_transformers/CHANGELOG.md
index a471614..0cb3b88 100644
--- a/pkg/code_transformers/CHANGELOG.md
+++ b/pkg/code_transformers/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.2.3+2
+
+* Added logic to discover the location of the dart SDK when the dart binary is a
+  symlink.
+
 ## 0.2.3
 
 * Added support for logging stable error messages from transformers.
diff --git a/pkg/code_transformers/lib/src/dart_sdk.dart b/pkg/code_transformers/lib/src/dart_sdk.dart
index 5dfcab8..339d457 100644
--- a/pkg/code_transformers/lib/src/dart_sdk.dart
+++ b/pkg/code_transformers/lib/src/dart_sdk.dart
@@ -5,7 +5,7 @@
 library code_transformers.src.dart_sdk;
 
 import 'dart:convert' as convert;
-import 'dart:io' show File, Platform, Process;
+import 'dart:io' show File, Link, Platform, Process;
 import 'package:path/path.dart' as path;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -23,18 +23,24 @@
 
   bool isSdkDir(String dirname) =>
       new File(path.join(dirname, 'lib', '_internal', 'libraries.dart'))
-        .existsSync();
+      .existsSync();
 
-  if (path.split(Platform.executable).length == 1) {
+  String executable = Platform.executable;
+  if (path.split(executable).length == 1) {
     // TODO(blois): make this cross-platform.
     // HACK: A single part, hope it's on the path.
-    var result = Process.runSync('which', ['dart'],
-        stdoutEncoding: convert.UTF8);
-
-    var sdkDir = path.dirname(path.dirname(result.stdout));
+    executable = Process.runSync('which', ['dart'],
+        stdoutEncoding: convert.UTF8).stdout.trim();
+    // In case Dart is symlinked (e.g. homebrew on Mac) follow symbolic links.
+    var link = new Link(executable);
+    if (link.existsSync()) {
+      executable = link.resolveSymbolicLinksSync();
+    }
+    var sdkDir = path.dirname(path.dirname(executable));
     if (isSdkDir(sdkDir)) return sdkDir;
   }
-  var dartDir = path.dirname(path.absolute(Platform.executable));
+
+  var dartDir = path.dirname(path.absolute(executable));
   // If there's a sub-dir named dart-sdk then we're most likely executing from
   // a dart enlistment build directory.
   if (isSdkDir(path.join(dartDir, 'dart-sdk'))) {
diff --git a/pkg/code_transformers/pubspec.yaml b/pkg/code_transformers/pubspec.yaml
index 9ee39cc..f56826e 100644
--- a/pkg/code_transformers/pubspec.yaml
+++ b/pkg/code_transformers/pubspec.yaml
@@ -1,5 +1,5 @@
 name: code_transformers
-version: 0.2.3+1
+version: 0.2.3+2
 author: "Dart Team <misc@dartlang.org>"
 description: Collection of utilities related to creating barback transformers.
 homepage: http://www.dartlang.org
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 64bb66c..8567fb3 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -10,7 +10,8 @@
 import 'dart2jslib.dart' as leg;
 import 'tree/tree.dart' as tree;
 import 'elements/elements.dart' as elements;
-import 'package:_internal/libraries.dart';
+import 'package:_internal/libraries.dart' hide LIBRARIES;
+import 'package:_internal/libraries.dart' as library_info show LIBRARIES;
 import 'source_file.dart';
 
 const bool forceIncrementalSupport =
@@ -152,7 +153,7 @@
   // TODO(johnniwinther): Merge better with [translateDartUri] when
   // [scanBuiltinLibrary] is removed.
   String lookupLibraryPath(String dartLibraryName) {
-    LibraryInfo info = LIBRARIES[dartLibraryName];
+    LibraryInfo info = lookupLibraryInfo(dartLibraryName);
     if (info == null) return null;
     if (!info.isDart2jsLibrary) return null;
     if (!allowedLibraryCategories.contains(info.category)) return null;
@@ -164,7 +165,7 @@
   }
 
   String lookupPatchPath(String dartLibraryName) {
-    LibraryInfo info = LIBRARIES[dartLibraryName];
+    LibraryInfo info = lookupLibraryInfo(dartLibraryName);
     if (info == null) return null;
     if (!info.isDart2jsLibrary) return null;
     String path = info.dart2jsPatchPath;
@@ -259,7 +260,7 @@
 
   Uri translateDartUri(elements.LibraryElement importingLibrary,
                        Uri resolvedUri, tree.Node node) {
-    LibraryInfo libraryInfo = LIBRARIES[resolvedUri.path];
+    LibraryInfo libraryInfo = lookupLibraryInfo(resolvedUri.path);
     String path = lookupLibraryPath(resolvedUri.path);
     if (libraryInfo != null &&
         libraryInfo.category == "Internal") {
@@ -385,4 +386,8 @@
   }
 
   fromEnvironment(String name) => environment[name];
+
+  LibraryInfo lookupLibraryInfo(String libraryName) {
+    return library_info.LIBRARIES[libraryName];
+  }
 }
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index a104843..31eb5b3 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -162,8 +162,8 @@
             value = null;
           }
         } else {
-          DartType constantType = value.value.computeType(compiler);
-          if (!constantSystem.isSubtype(compiler,
+          DartType constantType = value.value.getType(compiler.coreTypes);
+          if (!constantSystem.isSubtype(compiler.types,
                                         constantType, elementType)) {
             if (isConst) {
               compiler.reportFatalError(
@@ -485,10 +485,12 @@
             message: MessageKind.DEFERRED_COMPILE_TIME_CONSTANT);
       }
       if (Elements.isStaticOrTopLevelFunction(element)) {
+        FunctionElementX function = element;
+        function.computeType(compiler);
         return new AstConstant(
             context, send, new FunctionConstantExpression(
-                new FunctionConstantValue(element),
-                element));
+                new FunctionConstantValue(function),
+                function));
       } else if (Elements.isStaticOrTopLevelField(element)) {
         ConstantExpression result;
         if (element.isConst) {
@@ -601,7 +603,7 @@
     if (condition == null) {
       return null;
     } else if (!condition.value.isBool) {
-      DartType conditionType = condition.value.computeType(compiler);
+      DartType conditionType = condition.value.getType(compiler.coreTypes);
       if (isEvaluatingConstant) {
         compiler.reportFatalError(
             node.condition, MessageKind.NOT_ASSIGNABLE,
@@ -732,7 +734,7 @@
       }
 
       if (!firstArgument.isString) {
-        DartType type = defaultValue.computeType(compiler);
+        DartType type = defaultValue.getType(compiler.coreTypes);
         compiler.reportFatalError(
             send.arguments.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.stringClass.rawType});
@@ -741,7 +743,7 @@
 
       if (constructor == compiler.intEnvironment &&
           !(defaultValue.isNull || defaultValue.isInt)) {
-        DartType type = defaultValue.computeType(compiler);
+        DartType type = defaultValue.getType(compiler.coreTypes);
         compiler.reportFatalError(
             send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.intClass.rawType});
@@ -750,7 +752,7 @@
 
       if (constructor == compiler.boolEnvironment &&
           !(defaultValue.isNull || defaultValue.isBool)) {
-        DartType type = defaultValue.computeType(compiler);
+        DartType type = defaultValue.getType(compiler.coreTypes);
         compiler.reportFatalError(
             send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.boolClass.rawType});
@@ -759,7 +761,7 @@
 
       if (constructor == compiler.stringEnvironment &&
           !(defaultValue.isNull || defaultValue.isString)) {
-        DartType type = defaultValue.computeType(compiler);
+        DartType type = defaultValue.getType(compiler.coreTypes);
         compiler.reportFatalError(
             send.arguments.tail.head, MessageKind.NOT_ASSIGNABLE,
             {'fromType': type, 'toType': compiler.stringClass.rawType});
@@ -907,8 +909,9 @@
                             AstConstant constant) {
     if (compiler.enableTypeAssertions) {
       DartType elementType = element.type.substByContext(constructedType);
-      DartType constantType = constant.value.computeType(compiler);
-      if (!constantSystem.isSubtype(compiler, constantType, elementType)) {
+      DartType constantType = constant.value.getType(compiler.coreTypes);
+      if (!constantSystem.isSubtype(compiler.types,
+                                    constantType, elementType)) {
         compiler.withCurrentElement(constant.element, () {
           compiler.reportFatalError(
               constant.node, MessageKind.NOT_ASSIGNABLE,
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index d298547..589d987 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -629,6 +629,7 @@
   World world;
   String assembledCode;
   Types types;
+  _CompilerCoreTypes _coreTypes;
 
   final CacheStrategy cacheStrategy;
 
@@ -770,23 +771,26 @@
   /// Initialized when dart:typed_data is loaded.
   LibraryElement typedDataLibrary;
 
-  ClassElement objectClass;
-  ClassElement boolClass;
-  ClassElement numClass;
-  ClassElement intClass;
-  ClassElement doubleClass;
-  ClassElement stringClass;
-  ClassElement functionClass;
-  ClassElement nullClass;
-  ClassElement listClass;
-  ClassElement typeClass;
-  ClassElement mapClass;
-  ClassElement symbolClass;
-  ClassElement stackTraceClass;
+  ClassElement get objectClass => _coreTypes.objectClass;
+  ClassElement get boolClass => _coreTypes.boolClass;
+  ClassElement get numClass => _coreTypes.numClass;
+  ClassElement get intClass => _coreTypes.intClass;
+  ClassElement get doubleClass => _coreTypes.doubleClass;
+  ClassElement get stringClass => _coreTypes.stringClass;
+  ClassElement get functionClass => _coreTypes.functionClass;
+  ClassElement get nullClass => _coreTypes.nullClass;
+  ClassElement get listClass => _coreTypes.listClass;
+  ClassElement get typeClass => _coreTypes.typeClass;
+  ClassElement get mapClass => _coreTypes.mapClass;
+  ClassElement get symbolClass => _coreTypes.symbolClass;
+  ClassElement get stackTraceClass => _coreTypes.stackTraceClass;
+  ClassElement get futureClass => _coreTypes.futureClass;
+  ClassElement get iterableClass => _coreTypes.iterableClass;
+  ClassElement get streamClass => _coreTypes.streamClass;
+
+  CoreTypes get coreTypes => _coreTypes;
+
   ClassElement typedDataClass;
-  ClassElement futureClass;
-  ClassElement iterableClass;
-  ClassElement streamClass;
 
   /// The constant for the [proxy] variable defined in dart:core.
   ConstantValue proxyConstant;
@@ -1008,6 +1012,9 @@
       disableInlining = true;
     }
     world = new World(this);
+    // TODO(johnniwinther): Initialize core types in [initializeCoreClasses] and
+    // make its field final.
+    _coreTypes = new _CompilerCoreTypes(this);
     types = new Types(this);
     tracer = new Tracer(this, this.outputProvider);
 
@@ -1223,8 +1230,8 @@
       mirrorsUsedClass = findRequiredElement(library, 'MirrorsUsed');
     } else if (uri == DART_ASYNC) {
       deferredLibraryClass = findRequiredElement(library, 'DeferredLibrary');
-      futureClass = findRequiredElement(library, 'Future');
-      streamClass = findRequiredElement(library, 'Stream');
+      _coreTypes.futureClass = findRequiredElement(library, 'Future');
+      _coreTypes.streamClass = findRequiredElement(library, 'Stream');
     } else if (uri == DART_NATIVE_TYPED_DATA) {
       typedDataClass = findRequiredElement(library, 'NativeTypedData');
     } else if (uri == js_backend.JavaScriptBackend.DART_JS_HELPER) {
@@ -1367,20 +1374,20 @@
       }
       return result;
     }
-    objectClass = lookupCoreClass('Object');
-    boolClass = lookupCoreClass('bool');
-    numClass = lookupCoreClass('num');
-    intClass = lookupCoreClass('int');
-    doubleClass = lookupCoreClass('double');
-    stringClass = lookupCoreClass('String');
-    functionClass = lookupCoreClass('Function');
-    listClass = lookupCoreClass('List');
-    typeClass = lookupCoreClass('Type');
-    mapClass = lookupCoreClass('Map');
-    nullClass = lookupCoreClass('Null');
-    stackTraceClass = lookupCoreClass('StackTrace');
-    iterableClass = lookupCoreClass('Iterable');
-    symbolClass = lookupCoreClass('Symbol');
+    _coreTypes.objectClass = lookupCoreClass('Object');
+    _coreTypes.boolClass = lookupCoreClass('bool');
+    _coreTypes.numClass = lookupCoreClass('num');
+    _coreTypes.intClass = lookupCoreClass('int');
+    _coreTypes.doubleClass = lookupCoreClass('double');
+    _coreTypes.stringClass = lookupCoreClass('String');
+    _coreTypes.functionClass = lookupCoreClass('Function');
+    _coreTypes.listClass = lookupCoreClass('List');
+    _coreTypes.typeClass = lookupCoreClass('Type');
+    _coreTypes.mapClass = lookupCoreClass('Map');
+    _coreTypes.nullClass = lookupCoreClass('Null');
+    _coreTypes.stackTraceClass = lookupCoreClass('StackTrace');
+    _coreTypes.iterableClass = lookupCoreClass('Iterable');
+    _coreTypes.symbolClass = lookupCoreClass('Symbol');
     if (!missingCoreClasses.isEmpty) {
       internalError(coreLibrary,
           'dart:core library does not contain required classes: '
@@ -2347,3 +2354,64 @@
 
   String relativize(Uri baseUri) => '$baseUri';
 }
+
+class _CompilerCoreTypes implements CoreTypes {
+  final Compiler compiler;
+
+  ClassElementX objectClass;
+  ClassElementX boolClass;
+  ClassElementX numClass;
+  ClassElementX intClass;
+  ClassElementX doubleClass;
+  ClassElementX stringClass;
+  ClassElementX functionClass;
+  ClassElementX nullClass;
+  ClassElementX listClass;
+  ClassElementX typeClass;
+  ClassElementX mapClass;
+  ClassElementX symbolClass;
+  ClassElementX stackTraceClass;
+  ClassElementX futureClass;
+  ClassElementX iterableClass;
+  ClassElementX streamClass;
+
+  _CompilerCoreTypes(this.compiler);
+
+  @override
+  InterfaceType get objectType => objectClass.computeType(compiler);
+
+  @override
+  InterfaceType get boolType => boolClass.computeType(compiler);
+
+  @override
+  InterfaceType get doubleType => doubleClass.computeType(compiler);
+
+  @override
+  InterfaceType get functionType =>  functionClass.computeType(compiler);
+
+  @override
+  InterfaceType get intType => intClass.computeType(compiler);
+
+  @override
+  InterfaceType listType([DartType elementType = const DynamicType()]) {
+    return listClass.computeType(compiler).createInstantiation([elementType]);
+  }
+
+  @override
+  InterfaceType mapType([DartType keyType = const DynamicType(),
+                         DartType valueType = const DynamicType()]) {
+    return mapClass.computeType(compiler)
+        .createInstantiation([keyType, valueType]);
+  }
+
+  @override
+  InterfaceType get nullType => nullClass.computeType(compiler);
+
+  @override
+  InterfaceType get numType => numClass.computeType(compiler);
+
+  @override
+  InterfaceType get stringType =>  stringClass.computeType(compiler);
+}
+
+typedef void InternalErrorFunction(Spannable location, String message);
diff --git a/pkg/compiler/lib/src/constant_system.dart b/pkg/compiler/lib/src/constant_system.dart
index 36b98d7..6a1bfb0 100644
--- a/pkg/compiler/lib/src/constant_system.dart
+++ b/pkg/compiler/lib/src/constant_system.dart
@@ -62,7 +62,7 @@
 
   // We need to special case the subtype check for JavaScript constant
   // system because an int is a double at runtime.
-  bool isSubtype(Compiler compiler, DartType s, DartType t);
+  bool isSubtype(DartTypes types, DartType s, DartType t);
 
   /** Returns true if the [constant] is an integer at runtime. */
   bool isInt(ConstantValue constant);
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index 1cc239d..30fb62e 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -402,7 +402,7 @@
   bool isBool(ConstantValue constant) => constant.isBool;
   bool isNull(ConstantValue constant) => constant.isNull;
 
-  bool isSubtype(Compiler compiler, DartType s, DartType t) {
-    return compiler.types.isSubtype(s, t);
+  bool isSubtype(DartTypes types, DartType s, DartType t) {
+    return types.isSubtype(s, t);
   }
 }
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 125d668..cf6f2be 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -4,10 +4,10 @@
 
 library dart2js.constants.values;
 
+import '../core_types.dart';
 import '../dart_types.dart';
 import '../dart2jslib.dart'
-    show assertDebugMode,
-         Compiler;
+    show assertDebugMode;
 import '../elements/elements.dart'
     show ClassElement,
          Element,
@@ -17,23 +17,22 @@
 import '../types/types.dart' as ti show TypeMask;
 import '../util/util.dart' show SMI_MASK;
 
-abstract class ConstantValueVisitor<R> {
+abstract class ConstantValueVisitor<R, A> {
   const ConstantValueVisitor();
 
-  R visitFunction(FunctionConstantValue constant);
-  R visitNull(NullConstantValue constant);
-  R visitInt(IntConstantValue constant);
-  R visitDouble(DoubleConstantValue constant);
-  R visitTrue(TrueConstantValue constant);
-  R visitFalse(FalseConstantValue constant);
-  R visitString(StringConstantValue constant);
-  R visitList(ListConstantValue constant);
-  R visitMap(MapConstantValue constant);
-  R visitConstructed(ConstructedConstantValue constant);
-  R visitType(TypeConstantValue constant);
-  R visitInterceptor(InterceptorConstantValue constant);
-  R visitDummy(DummyConstantValue constant);
-  R visitDeferred(DeferredConstantValue constant);
+  R visitFunction(FunctionConstantValue constant, A arg);
+  R visitNull(NullConstantValue constant, A arg);
+  R visitInt(IntConstantValue constant, A arg);
+  R visitDouble(DoubleConstantValue constant, A arg);
+  R visitBool(BoolConstantValue constant, A arg);
+  R visitString(StringConstantValue constant, A arg);
+  R visitList(ListConstantValue constant, A arg);
+  R visitMap(MapConstantValue constant, A arg);
+  R visitConstructed(ConstructedConstantValue constant, A arg);
+  R visitType(TypeConstantValue constant, A arg);
+  R visitInterceptor(InterceptorConstantValue constant, A arg);
+  R visitDummy(DummyConstantValue constant, A arg);
+  R visitDeferred(DeferredConstantValue constant, A arg);
 }
 
 abstract class ConstantValue {
@@ -65,13 +64,11 @@
   bool get isOne => false;
 
   // TODO(johnniwinther): Replace with a 'type' getter.
-  DartType computeType(Compiler compiler);
-
-  ti.TypeMask computeMask(Compiler compiler);
+  DartType getType(CoreTypes types);
 
   List<ConstantValue> getDependencies();
 
-  accept(ConstantValueVisitor visitor);
+  accept(ConstantValueVisitor visitor, arg);
 
   /// The value of this constant in Dart syntax, if possible.
   ///
@@ -94,9 +91,11 @@
 }
 
 class FunctionConstantValue extends ConstantValue {
-  Element element;
+  FunctionElement element;
 
-  FunctionConstantValue(this.element);
+  FunctionConstantValue(this.element) {
+    assert(element.type != null);
+  }
 
   bool get isFunction => true;
 
@@ -111,16 +110,11 @@
     return new DartString.literal(element.name);
   }
 
-  // TODO(johnniwinther): remove computeType.
-  DartType computeType(Compiler compiler) => element.computeType(compiler);
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.functionType;
-  }
+  DartType getType(CoreTypes types) => element.type;
 
   int get hashCode => (17 * element.hashCode) & 0x7fffffff;
 
-  accept(ConstantValueVisitor visitor) => visitor.visitFunction(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitFunction(this, arg);
 
   String unparse() {
     if (element.isStatic) {
@@ -172,20 +166,14 @@
 
   get primitiveValue => null;
 
-  DartType computeType(Compiler compiler) {
-    return compiler.nullClass.computeType(compiler);
-  }
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.nullType;
-  }
+  DartType getType(CoreTypes types) => types.nullType;
 
   // The magic constant has no meaning. It is just a random value.
   int get hashCode => 785965825;
 
   DartString toDartString() => const LiteralDartString("null");
 
-  accept(ConstantValueVisitor visitor) => visitor.visitNull(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitNull(this, arg);
 
   String toStructuredString() => 'NullConstant';
 }
@@ -234,16 +222,7 @@
 
   bool get isOne => primitiveValue == 1;
 
-  DartType computeType(Compiler compiler) {
-    return compiler.intClass.rawType;
-  }
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    if (isUInt31()) return compiler.typesTask.uint31Type;
-    if (isUInt32()) return compiler.typesTask.uint32Type;
-    if (isPositive()) return compiler.typesTask.positiveIntType;
-    return compiler.typesTask.intType;
-  }
+  DartType getType(CoreTypes types) => types.intType;
 
   // We have to override the equality operator so that ints and doubles are
   // treated as separate constants.
@@ -261,7 +240,7 @@
     return new DartString.literal(primitiveValue.toString());
   }
 
-  accept(ConstantValueVisitor visitor) => visitor.visitInt(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitInt(this, arg);
 
   String toStructuredString() => 'IntConstant(${unparse()})';
 }
@@ -298,21 +277,7 @@
 
   bool get isOne => primitiveValue == 1.0;
 
-  DartType computeType(Compiler compiler) {
-    return compiler.doubleClass.rawType;
-  }
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    // We have to distinguish -0.0 from 0, but for all practical purposes
-    // -0.0 is an integer.
-    // TODO(17235): this kind of special casing should only happen in the
-    // backend.
-    if (isMinusZero && compiler.backend.constantSystem.isInt(this)) {
-      return compiler.typesTask.uint31Type;
-    }
-    assert(!compiler.backend.constantSystem.isInt(this));
-    return compiler.typesTask.doubleType;
-  }
+  DartType getType(CoreTypes types) => types.doubleType;
 
   bool operator ==(var other) {
     if (other is !DoubleConstantValue) return false;
@@ -333,7 +298,7 @@
     return new DartString.literal(primitiveValue.toString());
   }
 
-  accept(ConstantValueVisitor visitor) => visitor.visitDouble(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitDouble(this, arg);
 
   String toStructuredString() => 'DoubleConstant(${unparse()})';
 }
@@ -347,16 +312,12 @@
 
   bool get isBool => true;
 
-  DartType computeType(Compiler compiler) {
-    return compiler.boolClass.rawType;
-  }
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.boolType;
-  }
+  DartType getType(CoreTypes types) => types.boolType;
 
   BoolConstantValue negate();
 
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitBool(this, arg);
+
   String toStructuredString() => 'BoolConstant(${unparse()})';
 }
 
@@ -378,8 +339,6 @@
   int get hashCode => 499;
 
   DartString toDartString() => const LiteralDartString("true");
-
-  accept(ConstantValueVisitor visitor) => visitor.visitTrue(this);
 }
 
 class FalseConstantValue extends BoolConstantValue {
@@ -400,8 +359,6 @@
   int get hashCode => 536555975;
 
   DartString toDartString() => const LiteralDartString("false");
-
-  accept(ConstantValueVisitor visitor) => visitor.visitFalse(this);
 }
 
 class StringConstantValue extends PrimitiveConstantValue {
@@ -418,13 +375,7 @@
 
   bool get isString => true;
 
-  DartType computeType(Compiler compiler) {
-    return compiler.stringClass.rawType;
-  }
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.stringType;
-  }
+  DartType getType(CoreTypes types) => types.stringType;
 
   bool operator ==(var other) {
     if (other is !StringConstantValue) return false;
@@ -437,7 +388,7 @@
 
   int get length => primitiveValue.length;
 
-  accept(ConstantValueVisitor visitor) => visitor.visitString(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitString(this, arg);
 
   // TODO(johnniwinther): Ensure correct escaping.
   String unparse() => '"${primitiveValue.slowToString()}"';
@@ -446,13 +397,13 @@
 }
 
 abstract class ObjectConstantValue extends ConstantValue {
-  final InterfaceType  type;
+  final InterfaceType type;
 
   ObjectConstantValue(this.type);
 
   bool get isObject => true;
 
-  DartType computeType(Compiler compiler) => type;
+  DartType getType(CoreTypes types) => type;
 
   void _unparseTypeArguments(StringBuffer sb) {
     if (!type.treatAsRaw) {
@@ -476,15 +427,11 @@
            representedType == other.representedType;
   }
 
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.typeType;
-  }
-
   int get hashCode => representedType.hashCode * 13;
 
   List<ConstantValue> getDependencies() => const <ConstantValue>[];
 
-  accept(ConstantValueVisitor visitor) => visitor.visitType(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitType(this, arg);
 
   String unparse() => '$representedType';
 
@@ -528,11 +475,7 @@
 
   int get length => entries.length;
 
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.constListType;
-  }
-
-  accept(ConstantValueVisitor visitor) => visitor.visitList(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitList(this, arg);
 
   String unparse() {
     StringBuffer sb = new StringBuffer();
@@ -590,10 +533,6 @@
     return hash;
   }
 
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.constMapType;
-  }
-
   bool operator ==(var other) {
     if (other is !MapConstantValue) return false;
     MapConstantValue otherMap = other;
@@ -616,7 +555,7 @@
 
   int get length => keys.length;
 
-  accept(ConstantValueVisitor visitor) => visitor.visitMap(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitMap(this, arg);
 
   String unparse() {
     StringBuffer sb = new StringBuffer();
@@ -664,14 +603,12 @@
 
   List<ConstantValue> getDependencies() => const <ConstantValue>[];
 
-  accept(ConstantValueVisitor visitor) => visitor.visitInterceptor(this);
-
-  DartType computeType(Compiler compiler) => const DynamicType();
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    return compiler.typesTask.nonNullType;
+  accept(ConstantValueVisitor visitor, arg) {
+    return visitor.visitInterceptor(this, arg);
   }
 
+  DartType getType(CoreTypes types) => const DynamicType();
+
   String unparse() {
     return 'interceptor($dispatchedType)';
   }
@@ -681,6 +618,7 @@
   }
 }
 
+// TODO(johnniwinther): Remove this class.
 class DummyConstantValue extends ConstantValue {
   final ti.TypeMask typeMask;
 
@@ -697,11 +635,9 @@
 
   List<ConstantValue> getDependencies() => const <ConstantValue>[];
 
-  accept(ConstantValueVisitor visitor) => visitor.visitDummy(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitDummy(this, arg);
 
-  DartType computeType(Compiler compiler) => const DynamicType();
-
-  ti.TypeMask computeMask(Compiler compiler) => typeMask;
+  DartType getType(CoreTypes types) => const DynamicType();
 
   String unparse() => 'dummy($typeMask)';
 
@@ -745,15 +681,10 @@
 
   List<ConstantValue> getDependencies() => fields;
 
-  ti.TypeMask computeMask(Compiler compiler) {
-    if (compiler.backend.isInterceptorClass(type.element)) {
-      return compiler.typesTask.nonNullType;
-    }
-    return new ti.TypeMask.nonNullExact(type.element, compiler.world);
+  accept(ConstantValueVisitor visitor, arg) {
+    return visitor.visitConstructed(this, arg);
   }
 
-  accept(ConstantValueVisitor visitor) => visitor.visitConstructed(this);
-
   Map<Element, ConstantValue> get fieldElements {
     // TODO(ahe): Refactor constant system to store this information directly.
     ClassElement classElement = type.element;
@@ -820,13 +751,9 @@
 
   List<ConstantValue> getDependencies() => <ConstantValue>[referenced];
 
-  accept(ConstantValueVisitor visitor) => visitor.visitDeferred(this);
+  accept(ConstantValueVisitor visitor, arg) => visitor.visitDeferred(this, arg);
 
-  DartType computeType(Compiler compiler) => referenced.computeType(compiler);
-
-  ti.TypeMask computeMask(Compiler compiler) {
-    return referenced.computeMask(compiler);
-  }
+  DartType getType(CoreTypes types) => referenced.getType(types);
 
   String unparse() => 'deferred(${referenced.unparse()})';
 
diff --git a/pkg/compiler/lib/src/core_types.dart b/pkg/compiler/lib/src/core_types.dart
new file mode 100644
index 0000000..291978d
--- /dev/null
+++ b/pkg/compiler/lib/src/core_types.dart
@@ -0,0 +1,43 @@
+// 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 dart2js.type_system;
+
+import 'dart_types.dart';
+
+/// The core types in Dart.
+abstract class CoreTypes {
+  /// The `Object` type defined in 'dart:core'.
+  InterfaceType get objectType;
+
+  /// The `bool` type defined in 'dart:core'.
+  InterfaceType get boolType;
+
+  /// The `bool` type defined in 'dart:core'.
+  InterfaceType get numType;
+
+  /// The `int` type defined in 'dart:core'.
+  InterfaceType get intType;
+
+  /// The `double` type defined in 'dart:core'.
+  InterfaceType get doubleType;
+
+  /// The `String` type defined in 'dart:core'.
+  InterfaceType get stringType;
+
+  /// The `Function` type defined in 'dart:core'.
+  InterfaceType get functionType;
+
+  /// The `Null` type defined in 'dart:core'.
+  InterfaceType get nullType;
+
+  /// Returns an instance of the `List` type defined in 'dart:core' with
+  /// [elementType] as its type argument.
+  InterfaceType listType([DartType elementType = const DynamicType()]);
+
+  /// Returns an instance of the `Map` type defined in 'dart:core' with
+  /// [keyType] and [valueType] as its type arguments.
+  InterfaceType mapType([DartType keyType = const DynamicType(),
+                         DartType valueType = const DynamicType()]);
+}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index 73d4afa..76c762b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -6,7 +6,6 @@
 
 import '../constants/expressions.dart';
 import '../constants/values.dart' show PrimitiveConstantValue;
-import '../dart_backend/dart_backend.dart' show DartBackend;
 import '../dart_types.dart';
 import '../dart2jslib.dart';
 import '../elements/elements.dart';
@@ -580,19 +579,37 @@
     _current = null;
   }
 
+  ir.SuperInitializer makeSuperInitializer(ConstructorElement target,
+                                           List<ir.RunnableBody> arguments,
+                                           Selector selector) {
+    return new ir.SuperInitializer(target, arguments, selector);
+  }
+
+  ir.FieldInitializer makeFieldInitializer(FieldElement element,
+                                           ir.RunnableBody body) {
+    return new ir.FieldInitializer(element, body);
+  }
+
   /// Create a [ir.FieldDefinition] for the current [Element] using [_root] as
   /// the body using [initializer] as the initial value.
   ir.FieldDefinition makeFieldDefinition(ir.Primitive initializer) {
     if (initializer == null) {
       return new ir.FieldDefinition.withoutInitializer(state.currentElement);
     } else {
-      buildReturn(initializer);
-      return new ir.FieldDefinition(state.currentElement,
-                                    state.returnContinuation,
-                                    _root);
+      ir.RunnableBody body = makeRunnableBody(initializer);
+      return new ir.FieldDefinition(state.currentElement, body);
     }
   }
 
+  ir.RunnableBody makeRunnableBody([ir.Primitive value]) {
+    if (value == null) {
+      _ensureReturn();
+    } else {
+      buildReturn(value);
+    }
+    return new ir.RunnableBody(_root, state.returnContinuation);
+  }
+
   /// Create a [ir.FunctionDefinition] for [element] using [_root] as the body.
   ///
   /// Parameters must be created before the construction of the body using
@@ -609,13 +626,32 @@
       return new ir.FunctionDefinition.abstract(
                 element, state.functionParameters, defaults);
     } else {
-      _ensureReturn();
+      ir.RunnableBody body = makeRunnableBody();
       return new ir.FunctionDefinition(
-          element, state.returnContinuation, state.functionParameters, _root,
+          element, state.functionParameters, body,
           state.localConstants, defaults, closure.getClosureList(element));
     }
   }
 
+  ir.ConstructorDefinition makeConstructorDefinition(
+      List<ConstantExpression> defaults, List<ir.Initializer> initializers) {
+    FunctionElement element = state.currentElement;
+    if (element.isExternal) {
+      assert(invariant(element, _root == null,
+          message: "Non-empty body for external constructor $element: $_root"));
+      assert(invariant(element, state.localConstants.isEmpty,
+          message: "Local constants for external constructor $element: "
+                   "${state.localConstants}"));
+      return new ir.ConstructorDefinition.abstract(
+                element, state.functionParameters, defaults);
+    }
+    ir.RunnableBody body = makeRunnableBody();
+    return new ir.ConstructorDefinition(
+        element, state.functionParameters, body, initializers,
+        state.localConstants, defaults,
+        closure.getClosureList(element));
+  }
+
   /// Create a super invocation where the method name and the argument structure
   /// are defined by [selector] and the argument values are defined by
   /// [arguments].
@@ -695,6 +731,7 @@
   /// defined by [selector].
   ir.Primitive buildStaticGet(Element element, Selector selector) {
     assert(selector.isGetter);
+    // TODO(karlklose,sigurdm): build different nodes for getters.
     return _buildInvokeStatic(element, selector, const <ir.Primitive>[]);
   }
 
@@ -704,6 +741,7 @@
                               Selector selector,
                               ir.Primitive value) {
     assert(selector.isSetter);
+    // TODO(karlklose,sigurdm): build different nodes for setters.
     _buildInvokeStatic(element, selector, <ir.Primitive>[value]);
     return value;
   }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
index e800a5c..56433a1 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_visitor.dart
@@ -66,7 +66,9 @@
       assert(invariant(element, !element.isNative));
 
       // TODO(kmillikin,sigurdm): Support constructors.
-      if (element is ConstructorElement) return false;
+      if (element is ConstructorElement && !element.isGenerativeConstructor) {
+        return false;
+      }
 
     } else if (element is! FieldElement) {
       compiler.internalError(element, "Unexpected elementtype $element");
@@ -187,9 +189,91 @@
       defaults.add(getConstantForVariable(element));
     });
 
-    visit(node.body);
+    List<ir.Initializer> initializers;
+    if (element.isGenerativeConstructor) {
+      initializers = buildConstructorInitializers(node, element);
+      visit(node.body);
+      return irBuilder.makeConstructorDefinition(defaults, initializers);
+    } else {
+      visit(node.body);
+      return irBuilder.makeFunctionDefinition(defaults);
+    }
+  }
 
-    return irBuilder.makeFunctionDefinition(defaults);
+  List<ir.Initializer> buildConstructorInitializers(
+      ast.FunctionExpression function, ConstructorElement element) {
+    List<ir.Initializer> result = <ir.Initializer>[];
+    FunctionSignature signature = element.functionSignature;
+
+    void tryAddInitializingFormal(ParameterElement parameterElement) {
+      if (parameterElement.isInitializingFormal) {
+        InitializingFormalElement initializingFormal = parameterElement;
+        withBuilder(new IrBuilder.delimited(irBuilder), () {
+          ir.Primitive value = irBuilder.buildLocalGet(parameterElement);
+          result.add(irBuilder.makeFieldInitializer(
+              initializingFormal.fieldElement,
+              irBuilder.makeRunnableBody(value)));
+        });
+      }
+    }
+
+    // TODO(sigurdm): Preserve initializing formals as initializing formals.
+    signature.orderedForEachParameter(tryAddInitializingFormal);
+
+    if (function.initializers == null) return result;
+    bool explicitSuperInitializer = false;
+    for(ast.Node initializer in function.initializers) {
+      if (initializer is ast.SendSet) {
+        // Field initializer.
+        FieldElement field = elements[initializer];
+        withBuilder(new IrBuilder.delimited(irBuilder), () {
+          ir.Primitive value = visit(initializer.arguments.head);
+          ir.RunnableBody body = irBuilder.makeRunnableBody(value);
+          result.add(irBuilder.makeFieldInitializer(field, body));
+        });
+      } else if (initializer is ast.Send) {
+        // Super or this initializer.
+        if (ast.Initializers.isConstructorRedirect(initializer)) {
+          giveup(initializer, "constructor redirect (this) initializer");
+        }
+        ConstructorElement constructor = elements[initializer].implementation;
+        Selector selector = elements.getSelector(initializer);
+        List<ir.RunnableBody> arguments =
+            initializer.arguments.mapToList((ast.Node argument) {
+          return withBuilder(new IrBuilder.delimited(irBuilder), () {
+            ir.Primitive value = visit(argument);
+            return irBuilder.makeRunnableBody(value);
+          });
+        });
+        result.add(irBuilder.makeSuperInitializer(constructor,
+                                                  arguments,
+                                                  selector));
+        explicitSuperInitializer = true;
+      } else {
+        compiler.internalError(initializer,
+                               "Unexpected initializer type $initializer");
+      }
+
+    }
+    if (!explicitSuperInitializer) {
+      // No super initializer found. Try to find the default constructor if
+      // the class is not Object.
+      ClassElement enclosingClass = element.enclosingClass;
+      if (!enclosingClass.isObject) {
+        ClassElement superClass = enclosingClass.superclass;
+        Selector selector =
+            new Selector.callDefaultConstructor(enclosingClass.library);
+        FunctionElement target = superClass.lookupConstructor(selector);
+        if (target == null) {
+          compiler.internalError(superClass,
+              "No default constructor available.");
+        }
+        result.add(irBuilder.makeSuperInitializer(target,
+                                                  <ir.RunnableBody>[],
+                                                  selector));
+      }
+    }
+    return result;
   }
 
   ir.FunctionDefinition buildFunction(FunctionElement element) {
@@ -897,6 +981,7 @@
   DetectClosureVariables(this.elements);
 
   FunctionElement currentFunction;
+  bool insideInitializer = false;
   Set<Local> usedFromClosure = new Set<Local>();
   Set<FunctionElement> recursiveFunctions = new Set<FunctionElement>();
 
@@ -912,7 +997,7 @@
     node.visitChildren(this);
   }
 
-  visitSend(ast.Send node) {
+  void handleSend(ast.Send node) {
     Element element = elements[node];
     if (Elements.isLocal(element) &&
         !element.isConst &&
@@ -920,12 +1005,40 @@
       LocalElement local = element;
       markAsClosureVariable(local);
     }
+  }
+
+  visitSend(ast.Send node) {
+    handleSend(node);
+    node.visitChildren(this);
+  }
+
+  visitSendSet(ast.SendSet node) {
+    handleSend(node);
+    Element element = elements[node];
+    // Initializers in an initializer-list can communicate via parameters.
+    // If a parameter is stored in an initializer list we box it.
+    if (insideInitializer &&
+        Elements.isLocal(element) &&
+        element.isParameter) {
+      LocalElement local = element;
+      // TODO(sigurdm): Fix this.
+      // Though these variables do not outlive the activation of the function,
+      // they still need to be boxed.  As a simplification, we treat them as if
+      // they are captured by a closure (i.e., they do outlive the activation of
+      // the function).
+      markAsClosureVariable(local);
+    }
     node.visitChildren(this);
   }
 
   visitFunctionExpression(ast.FunctionExpression node) {
     FunctionElement oldFunction = currentFunction;
     currentFunction = elements[node];
+    if (node.initializers != null) {
+      insideInitializer = true;
+      visit(node.initializers);
+      insideInitializer = false;
+    }
     visit(node.body);
     currentFunction = oldFunction;
   }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
index b4f111a..07bc61a 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes.dart
@@ -193,12 +193,18 @@
   final List<Reference<Primitive>> arguments;
 
   InvokeMethod(Primitive receiver,
-               this.selector,
+               Selector selector,
                Continuation cont,
                List<Primitive> args)
-      : receiver = new Reference<Primitive>(receiver),
-        continuation = new Reference<Continuation>(cont),
-        arguments = _referenceList(args) {
+      : this.internal(new Reference<Primitive>(receiver),
+                      selector,
+                      new Reference<Continuation>(cont),
+                      _referenceList(args));
+
+  InvokeMethod.internal(this.receiver,
+                        this.selector,
+                        this.continuation,
+                        this.arguments) {
     assert(selector != null);
     assert(selector.kind == SelectorKind.CALL ||
            selector.kind == SelectorKind.OPERATOR ||
@@ -208,6 +214,8 @@
            (selector.kind == SelectorKind.INDEX && arguments.length == 2));
   }
 
+  bool get isIntercepted => receiver.definition is Interceptor;
+
   accept(Visitor visitor) => visitor.visitInvokeMethod(this);
 }
 
@@ -446,7 +454,13 @@
   accept(Visitor visitor) => visitor.visitBranch(this);
 }
 
-class Identical extends Primitive {
+/// Marker interface for nodes that are only handled in the JavaScript backend.
+///
+/// These nodes are generated by the unsugar step and need special translation
+/// to the Tree IR, which is implemented in JsTreeBuilder.
+abstract class JsSpecificNode {}
+
+class Identical extends Primitive implements JsSpecificNode {
   final Reference<Primitive> left;
   final Reference<Primitive> right;
   Identical(Primitive left, Primitive right)
@@ -455,6 +469,14 @@
   accept(Visitor visitor) => visitor.visitIdentical(this);
 }
 
+class Interceptor extends Primitive implements JsSpecificNode {
+  final Reference<Primitive> input;
+  final Set<ClassElement> interceptedClasses;
+  Interceptor(Primitive input, this.interceptedClasses)
+      : this.input = new Reference<Primitive>(input);
+  accept(Visitor visitor) => visitor.visitInterceptor(this);
+}
+
 class Constant extends Primitive {
   final ConstantExpression expression;
 
@@ -549,7 +571,7 @@
 }
 
 abstract class ExecutableDefinition implements Node {
-  Expression get body;
+  RunnableBody get body;
 
   applyPass(Pass pass);
 }
@@ -557,16 +579,14 @@
 // This is basically a function definition with an empty parameter list and a
 // field element instead of a function element and no const declarations, and
 // never a getter or setter, though that's less important.
-class FieldDefinition extends Node
-    implements InteriorNode, ExecutableDefinition {
+class FieldDefinition extends Node implements ExecutableDefinition {
   final FieldElement element;
-  final Continuation returnContinuation;
-  Expression body;
+  RunnableBody body;
 
-  FieldDefinition(this.element, this.returnContinuation, this.body);
+  FieldDefinition(this.element, this.body);
 
   FieldDefinition.withoutInitializer(this.element)
-      : this.returnContinuation = null;
+      : this.body = null;
 
   accept(Visitor visitor) => visitor.visitFieldDefinition(this);
   applyPass(Pass pass) => pass.rewriteFieldDefinition(this);
@@ -602,15 +622,22 @@
   accept(Visitor v) => v.visitClosureVariable(this);
 }
 
+class RunnableBody implements InteriorNode {
+  Expression body;
+  final Continuation returnContinuation;
+  Node parent;
+  RunnableBody(this.body, this.returnContinuation);
+  accept(Visitor visitor) => visitor.visitRunnableBody(this);
+}
+
 /// A function definition, consisting of parameters and a body.  The parameters
 /// include a distinguished continuation parameter.
 class FunctionDefinition extends Node
-    implements InteriorNode, ExecutableDefinition {
+    implements ExecutableDefinition {
   final FunctionElement element;
-  final Continuation returnContinuation;
   /// Mixed list of [Parameter]s and [ClosureVariable]s.
   final List<Definition> parameters;
-  Expression body;
+  final RunnableBody body;
   final List<ConstDeclaration> localConstants;
 
   /// Values for optional parameters.
@@ -619,16 +646,19 @@
   /// Closure variables declared by this function.
   final List<ClosureVariable> closureVariables;
 
-  FunctionDefinition(this.element, this.returnContinuation,
-      this.parameters, this.body, this.localConstants,
-      this.defaultParameterValues, this.closureVariables);
+  FunctionDefinition(this.element,
+      this.parameters,
+      this.body,
+      this.localConstants,
+      this.defaultParameterValues,
+      this.closureVariables);
 
   FunctionDefinition.abstract(this.element,
                               this.parameters,
                               this.defaultParameterValues)
-      : this.returnContinuation = null,
-        this.localConstants = const <ConstDeclaration>[],
-        this.closureVariables = const <ClosureVariable>[];
+      : body = null,
+        localConstants = const <ConstDeclaration>[],
+        closureVariables = const <ClosureVariable>[];
 
   accept(Visitor visitor) => visitor.visitFunctionDefinition(this);
   applyPass(Pass pass) => pass.rewriteFunctionDefinition(this);
@@ -640,6 +670,52 @@
   bool get isAbstract => body == null;
 }
 
+abstract class Initializer extends Node {}
+
+class FieldInitializer implements Initializer {
+  final FieldElement element;
+  final RunnableBody body;
+  Node parent;
+
+  FieldInitializer(this.element, this.body);
+  accept(Visitor visitor) => visitor.visitFieldInitializer(this);
+}
+
+class SuperInitializer implements Initializer {
+  final ConstructorElement target;
+  final List<RunnableBody> arguments;
+  final Selector selector;
+  Node parent;
+  SuperInitializer(this.target, this.arguments, this.selector);
+  accept(Visitor visitor) => visitor.visitSuperInitializer(this);
+}
+
+class ConstructorDefinition extends FunctionDefinition {
+  final List<Initializer> initializers;
+
+  ConstructorDefinition(ConstructorElement element,
+                        List<Definition> parameters,
+                        RunnableBody body,
+                        this.initializers,
+                        List<ConstDeclaration> localConstants,
+                        List<ConstantExpression> defaultParameterValues,
+                        List<ClosureVariable> closureVariables)
+      : super(element, parameters, body, localConstants,
+              defaultParameterValues, closureVariables);
+
+  // 'Abstract' here means "has no body" and is used to represent external
+  // constructors.
+  ConstructorDefinition.abstract(
+      ConstructorElement element,
+      List<Definition> parameters,
+      List<ConstantExpression> defaultParameterValues)
+      : initializers = null,
+        super.abstract(element, parameters, defaultParameterValues);
+
+  accept(Visitor visitor) => visitor.visitConstructorDefinition(this);
+  applyPass(Pass pass) => pass.rewriteConstructorDefinition(this);
+}
+
 List<Reference<Primitive>> _referenceList(Iterable<Primitive> definitions) {
   return definitions.map((e) => new Reference<Primitive>(e)).toList();
 }
@@ -654,10 +730,19 @@
   T visitDefinition(Definition node) => visitNode(node);
   T visitPrimitive(Primitive node) => visitDefinition(node);
   T visitCondition(Condition node) => visitNode(node);
+  T visitRunnableBody(RunnableBody node) => visitNode(node);
 
   // Concrete classes.
   T visitFieldDefinition(FieldDefinition node) => visitNode(node);
   T visitFunctionDefinition(FunctionDefinition node) => visitNode(node);
+  T visitConstructorDefinition(ConstructorDefinition node) {
+    return visitFunctionDefinition(node);
+  }
+
+  // Initializers
+  T visitInitializer(Initializer node) => visitNode(node);
+  T visitFieldInitializer(FieldInitializer node) => visitInitializer(node);
+  T visitSuperInitializer(SuperInitializer node) => visitInitializer(node);
 
   // Expressions.
   T visitLetPrim(LetPrim node) => visitExpression(node);
@@ -690,6 +775,7 @@
 
   // JavaScript specific nodes.
   T visitIdentical(Identical node) => visitPrimitive(node);
+  T visitInterceptor(Interceptor node) => visitPrimitive(node);
 }
 
 /// Recursively visits the entire CPS term, and calls abstract `process*`
@@ -702,11 +788,17 @@
   // with the appropriate visits in this class (for example, visitLetCont),
   // while leaving other nodes for subclasses (i.e., visitLiteralList).
   visitNode(Node node) {
-    throw "RecursiveVisitor is stale, add missing visit overrides";
+    throw "$this is stale, add missing visit override for $node";
   }
 
   processReference(Reference ref) {}
 
+  processRunnableBody(RunnableBody node) {}
+  visitRunnableBody(RunnableBody node) {
+    processRunnableBody(node);
+    visit(node.body);
+  }
+
   processFieldDefinition(FieldDefinition node) {}
   visitFieldDefinition(FieldDefinition node) {
     processFieldDefinition(node);
@@ -724,6 +816,27 @@
     }
   }
 
+  processConstructorDefinition(ConstructorDefinition node) {}
+  visitConstructorDefinition(ConstructorDefinition node) {
+    processConstructorDefinition(node);
+    node.parameters.forEach(visit);
+    node.initializers.forEach(visit);
+    visit(node.body);
+  }
+
+  processFieldInitializer(FieldInitializer node) {}
+  visitFieldInitializer(FieldInitializer node) {
+    processFieldInitializer(node);
+    visit(node.body.body);
+  }
+
+  processSuperInitializer(SuperInitializer node) {}
+  visitSuperInitializer(SuperInitializer node) {
+    processSuperInitializer(node);
+    node.arguments.forEach(
+        (RunnableBody argument) => visit(argument.body));
+  }
+
   // Expressions.
 
   processLetPrim(LetPrim node) {}
@@ -879,6 +992,12 @@
     processReference(node.left);
     processReference(node.right);
   }
+
+  processInterceptor(Interceptor node) {}
+  visitInterceptor(Interceptor node) {
+    processInterceptor(node);
+    processReference(node.input);
+  }
 }
 
 /// Keeps track of currently unused register indices.
@@ -945,6 +1064,10 @@
     }
   }
 
+  void visitRunnableBody(RunnableBody node) {
+    visit(node.body);
+  }
+
   void visitFunctionDefinition(FunctionDefinition node) {
     if (!node.isAbstract) {
       visit(node.body);
@@ -957,6 +1080,27 @@
     }
   }
 
+  void visitConstructorDefinition(ConstructorDefinition node) {
+    if (!node.isAbstract) {
+      node.initializers.forEach(visit);
+      visit(node.body);
+    }
+    // Assign indices to unused parameters.
+    for (Definition param in node.parameters) {
+      if (param is Primitive) {
+        allocate(param);
+      }
+    }
+  }
+
+  void visitFieldInitializer(FieldInitializer node) {
+    visit(node.body.body);
+  }
+
+  void visitSuperInitializer(SuperInitializer node) {
+    node.arguments.forEach((RunnableBody argument) => visit(argument.body));
+  }
+
   void visitLetPrim(LetPrim node) {
     visit(node.body);
     release(node.primitive);
@@ -1063,5 +1207,8 @@
     visitReference(node.left);
     visitReference(node.right);
   }
-}
 
+  void visitInterceptor(Interceptor node) {
+    visitReference(node.input);
+  }
+}
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
index d7ec6a95..7887a74 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_nodes_sexpr.dart
@@ -4,6 +4,7 @@
 
 library dart2js.ir_nodes_sexpr;
 
+import '../constants/values.dart';
 import '../util/util.dart';
 import 'cps_ir_nodes.dart';
 
@@ -15,16 +16,22 @@
 class SExpressionStringifier extends Visitor<String> with Indentation {
   final _Namer namer = new _Namer();
 
-  String newValueName(Node node) => namer.defineValueName(node);
-  String newContinuationName(Node node) => namer.defineContinuationName(node);
-  final Decorator decorator;
+  String newValueName(Primitive node) => namer.nameValue(node);
+  String newContinuationName(Continuation node) => namer.nameContinuation(node);
+  Decorator decorator;
 
-  SExpressionStringifier([this.decorator]);
+  SExpressionStringifier([this.decorator]) {
+    if (this.decorator == null) {
+      this.decorator = (Node node, String s) => s;
+    }
+  }
 
-  String access(Reference<Definition> r) => namer.getName(r.definition);
+  String access(Reference<Definition> r) {
+    return decorator(r.definition, namer.getName(r.definition));
+  }
 
   String visitParameter(Parameter node) {
-    return namer.useElementName(node);
+    return namer.nameParameter(node);
   }
 
   String visitClosureVariable(ClosureVariable node) {
@@ -35,26 +42,25 @@
   /// calls must go through this method.
   String visit(Node node) {
     String s = super.visit(node);
-    return (decorator == null) ? s : decorator(node, s);
+    return decorator(node, s);
   }
 
   String visitFunctionDefinition(FunctionDefinition node) {
     String name = node.element.name;
-    namer.useReturnName(node.returnContinuation);
-    String closureVariables = node.closureVariables.isEmpty
-        ? ''
-        : '{${node.closureVariables.map(namer.defineClosureName).join(' ')}} ';
+    namer.setReturnContinuation(node.body.returnContinuation);
+    String closureVariables =
+        node.closureVariables.map(namer.nameClosureVariable).join(' ');
     String parameters = node.parameters.map(visit).join(' ');
-    String body = indentBlock(() => visit(node.body));
-    return '$indentation(FunctionDefinition $name $closureVariables'
-           '($parameters return)\n$body)';
+    String body = indentBlock(() => visit(node.body.body));
+    return '$indentation(FunctionDefinition $name ($parameters) return'
+        ' ($closureVariables)\n$body)';
   }
 
   String visitFieldDefinition(FieldDefinition node) {
     String name = node.element.name;
     if (node.hasInitializer) {
-      namer.useReturnName(node.returnContinuation);
-      String body = indentBlock(() => visit(node.body));
+      namer.setReturnContinuation(node.body.returnContinuation);
+      String body = indentBlock(() => visit(node.body.body));
       return '$indentation(FieldDefinition $name (return)\n'
              '$body)';
     } else {
@@ -75,7 +81,7 @@
     // should recurse to [visit].  Currently we can't do that, because the
     // unstringifier_test produces [LetConts] with dummy arguments on them.
     String parameters = node.continuation.parameters
-        .map((p) => ' ${newValueName(p)}')
+        .map((p) => ' ${decorator(p, newValueName(p))}')
         .join('');
     String contBody = indentBlock(() => visit(node.continuation.body));
     String body = visit(node.body);
@@ -154,7 +160,9 @@
   }
 
   String visitConstant(Constant node) {
-    return '(Constant ${node.expression.value.toStructuredString()})';
+    String value =
+        node.expression.value.accept(new ConstantStringifier(), null);
+    return '(Constant $value)';
   }
 
   String visitThis(This node) {
@@ -223,6 +231,74 @@
     String right = access(node.right);
     return '(Identical $left $right)';
   }
+
+  String visitInterceptor(Interceptor node) {
+    return '(Interceptor ${node.input})';
+  }
+}
+
+class ConstantStringifier extends ConstantValueVisitor<String, Null> {
+  // Some of these methods are unimplemented because we haven't had a need
+  // to print such constants.  When printing is implemented, the corresponding
+  // parsing support should be added to SExpressionUnstringifier.parseConstant
+  // in the dart2js tests (currently in the file
+  // tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart).
+
+  String _failWith(ConstantValue constant) {
+    throw 'Stringification not supported for ${constant.toStructuredString()}';
+  }
+
+  String visitFunction(FunctionConstantValue constant, _) {
+    return _failWith(constant);
+  }
+
+  String visitNull(NullConstantValue constant, _) {
+    return '(Null)';
+  }
+
+  String visitInt(IntConstantValue constant, _) {
+    return '(Int ${constant.unparse()})';
+  }
+
+  String visitDouble(DoubleConstantValue constant, _) {
+    return '(Double ${constant.unparse()})';
+  }
+
+  String visitBool(BoolConstantValue constant, _) {
+    return '(Bool ${constant.unparse()})';
+  }
+
+  String visitString(StringConstantValue constant, _) {
+    return '(String ${constant.unparse()})';
+  }
+
+  String visitList(ListConstantValue constant, _) {
+    return _failWith(constant);
+  }
+
+  String visitMap(MapConstantValue constant, _) {
+    return _failWith(constant);
+  }
+
+  String visitConstructed(ConstructedConstantValue constant, _) {
+    return _failWith(constant);
+  }
+
+  String visitType(TypeConstantValue constant, _) {
+    return _failWith(constant);
+  }
+
+  String visitInterceptor(InterceptorConstantValue constant, _) {
+    return _failWith(constant);
+  }
+
+  String visitDummy(DummyConstantValue constant, _) {
+    return _failWith(constant);
+  }
+
+  String visitDeferred(DeferredConstantValue constant, _) {
+    return _failWith(constant);
+  }
 }
 
 class _Namer {
@@ -230,29 +306,29 @@
   int _valueCounter = 0;
   int _continuationCounter = 0;
 
-  String useElementName(Parameter parameter) {
+  String nameParameter(Parameter parameter) {
     assert(!_names.containsKey(parameter));
     return _names[parameter] = parameter.hint.name;
   }
 
-  String defineClosureName(ClosureVariable variable) {
+  String nameClosureVariable(ClosureVariable variable) {
     assert(!_names.containsKey(variable));
     return _names[variable] = variable.hint.name;
   }
 
-  String defineContinuationName(Node node) {
+  String nameContinuation(Continuation node) {
     assert(!_names.containsKey(node));
     return _names[node] = 'k${_continuationCounter++}';
   }
 
-  String defineValueName(Node node) {
+  String nameValue(Primitive node) {
     assert(!_names.containsKey(node));
     return _names[node] = 'v${_valueCounter++}';
   }
 
-  String useReturnName(Continuation node) {
+  void setReturnContinuation(Continuation node) {
     assert(!_names.containsKey(node) || _names[node] == 'return');
-    return _names[node] = 'return';
+    _names[node] = 'return';
   }
 
   String getName(Node node) {
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
index d9efa83..c68ce94 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_tracer.dart
@@ -36,7 +36,9 @@
     BlockCollector builder = new BlockCollector(names);
     builder.visit(node);
 
-    printNode(builder.entry);
+    for (Block block in builder.entries) {
+      printNode(block);
+    }
     for (Block block in builder.cont2block.values) {
       printNode(block);
     }
@@ -50,6 +52,12 @@
   }
 
   visitFunctionDefinition(cps_ir.FunctionDefinition node) {
+    if (node.isAbstract) return;
+    visitExecutableDefinition(node);
+  }
+
+  visitConstructorDefinition(cps_ir.ConstructorDefinition node) {
+    if (node.isAbstract) return;
     visitExecutableDefinition(node);
   }
 
@@ -249,6 +257,10 @@
     return "Identical($left, $right)";
   }
 
+  visitInterceptor(cps_ir.Interceptor node) {
+    return "Interceptor(${node.input})";
+  }
+
   visitThis(cps_ir.This node) {
     return "This";
   }
@@ -266,11 +278,14 @@
     return 'GetClosureVariable $variable';
   }
 
-
+  visitRunnableBody(cps_ir.RunnableBody node) {}
+  visitFieldInitializer(cps_ir.FieldInitializer node) {}
+  visitSuperInitializer(cps_ir.SuperInitializer node) {}
   visitCondition(cps_ir.Condition c) {}
   visitExpression(cps_ir.Expression e) {}
   visitPrimitive(cps_ir.Primitive p) {}
   visitDefinition(cps_ir.Definition d) {}
+  visitInitializer(cps_ir.Initializer i) {}
   visitNode(cps_ir.Node n) {}
 }
 
@@ -328,9 +343,9 @@
 }
 
 class BlockCollector extends cps_ir.Visitor {
-  Block entry;
   final Map<cps_ir.Continuation, Block> cont2block =
       <cps_ir.Continuation, Block>{};
+  final Set<Block> entries = new Set<Block>();
   Block current_block;
 
   Names names;
@@ -345,8 +360,21 @@
     return block;
   }
 
+  visitRunnableBody(cps_ir.RunnableBody node) {
+    current_block = new Block(names.name(node), [], node.body);
+    entries.add(current_block);
+    visit(node.body);
+  }
+
+  visitFieldInitializer(cps_ir.FieldInitializer node) {
+    visit(node.body);
+  }
+
+  visitSuperInitializer(cps_ir.SuperInitializer node) {
+    node.arguments.forEach(visit);
+  }
+
   visitExecutableDefinition(cps_ir.ExecutableDefinition node) {
-    entry = current_block = new Block(names.name(node), [], node.body);
     visit(node.body);
   }
 
@@ -360,6 +388,10 @@
     visitExecutableDefinition(node);
   }
 
+  visitConstructorDefinition(cps_ir.ConstructorDefinition node) {
+    visitExecutableDefinition(node);
+  }
+
   visitLetPrim(cps_ir.LetPrim exp) {
     visit(exp.body);
   }
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 81f80bb..33a455f 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library dart2js.optimizers;
+library dart2js.cps_ir.optimizers;
 
 import '../constants/expressions.dart' show
     ConstantExpression,
@@ -13,8 +13,13 @@
 import '../tree/tree.dart' show LiteralDartString;
 import '../util/util.dart';
 import 'cps_ir_nodes.dart';
+import '../types/types.dart' show TypeMask, TypesTask;
+import '../types/constants.dart' show computeTypeMask;
+import '../elements/elements.dart' show ClassElement, Element, Entity,
+    FieldElement, FunctionElement, ParameterElement;
+import '../dart2jslib.dart' show ClassWorld;
 
-part 'constant_propagation.dart';
+part 'type_propagation.dart';
 part 'redundant_phi.dart';
 part 'shrinking_reductions.dart';
 
@@ -22,10 +27,28 @@
 abstract class Pass {
   /// Applies optimizations to root, rewriting it in the process.
   void rewrite(ExecutableDefinition root) => root.applyPass(this);
+
+  void rewriteConstructorDefinition(ConstructorDefinition root);
+  void rewriteFunctionDefinition(FunctionDefinition root);
+  void rewriteFieldDefinition(FieldDefinition root);
+}
+
+abstract class PassMixin implements Pass {
+  void rewrite(ExecutableDefinition root) => root.applyPass(this);
+
+  void rewriteExecutableDefinition(ExecutableDefinition root);
+
   void rewriteFunctionDefinition(FunctionDefinition root) {
-    return root.applyPass(this);
+    if (root.isAbstract) return;
+    rewriteExecutableDefinition(root);
+  }
+
+  void rewriteConstructorDefinition(ConstructorDefinition root) {
+    if (root.isAbstract) return;
+    rewriteExecutableDefinition(root);
   }
   void rewriteFieldDefinition(FieldDefinition root) {
-    return root.applyPass(this);
+    if (!root.hasInitializer) return;
+    rewriteExecutableDefinition(root);
   }
-}
+}
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
index e2f4ba9..ec665c1 100644
--- a/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
+++ b/pkg/compiler/lib/src/cps_ir/redundant_phi.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart2js.optimizers;
+part of dart2js.cps_ir.optimizers;
 
 /// Eliminate redundant phis from the given [FunctionDefinition].
 ///
@@ -12,21 +12,10 @@
 /// (except for feedback). Redundant parameters are removed from the
 /// continuation signature, all invocations, and replaced within the
 /// continuation body.
-class RedundantPhiEliminator extends RecursiveVisitor implements Pass {
+class RedundantPhiEliminator extends RecursiveVisitor with PassMixin {
   final Set<Continuation> workSet = new Set<Continuation>();
 
-  void rewrite(final ExecutableDefinition root) => root.applyPass(this);
-
-  void rewriteFunctionDefinition(final FunctionDefinition root) {
-    if (root.isAbstract) return;
-    rewriteExecutableDefinition(root);
-  }
-
-  void rewriteFieldDefinition(final FieldDefinition root) {
-    if (!root.hasInitializer) return;
-    rewriteExecutableDefinition(root);
-  }
-
+  @override
   void rewriteExecutableDefinition(final ExecutableDefinition root) {
 
     // Set all parent pointers.
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index 81e1137..336c1c4 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -2,18 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-part of dart2js.optimizers;
+part of dart2js.cps_ir.optimizers;
 
 /**
- * [[ShrinkingReducer]] applies shrinking reductions to CPS terms as described
+ * [ShrinkingReducer] applies shrinking reductions to CPS terms as described
  * in 'Compiling with Continuations, Continued' by Andrew Kennedy.
  */
-class ShrinkingReducer extends Pass {
+class ShrinkingReducer extends PassMixin {
   _RedexVisitor _redexVisitor;
   Set<_ReductionTask> _worklist;
 
   static final _DeletedNode _DELETED = new _DeletedNode();
 
+  /// Applies shrinking reductions to root, mutating root in the process.
+  @override
   void rewriteExecutableDefinition(ExecutableDefinition root) {
     _worklist = new Set<_ReductionTask>();
     _redexVisitor = new _RedexVisitor(_worklist);
@@ -32,18 +34,6 @@
     }
   }
 
-  /// Applies shrinking reductions to root, mutating root in the process.
-  void rewriteFieldDefinition(FieldDefinition root) {
-    if (!root.hasInitializer) return;
-    rewriteExecutableDefinition(root);
-  }
-
-  /// Applies shrinking reductions to root, mutating root in the process.
-  void rewriteFunctionDefinition(FunctionDefinition root) {
-    if (root.isAbstract) return;
-    rewriteExecutableDefinition(root);
-  }
-
   /// Removes the given node from the CPS graph, replacing it with its body
   /// and marking it as deleted. The node's parent must be a [[InteriorNode]].
   void _removeNode(InteriorNode node) {
@@ -304,17 +294,32 @@
 /// Traverses the CPS term and sets node.parent for each visited node.
 class ParentVisitor extends RecursiveVisitor {
 
-  processFieldDefinition(FieldDefinition node) {
-    node.body.parent = node;
-  }
-
   processFunctionDefinition(FunctionDefinition node) {
     node.body.parent = node;
     node.parameters.forEach((Definition p) => p.parent = node);
   }
 
+  processRunnableBody(RunnableBody node) {
+    node.body.parent = node;
+  }
+
+  processConstructorDefinition(ConstructorDefinition node) {
+    node.body.parent = node;
+    node.parameters.forEach((Definition p) => p.parent = node);
+    node.initializers.forEach((Initializer i) => i.parent = node);
+  }
+
   // Expressions.
 
+  processFieldInitializer(FieldInitializer node) {
+    node.body.body.parent = node;
+  }
+
+  processSuperInitializer(SuperInitializer node) {
+    node.arguments.forEach(
+        (RunnableBody argument) => argument.body.parent = node);
+  }
+
   processLetPrim(LetPrim node) {
     node.primitive.parent = node;
     node.body.parent = node;
@@ -411,6 +416,10 @@
     node.left.parent = node;
     node.right.parent = node;
   }
+
+  processInterceptor(Interceptor node) {
+    node.input.parent = node;
+  }
 }
 
 class _ReductionKind {
diff --git a/pkg/compiler/lib/src/cps_ir/constant_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
similarity index 65%
rename from pkg/compiler/lib/src/cps_ir/constant_propagation.dart
rename to pkg/compiler/lib/src/cps_ir/type_propagation.dart
index c9adf08..9585ff9 100644
--- a/pkg/compiler/lib/src/cps_ir/constant_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -2,57 +2,139 @@
 // 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.
 
-part of dart2js.optimizers;
+part of dart2js.cps_ir.optimizers;
+
+abstract class TypeSystem<T> {
+  T get dynamicType;
+  T get typeType;
+  T get functionType;
+  T get boolType;
+  T get intType;
+  T get stringType;
+  T get listType;
+  T get mapType;
+
+  T getReturnType(FunctionElement element);
+  T getParameterType(ParameterElement element);
+  bool areAssignable(T a, T b);
+  T join(T a, T b);
+  T typeOf(ConstantValue constant);
+}
+
+class UnitTypeSystem implements TypeSystem<String> {
+  static const String UNIT = 'unit';
+
+  get boolType => UNIT;
+  get dynamicType => UNIT;
+  get functionType => UNIT;
+  get intType => UNIT;
+  get listType => UNIT;
+  get mapType => UNIT;
+  get stringType => UNIT;
+  get typeType => UNIT;
+
+  bool areAssignable(a, b) => true;
+  getParameterType(_) => UNIT;
+  getReturnType(_) => UNIT;
+  join(a, b) => UNIT;
+  typeOf(_) => UNIT;
+}
+
+class TypeMaskSystem implements TypeSystem<TypeMask> {
+  final TypesTask inferrer;
+  final ClassWorld classWorld;
+
+  TypeMask get dynamicType => inferrer.dynamicType;
+  TypeMask get typeType => inferrer.typeType;
+  TypeMask get functionType => inferrer.functionType;
+  TypeMask get boolType => inferrer.boolType;
+  TypeMask get intType => inferrer.intType;
+  TypeMask get stringType => inferrer.stringType;
+  TypeMask get listType => inferrer.listType;
+  TypeMask get mapType => inferrer.mapType;
+
+  TypeMaskSystem(dart2js.Compiler compiler)
+    : inferrer = compiler.typesTask,
+      classWorld = compiler.world;
+
+  TypeMask getParameterType(ParameterElement parameter) {
+    return inferrer.getGuaranteedTypeOfElement(parameter);
+  }
+
+  TypeMask getReturnType(FunctionElement function) {
+    return inferrer.getGuaranteedReturnTypeOfElement(function);
+  }
+
+  @override
+  bool areAssignable(TypeMask a, TypeMask b) {
+    return a.containsMask(b, classWorld) || b.containsMask(a, classWorld);
+  }
+
+  @override
+  TypeMask join(TypeMask a, TypeMask b) {
+    return a.union(b, classWorld);
+  }
+
+  @override
+  TypeMask typeOf(ConstantValue constant) {
+    return computeTypeMask(inferrer.compiler, constant);
+  }
+}
 
 /**
- * Propagates constants throughout the IR, and replaces branches with fixed
- * jumps as well as side-effect free expressions with known constant results.
+ * Propagates types (including value types for constants) throughout the IR, and
+ * replaces branches with fixed jumps as well as side-effect free expressions
+ * with known constant results.
+ *
  * Should be followed by the [ShrinkingReducer] pass.
  *
  * Implemented according to 'Constant Propagation with Conditional Branches'
  * by Wegman, Zadeck.
  */
-class ConstantPropagator extends Pass {
-
-  // Required for type determination in analysis of TypeOperator expressions.
-  final dart2js.Compiler _compiler;
+class TypePropagator<T> extends PassMixin {
+  // TODO(karlklose): remove reference to _compiler. It is currently used to
+  // compute [TypeMask]s.
+  final types.DartTypes _dartTypes;
 
   // The constant system is used for evaluation of expressions with constant
   // arguments.
   final dart2js.ConstantSystem _constantSystem;
+  final TypeSystem _typeSystem;
+  final dart2js.InternalErrorFunction _internalError;
+  final Map<Node, _AbstractValue> _types;
 
-  ConstantPropagator(this._compiler, this._constantSystem);
 
-  void _rewriteExecutableDefinition(ExecutableDefinition root) {
+  TypePropagator(this._dartTypes,
+                 this._constantSystem,
+                 this._typeSystem,
+                 this._internalError)
+      : _types = <Node, _AbstractValue>{};
+
+  @override
+  void rewriteExecutableDefinition(ExecutableDefinition root) {
     // Set all parent pointers.
     new ParentVisitor().visit(root);
 
     // Analyze. In this phase, the entire term is analyzed for reachability
-    // and the constant status of each expression.
+    // and the abstract value of each expression.
+    _TypePropagationVisitor<T> analyzer = new _TypePropagationVisitor<T>(
+        _constantSystem,
+        _typeSystem,
+        _types,
+        _internalError,
+        _dartTypes);
 
-    _ConstPropagationVisitor analyzer =
-        new _ConstPropagationVisitor(_compiler, _constantSystem);
     analyzer.analyze(root);
 
     // Transform. Uses the data acquired in the previous analysis phase to
     // replace branches with fixed targets and side-effect-free expressions
     // with constant results.
-
     _TransformingVisitor transformer = new _TransformingVisitor(
-        analyzer.reachableNodes, analyzer.node2value);
+        analyzer.reachableNodes, analyzer.values, _internalError);
     transformer.transform(root);
   }
 
-  void rewriteFunctionDefinition(FunctionDefinition root) {
-    if (root.isAbstract) return;
-    _rewriteExecutableDefinition(root);
-  }
-
-  void rewriteFieldDefinition(FieldDefinition root) {
-    if (!root.hasInitializer) return;
-    _rewriteExecutableDefinition(root);
-  }
-
+  getType(Node node) => _types[node];
 }
 
 /**
@@ -60,11 +142,12 @@
  * actual transformations on the CPS graph.
  */
 class _TransformingVisitor extends RecursiveVisitor {
-
   final Set<Node> reachable;
-  final Map<Node, _ConstnessLattice> node2value;
+  final Map<Node, _AbstractValue> values;
 
-  _TransformingVisitor(this.reachable, this.node2value);
+  final dart2js.InternalErrorFunction internalError;
+
+  _TransformingVisitor(this.reachable, this.values, this.internalError);
 
   void transform(ExecutableDefinition root) {
     visit(root);
@@ -76,16 +159,15 @@
   LetPrim constifyExpression(Expression node,
                              Continuation continuation,
                              void unlink()) {
-    _ConstnessLattice cell = node2value[node];
-    if (cell == null || !cell.isConstant) {
+    _AbstractValue value = values[node];
+    if (value == null || !value.isConstant) {
       return null;
     }
 
     assert(continuation.parameters.length == 1);
 
     // Set up the replacement structure.
-
-    PrimitiveConstantValue primitiveConstant = cell.constant;
+    PrimitiveConstantValue primitiveConstant = value.constant;
     ConstantExpression constExp =
         new PrimitiveConstantExpression(primitiveConstant);
     Constant constant = new Constant(constExp);
@@ -207,7 +289,7 @@
  * const-ness as well as reachability, both of which are used in the subsequent
  * transformation pass.
  */
-class _ConstPropagationVisitor extends Visitor {
+class _TypePropagationVisitor<T> extends Visitor {
   // The node worklist stores nodes that are both reachable and need to be
   // processed, but have not been processed yet. Using a worklist avoids deep
   // recursion.
@@ -224,15 +306,44 @@
   // since their lattice value has changed.
   final Set<Definition> defWorkset = new Set<Definition>();
 
-  final dart2js.Compiler compiler;
   final dart2js.ConstantSystem constantSystem;
+  final TypeSystem typeSystem;
+  final dart2js.InternalErrorFunction internalError;
+  final types.DartTypes _dartTypes;
+
+  _AbstractValue unknownDynamic;
+
+  _AbstractValue unknown([T t]) {
+    if (t == null) {
+      return unknownDynamic;
+    } else {
+      return new _AbstractValue.unknown(t);
+    }
+  }
+
+  _AbstractValue nonConst([T type]) {
+    if (type == null) {
+      type = typeSystem.dynamicType;
+    }
+    return new _AbstractValue.nonConst(type);
+  }
+
+  _AbstractValue constantValue(ConstantValue constant, T type) {
+    return new _AbstractValue(constant, type);
+  }
 
   // Stores the current lattice value for nodes. Note that it contains not only
   // definitions as keys, but also expressions such as method invokes.
   // Access through [getValue] and [setValue].
-  final Map<Node, _ConstnessLattice> node2value = <Node, _ConstnessLattice>{};
+  final Map<Node, _AbstractValue> values;
 
-  _ConstPropagationVisitor(this.compiler, this.constantSystem);
+  _TypePropagationVisitor(this.constantSystem,
+                          TypeSystem typeSystem,
+                          this.values,
+                          this.internalError,
+                          this._dartTypes)
+    : this.unknownDynamic = new _AbstractValue.unknown(typeSystem.dynamicType),
+      this.typeSystem = typeSystem;
 
   void analyze(ExecutableDefinition root) {
     reachableNodes.clear();
@@ -276,17 +387,17 @@
   /// Returns the lattice value corresponding to [node], defaulting to unknown.
   ///
   /// Never returns null.
-  _ConstnessLattice getValue(Node node) {
-    _ConstnessLattice value = node2value[node];
-    return (value == null) ? _ConstnessLattice.Unknown : value;
+  _AbstractValue getValue(Node node) {
+    _AbstractValue value = values[node];
+    return (value == null) ? unknown() : value;
   }
 
   /// Joins the passed lattice [updateValue] to the current value of [node],
   /// and adds it to the definition work set if it has changed and [node] is
   /// a definition.
-  void setValue(Node node, _ConstnessLattice updateValue) {
-    _ConstnessLattice oldValue = getValue(node);
-    _ConstnessLattice newValue = updateValue.join(oldValue);
+  void setValue(Node node, _AbstractValue updateValue) {
+    _AbstractValue oldValue = getValue(node);
+    _AbstractValue newValue = updateValue.join(oldValue, typeSystem);
     if (oldValue == newValue) {
       return;
     }
@@ -294,7 +405,7 @@
     // Values may only move in the direction UNKNOWN -> CONSTANT -> NONCONST.
     assert(newValue.kind >= oldValue.kind);
 
-    node2value[node] = newValue;
+    values[node] = newValue;
     if (node is Definition) {
       defWorkset.add(node);
     }
@@ -303,8 +414,12 @@
   // -------------------------- Visitor overrides ------------------------------
 
   void visitNode(Node node) {
-    compiler.internalError(NO_LOCATION_SPANNABLE,
-        "_ConstPropagationVisitor is stale, add missing visit overrides");
+    internalError(NO_LOCATION_SPANNABLE,
+        "_TypePropagationVisitor is stale, add missing visit overrides");
+  }
+
+  void visitRunnableBody(RunnableBody node) {
+    setReachable(node.body);
   }
 
   void visitFunctionDefinition(FunctionDefinition node) {
@@ -336,7 +451,11 @@
 
     assert(cont.parameters.length == 1);
     Parameter returnValue = cont.parameters[0];
-    setValue(returnValue, _ConstnessLattice.NonConst);
+    Entity target = node.target;
+    T returnType = target is FieldElement
+        ? typeSystem.dynamicType
+        : typeSystem.getReturnType(node.target);
+    setValue(returnValue, nonConst(returnType));
   }
 
   void visitInvokeContinuation(InvokeContinuation node) {
@@ -347,7 +466,7 @@
     // continuation. Note that this is effectively a phi node in SSA terms.
     for (int i = 0; i < node.arguments.length; i++) {
       Definition def = node.arguments[i].definition;
-      _ConstnessLattice cell = getValue(def);
+      _AbstractValue cell = getValue(def);
       setValue(cont.parameters[i], cell);
     }
   }
@@ -358,13 +477,13 @@
 
     /// Sets the value of both the current node and the target continuation
     /// parameter.
-    void setValues(_ConstnessLattice updateValue) {
+    void setValues(_AbstractValue updateValue) {
       setValue(node, updateValue);
       Parameter returnValue = cont.parameters[0];
       setValue(returnValue, updateValue);
     }
 
-    _ConstnessLattice lhs = getValue(node.receiver.definition);
+    _AbstractValue lhs = getValue(node.receiver.definition);
     if (lhs.isUnknown) {
       // This may seem like a missed opportunity for evaluating short-circuiting
       // boolean operations; we are currently skipping these intentionally since
@@ -374,11 +493,11 @@
       // a type-check (in checked mode) are still executed.
       return;  // And come back later.
     } else if (lhs.isNonConst) {
-      setValues(_ConstnessLattice.NonConst);
+      setValues(nonConst());
       return;
     } else if (!node.selector.isOperator) {
       // TODO(jgruber): Handle known methods on constants such as String.length.
-      setValues(_ConstnessLattice.NonConst);
+      setValues(nonConst());
       return;
     }
 
@@ -398,7 +517,7 @@
     } else if (node.selector.argumentCount == 1) {
       // Binary operator.
 
-      _ConstnessLattice rhs = getValue(node.arguments[0].definition);
+      _AbstractValue rhs = getValue(node.arguments[0].definition);
       if (!rhs.isConstant) {
         setValues(rhs);
         return;
@@ -412,9 +531,12 @@
 
     // Update value of the continuation parameter. Again, this is effectively
     // a phi.
-
-    setValues((result == null) ?
-        _ConstnessLattice.NonConst : new _ConstnessLattice(result));
+    if (result == null) {
+      setValues(nonConst());
+    } else {
+      T type = typeSystem.typeOf(result);
+      setValues(new _AbstractValue(result, type));
+    }
    }
 
   void visitInvokeSuperMethod(InvokeSuperMethod node) {
@@ -423,7 +545,8 @@
 
     assert(cont.parameters.length == 1);
     Parameter returnValue = cont.parameters[0];
-    setValue(returnValue, _ConstnessLattice.NonConst);
+    // TODO(karlklose): lookup the function and get ites return type.
+    setValue(returnValue, nonConst());
   }
 
   void visitInvokeConstructor(InvokeConstructor node) {
@@ -432,14 +555,14 @@
 
     assert(cont.parameters.length == 1);
     Parameter returnValue = cont.parameters[0];
-    setValue(returnValue, _ConstnessLattice.NonConst);
+    setValue(returnValue, nonConst());
   }
 
   void visitConcatenateStrings(ConcatenateStrings node) {
     Continuation cont = node.continuation.definition;
     setReachable(cont);
 
-    void setValues(_ConstnessLattice updateValue) {
+    void setValues(_AbstractValue updateValue) {
       setValue(node, updateValue);
       Parameter returnValue = cont.parameters[0];
       setValue(returnValue, updateValue);
@@ -455,6 +578,7 @@
       return constant != null && constant.value.isString;
     });
 
+    T type = typeSystem.stringType;
     assert(cont.parameters.length == 1);
     if (allStringConstants) {
       // All constant, we can concatenate ourselves.
@@ -465,15 +589,15 @@
       });
       LiteralDartString dartString = new LiteralDartString(allStrings.join());
       ConstantValue constant = new StringConstantValue(dartString);
-      setValues(new _ConstnessLattice(constant));
+      setValues(new _AbstractValue(constant, type));
     } else {
-      setValues(_ConstnessLattice.NonConst);
+      setValues(nonConst(type));
     }
   }
 
   void visitBranch(Branch node) {
     IsTrue isTrue = node.condition;
-    _ConstnessLattice conditionCell = getValue(isTrue.value.definition);
+    _AbstractValue conditionCell = getValue(isTrue.value.definition);
 
     if (conditionCell.isUnknown) {
       return;  // And come back later.
@@ -487,7 +611,7 @@
       // TODO(jgruber): Default to false in unchecked mode.
       setReachable(node.trueContinuation.definition);
       setReachable(node.falseContinuation.definition);
-      setValue(isTrue.value.definition, _ConstnessLattice.NonConst);
+      setValue(isTrue.value.definition, nonConst(typeSystem.boolType));
     } else if (conditionCell.isConstant &&
         conditionCell.constant.isBool) {
       BoolConstantValue boolConstant = conditionCell.constant;
@@ -500,7 +624,7 @@
     Continuation cont = node.continuation.definition;
     setReachable(cont);
 
-    void setValues(_ConstnessLattice updateValue) {
+    void setValues(_AbstractValue updateValue) {
       setValue(node, updateValue);
       Parameter returnValue = cont.parameters[0];
       setValue(returnValue, updateValue);
@@ -508,35 +632,37 @@
 
     if (node.isTypeCast) {
       // TODO(jgruber): Add support for `as` casts.
-      setValues(_ConstnessLattice.NonConst);
+      setValues(nonConst());
     }
 
-    _ConstnessLattice cell = getValue(node.receiver.definition);
+    _AbstractValue cell = getValue(node.receiver.definition);
     if (cell.isUnknown) {
       return;  // And come back later.
     } else if (cell.isNonConst) {
-      setValues(_ConstnessLattice.NonConst);
+      setValues(nonConst(cell.type));
     } else if (node.type.kind == types.TypeKind.INTERFACE) {
       // Receiver is a constant, perform is-checks at compile-time.
 
       types.InterfaceType checkedType = node.type;
       ConstantValue constant = cell.constant;
-      types.DartType constantType = constant.computeType(compiler);
+      // TODO(karlklose): remove call to computeType.
+      types.DartType constantType = constant.getType(_dartTypes.coreTypes);
 
-      _ConstnessLattice result = _ConstnessLattice.NonConst;
+      T type = typeSystem.boolType;
+      _AbstractValue result;
       if (constant.isNull &&
-          checkedType.element != compiler.nullClass &&
-          checkedType.element != compiler.objectClass) {
+          checkedType != _dartTypes.coreTypes.nullType &&
+          checkedType != _dartTypes.coreTypes.objectType) {
         // `(null is Type)` is true iff Type is in { Null, Object }.
-        result = new _ConstnessLattice(new FalseConstantValue());
+        result = constantValue(new FalseConstantValue(), type);
       } else {
         // Otherwise, perform a standard subtype check.
-        result = new _ConstnessLattice(
-            constantSystem.isSubtype(compiler, constantType, checkedType)
+        result = constantValue(
+            constantSystem.isSubtype(_dartTypes, constantType, checkedType)
             ? new TrueConstantValue()
-            : new FalseConstantValue());
+            : new FalseConstantValue(),
+            type);
       }
-
       setValues(result);
     }
   }
@@ -554,58 +680,65 @@
   void visitLiteralList(LiteralList node) {
     // Constant lists are translated into (Constant ListConstant(...)) IR nodes,
     // and thus LiteralList nodes are NonConst.
-    setValue(node, _ConstnessLattice.NonConst);
+    setValue(node, nonConst(typeSystem.listType));
   }
 
   void visitLiteralMap(LiteralMap node) {
     // Constant maps are translated into (Constant MapConstant(...)) IR nodes,
     // and thus LiteralMap nodes are NonConst.
-    setValue(node, _ConstnessLattice.NonConst);
+    setValue(node, nonConst(typeSystem.mapType));
   }
 
   void visitConstant(Constant node) {
-    setValue(node, new _ConstnessLattice(node.value));
+    ConstantValue value = node.value;
+    setValue(node, constantValue(value, typeSystem.typeOf(value)));
   }
 
   void visitThis(This node) {
-    setValue(node, _ConstnessLattice.NonConst);
+    // TODO(karlklose): Add the type.
+    setValue(node, nonConst());
   }
 
   void visitReifyTypeVar(ReifyTypeVar node) {
-    setValue(node, _ConstnessLattice.NonConst);
+    setValue(node, nonConst(typeSystem.typeType));
   }
 
   void visitCreateFunction(CreateFunction node) {
     setReachable(node.definition);
     ConstantValue constant =
         new FunctionConstantValue(node.definition.element);
-    setValue(node, new _ConstnessLattice(constant));
+    setValue(node, constantValue(constant, typeSystem.functionType));
   }
 
   void visitGetClosureVariable(GetClosureVariable node) {
-    setValue(node, _ConstnessLattice.NonConst);
+    setValue(node, nonConst());
   }
 
   void visitClosureVariable(ClosureVariable node) {
   }
 
   void visitParameter(Parameter node) {
+    Entity source = node.hint;
+    // TODO(karlklose): remove reference to the element model.
+    T type = (source is ParameterElement) ? typeSystem.getParameterType(source)
+        : typeSystem.dynamicType;
     if (node.parent is FunctionDefinition) {
       // Functions may escape and thus their parameters must be initialized to
       // NonConst.
-      setValue(node, _ConstnessLattice.NonConst);
+      setValue(node, nonConst(type));
     } else if (node.parent is Continuation) {
       // Continuations on the other hand are local, and parameters are
       // initialized to Unknown.
-      setValue(node, _ConstnessLattice.Unknown);
+      setValue(node, unknown());
     } else {
-      compiler.internalError(node.hint, "Unexpected parent of Parameter");
+      internalError(node.hint, "Unexpected parent of Parameter");
     }
   }
 
   void visitContinuation(Continuation node) {
     node.parameters.forEach((Parameter p) {
-      setValue(p, _ConstnessLattice.Unknown);
+      // TODO(karlklose): join parameter types from use sites.
+      setValue(p, unknown());
       defWorkset.add(p);
     });
 
@@ -624,82 +757,105 @@
   // JavaScript specific nodes.
 
   void visitIdentical(Identical node) {
-    _ConstnessLattice leftConst = getValue(node.left.definition);
-    _ConstnessLattice rightConst = getValue(node.left.definition);
+    _AbstractValue leftConst = getValue(node.left.definition);
+    _AbstractValue rightConst = getValue(node.right.definition);
     ConstantValue leftValue = leftConst.constant;
     ConstantValue rightValue = rightConst.constant;
     if (leftConst.isUnknown || rightConst.isUnknown) {
       // Come back later.
       return;
     } else if (!leftConst.isConstant || !rightConst.isConstant) {
-      setValue(node, _ConstnessLattice.NonConst);
+      T leftType = leftConst.type;
+      T rightType = rightConst.type;
+      if (!typeSystem.areAssignable(leftType, rightType)) {
+        setValue(node,
+            constantValue(new FalseConstantValue(), typeSystem.boolType));
+      } else {
+        setValue(node, nonConst(typeSystem.boolType));
+      }
     } else if (leftValue.isPrimitive && rightValue.isPrimitive) {
       assert(leftConst.isConstant && rightConst.isConstant);
       PrimitiveConstantValue left = leftValue;
       PrimitiveConstantValue right = rightValue;
       ConstantValue result =
           new BoolConstantValue(left.primitiveValue == right.primitiveValue);
-      setValue(node, new _ConstnessLattice(result));
+      setValue(node, new _AbstractValue(result, typeSystem.boolType));
     }
   }
+
+  void visitInterceptor(Interceptor node) {
+    setReachable(node.input.definition);
+  }
 }
 
-/// Represents the constant-state of a variable at some point in the program.
-/// UNKNOWN: may be some as yet undetermined constant.
-/// CONSTANT: is a constant as stored in the local field.
-/// NONCONST: not a constant.
-class _ConstnessLattice {
+/// Represents the abstract value of a primitive value at some point in the
+/// program. Abstract values of all kinds have a type [T].
+///
+/// The different kinds of abstract values represents the knowledge about the
+/// constness of the value:
+///   UNKNOWN: may be some as yet undetermined constant.
+///   CONSTANT: is a constant as stored in the local field.
+///   NONCONST: not a constant.
+class _AbstractValue<T> {
   static const int UNKNOWN  = 0;
   static const int CONSTANT = 1;
   static const int NONCONST = 2;
 
   final int kind;
   final ConstantValue constant;
+  final T type;
 
-  static final _ConstnessLattice Unknown =
-      new _ConstnessLattice._internal(UNKNOWN, null);
-  static final _ConstnessLattice NonConst =
-      new _ConstnessLattice._internal(NONCONST, null);
-
-  _ConstnessLattice._internal(this.kind, this.constant);
-  _ConstnessLattice(this.constant) : kind = CONSTANT {
-    assert(this.constant != null);
+  _AbstractValue._internal(this.kind, this.constant, this.type) {
+    assert(kind != CONSTANT || constant != null);
+    assert(type != null);
   }
 
+  _AbstractValue(ConstantValue constant, T type)
+      : this._internal(CONSTANT, constant, type);
+
+  _AbstractValue.unknown(T type)
+      : this._internal(UNKNOWN, null, type);
+
+  _AbstractValue.nonConst(T type)
+      : this._internal(NONCONST, null, type);
+
   bool get isUnknown  => (kind == UNKNOWN);
   bool get isConstant => (kind == CONSTANT);
   bool get isNonConst => (kind == NONCONST);
 
-  int get hashCode => kind | (constant.hashCode << 2);
-  bool operator==(_ConstnessLattice that) =>
-      (that.kind == this.kind && that.constant == this.constant);
+  int get hashCode {
+    return kind | (constant.hashCode * 5) | type.hashCode * 7;
+  }
+
+  bool operator ==(_AbstractValue that) {
+      return that.kind == this.kind &&
+          that.constant == this.constant &&
+          that.type == this.type;
+  }
 
   String toString() {
     switch (kind) {
       case UNKNOWN: return "Unknown";
-      case CONSTANT: return "Constant: $constant";
-      case NONCONST: return "Non-constant";
+      case CONSTANT: return "Constant: $constant: $type";
+      case NONCONST: return "Non-constant: $type";
       default: assert(false);
     }
     return null;
   }
 
   /// Compute the join of two values in the lattice.
-  _ConstnessLattice join(_ConstnessLattice that) {
+  _AbstractValue join(_AbstractValue that, TypeSystem typeSystem) {
     assert(that != null);
 
-    if (this.isNonConst || that.isUnknown) {
-      return this;
-    }
-
-    if (this.isUnknown || that.isNonConst) {
+    if (this.isUnknown) {
       return that;
-    }
-
-    if (this.constant == that.constant) {
+    } else if (that.isUnknown) {
       return this;
+    } else if (this.isConstant && that.isConstant &&
+               this.constant == that.constant) {
+      return this;
+    } else {
+      return new _AbstractValue.nonConst(typeSystem.join(this.type, that.type));
     }
-
-    return NonConst;
   }
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/dart2jslib.dart b/pkg/compiler/lib/src/dart2jslib.dart
index 974bb5e..d67712c 100644
--- a/pkg/compiler/lib/src/dart2jslib.dart
+++ b/pkg/compiler/lib/src/dart2jslib.dart
@@ -14,6 +14,7 @@
 import 'closure.dart' as closureMapping;
 import 'constants/expressions.dart';
 import 'constants/values.dart';
+import 'core_types.dart';
 import 'cps_ir/cps_ir_builder.dart' show IrBuilderTask;
 import 'dart_backend/dart_backend.dart' as dart_backend;
 import 'dart_types.dart';
@@ -24,6 +25,7 @@
     show ErroneousElementX,
          ClassElementX,
          CompilationUnitElementX,
+         FunctionElementX,
          LibraryElementX,
          PrefixElementX,
          VoidElementX,
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index 171244d..d5a2b70 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -11,10 +11,7 @@
   final Node ast;
   final TreeElements treeElements;
 
-  ElementAst(AstElement element)
-      : this.internal(element.resolvedAst.node, element.resolvedAst.elements);
-
-  ElementAst.internal(this.ast, this.treeElements);
+  ElementAst(this.ast, this.treeElements);
 }
 
 class DartBackend extends Backend {
@@ -133,7 +130,8 @@
   void codegen(CodegenWorkItem work) { }
 
   /// Create an [ElementAst] from the CPS IR.
-  static ElementAst createElementAst(Compiler compiler,
+  static ElementAst createElementAst(
+       Compiler compiler,
        Tracer tracer,
        ConstantSystem constantSystem,
        Element element,
@@ -149,7 +147,10 @@
       }
     }
 
-    new ConstantPropagator(compiler, constantSystem).rewrite(cpsDefinition);
+    // TODO(karlklose): enable type propagation for dart2dart when constant
+    // types are correctly marked as instantiated (Issue 21880).
+    new TypePropagator(compiler.types, constantSystem, new UnitTypeSystem(),
+        compiler.internalError).rewrite(cpsDefinition);
     traceGraph("Sparse constant propagation", cpsDefinition);
     new RedundantPhiEliminator().rewrite(cpsDefinition);
     traceGraph("Redundant phi elimination", cpsDefinition);
@@ -161,7 +162,8 @@
     // ranges that can be invalidated by transforming the IR.
     new cps_ir.RegisterAllocator().visit(cpsDefinition);
 
-    tree_builder.Builder builder = new tree_builder.Builder(compiler);
+    tree_builder.Builder builder =
+        new tree_builder.Builder(compiler.internalError);
     tree_ir.ExecutableDefinition treeDefinition = builder.build(cpsDefinition);
     assert(treeDefinition != null);
     traceGraph('Tree builder', treeDefinition);
@@ -182,7 +184,7 @@
     backend_ast.ExecutableDefinition backendAst =
         backend_ast_emitter.emit(treeDefinition);
     Node frontend_ast = backend2frontend.emit(treeElements, backendAst);
-    return new ElementAst.internal(frontend_ast, treeElements);
+    return new ElementAst(frontend_ast, treeElements);
 
   }
 
@@ -202,7 +204,8 @@
 
     ElementAst computeElementAst(AstElement element) {
       if (!compiler.irBuilder.hasIr(element)) {
-        return new ElementAst(element);
+        return new ElementAst(element.resolvedAst.node,
+                              element.resolvedAst.elements);
       } else {
         cps_ir.ExecutableDefinition definition =
             compiler.irBuilder.getIr(element);
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
index 5a0a277..3007f52 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_emitter.dart
@@ -29,7 +29,7 @@
   final List<VariableDeclaration> variables = <VariableDeclaration>[];
 
   /// Maps variables to their name.
-  final Map<tree.Variable, String> variableNames = <tree.Variable, String>{};
+  final Map<tree.Variable, String> variableNames;
 
   /// Maps local constants to their name.
   final Map<VariableElement, String> constantNames =
@@ -59,15 +59,28 @@
   /// Labels that could not be eliminated using fallthrough.
   final Set<tree.Label> _usedLabels = new Set<tree.Label>();
 
+  final bool inInitializer;
+
   /// The first dart_tree statement that is not converted to a variable
   /// initializer.
   tree.Statement firstStatement;
 
-  BuilderContext() : usedVariableNames = new Set<String>();
+  BuilderContext() : usedVariableNames = new Set<String>(),
+                     inInitializer = false,
+                     variableNames = <tree.Variable, String>{};
 
   BuilderContext.inner(BuilderContext<T> parent)
       : this._parent = parent,
-        usedVariableNames = parent.usedVariableNames;
+        usedVariableNames = parent.usedVariableNames,
+        inInitializer = false,
+        variableNames = <tree.Variable, String>{};
+
+  BuilderContext.initializer(BuilderContext<T> parent)
+      : this._parent = parent,
+        usedVariableNames = parent.usedVariableNames,
+        inInitializer = true,
+        variableNames =
+            new Map<tree.Variable, String>.from(parent.variableNames);
 
   // TODO(johnniwinther): Fully encapsulate handling of parameter, variable
   // and local funciton declarations.
@@ -85,7 +98,7 @@
   String getVariableName(tree.Variable variable) {
     // If the variable belongs to an enclosing function, ask the parent emitter
     // for the variable name.
-    if (variable.host != currentElement) {
+    if (!inInitializer && variable.host != currentElement) {
       return _parent.getVariableName(variable);
     }
 
@@ -192,6 +205,8 @@
                             BuilderContext<Statement> context) {
     if (definition is tree.FieldDefinition) {
       return emitField(definition, context);
+    } else if (definition is tree.ConstructorDefinition) {
+      return emitConstructor(definition, context);
     }
     assert(definition is tree.FunctionDefinition);
     return emitFunction(definition, context);
@@ -239,6 +254,87 @@
     return new CallFunction(function, []);
   }
 
+  bool _recognizeTrailingReturn(Statement statement) {
+    if (statement is Return) {
+      Expression expr = statement.expression;
+      if (expr == null || expr is Literal && expr.value.isNull) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  FunctionExpression emitConstructor(tree.ConstructorDefinition definition,
+                                     BuilderContext<Statement> context) {
+    context.currentElement = definition.element;
+
+    Parameters parameters = emitRootParameters(definition, context);
+
+    // Declare parameters.
+    for (tree.Variable param in definition.parameters) {
+      context.variableNames[param] = param.element.name;
+      context.usedVariableNames.add(param.element.name);
+      context.declaredVariables.add(param);
+    }
+
+    List<Expression> initializers;
+    Statement body;
+
+    if (!definition.isAbstract) {
+      initializers =
+          definition.initializers.map((tree.Initializer initializer) {
+        return visitExpression(initializer, context);
+      }).toList();
+
+      context.firstStatement = definition.body;
+      visitStatement(definition.body, context);
+      context.removeTrailingReturn(_recognizeTrailingReturn);
+
+      // Some of the variable declarations have already been added
+      // if their first assignment could be pulled into the initializer.
+      // Add the remaining variable declarations now.
+      for (tree.Variable variable in context.variableNames.keys) {
+        if (!context.declaredVariables.contains(variable)) {
+          context.addDeclaration(variable);
+        }
+      }
+
+      // Add constant declarations.
+      List<VariableDeclaration> constants = <VariableDeclaration>[];
+      for (ConstDeclaration constDecl in definition.localConstants) {
+        if (!context.constantNames.containsKey(constDecl.element)) {
+          continue; // Discard unused constants declarations.
+        }
+        String name = context.getConstantName(constDecl.element);
+        Expression value =
+            ConstantEmitter.createExpression(constDecl.expression, context);
+        VariableDeclaration decl = new VariableDeclaration(name, value);
+        decl.element = constDecl.element;
+        constants.add(decl);
+      }
+
+      List<Statement> bodyParts = [];
+      if (constants.length > 0) {
+        bodyParts.add(new VariableDeclarations(constants, isConst: true));
+      }
+      if (context.variables.length > 0) {
+        bodyParts.add(new VariableDeclarations(context.variables));
+      }
+      bodyParts.addAll(context.statements);
+
+      body = new Block(bodyParts);
+
+    }
+    FunctionType functionType = context.currentElement.type;
+
+    return new ConstructorDefinition(
+        parameters,
+        body,
+        initializers,
+        context.currentElement.name, definition.element.isConst)
+        ..element = context.currentElement;
+  }
+
   FunctionExpression emitFunction(tree.FunctionDefinition definition,
                                   BuilderContext<Statement> context) {
     context.currentElement = definition.element;
@@ -258,15 +354,7 @@
     } else {
       context.firstStatement = definition.body;
       visitStatement(definition.body, context);
-      context.removeTrailingReturn((Statement statement) {
-        if (statement is Return) {
-          Expression expr = statement.expression;
-          if (expr is Literal && expr.value.isNull) {
-            return true;
-          }
-        }
-        return false;
-      });
+      context.removeTrailingReturn(_recognizeTrailingReturn);
 
       // Some of the variable declarations have already been added
       // if their first assignment could be pulled into the initializer.
@@ -284,7 +372,8 @@
           continue; // Discard unused constants declarations.
         }
         String name = context.getConstantName(constDecl.element);
-        Expression value = emitConstant(constDecl.expression, context);
+        Expression value =
+            ConstantEmitter.createExpression(constDecl.expression, context);
         VariableDeclaration decl = new VariableDeclaration(name, value);
         decl.element = constDecl.element;
         constants.add(decl);
@@ -307,94 +396,27 @@
         parameters,
         body,
         name: context.currentElement.name,
-        returnType: emitOptionalType(functionType.returnType),
+        returnType: TypeGenerator.createOptionalType(functionType.returnType),
         isGetter: context.currentElement.isGetter,
         isSetter: context.currentElement.isSetter)
         ..element = context.currentElement;
   }
 
-  /// TODO(johnniwinther): Remove this when issue 21283 has been resolved.
-  int pseudoNameCounter = 0;
-
-  Parameter emitParameter(DartType type,
-                          BuilderContext<Statement> context,
-                          {String name,
-                           Element element,
-                           ConstantExpression defaultValue}) {
-    if (name == null && element != null) {
-      name = element.name;
-    }
-    if (name == null) {
-      name = '_${pseudoNameCounter++}';
-    }
-    Parameter parameter;
-    if (type.isFunctionType) {
-      FunctionType functionType = type;
-      TypeAnnotation returnType = emitOptionalType(functionType.returnType);
-      Parameters innerParameters =
-          emitParametersFromType(functionType, context);
-      parameter = new Parameter.function(name, returnType, innerParameters);
-    } else {
-      TypeAnnotation typeAnnotation = emitOptionalType(type);
-      parameter = new Parameter(name, type: typeAnnotation);
-    }
-    parameter.element = element;
-    if (defaultValue != null && !defaultValue.value.isNull) {
-      parameter.defaultValue = emitConstant(defaultValue, context);
-    }
-    return parameter;
-  }
-
-  Parameters emitParametersFromType(FunctionType functionType,
-                                    BuilderContext<Statement> context) {
-    if (functionType.namedParameters.isEmpty) {
-      return new Parameters(
-          emitParameters(functionType.parameterTypes, context),
-          emitParameters(functionType.optionalParameterTypes, context),
-          false);
-    } else {
-      return new Parameters(
-          emitParameters(functionType.parameterTypes, context),
-          emitParameters(functionType.namedParameterTypes, context,
-                         names: functionType.namedParameters),
-          true);
-    }
-  }
-
-  List<Parameter> emitParameters(
-      Iterable<DartType> parameterTypes,
-      BuilderContext<Statement> context,
-      {Iterable<String> names: const <String>[],
-       Iterable<ConstantExpression> defaultValues: const <ConstantExpression>[],
-       Iterable<Element> elements: const <Element>[]}) {
-    Iterator<String> name = names.iterator;
-    Iterator<ConstantExpression> defaultValue = defaultValues.iterator;
-    Iterator<Element> element = elements.iterator;
-    return parameterTypes.map((DartType type) {
-      name.moveNext();
-      defaultValue.moveNext();
-      element.moveNext();
-      return emitParameter(type, context,
-                           name: name.current,
-                           defaultValue: defaultValue.current,
-                           element: element.current);
-    }).toList();
-  }
-
   /// Emits parameters that are not nested inside other parameters.
   /// Root parameters can have default values, while inner parameters cannot.
   Parameters emitRootParameters(tree.FunctionDefinition function,
                                 BuilderContext<Statement> context) {
     FunctionType functionType = function.element.type;
-    List<Parameter> required = emitParameters(
-        functionType.parameterTypes, context,
+    List<Parameter> required = TypeGenerator.createParameters(
+        functionType.parameterTypes,
+        context: context,
         elements: function.parameters.map((p) => p.element));
     bool optionalParametersAreNamed = !functionType.namedParameters.isEmpty;
-    List<Parameter> optional = emitParameters(
+    List<Parameter> optional = TypeGenerator.createParameters(
         optionalParametersAreNamed
             ? functionType.namedParameterTypes
             : functionType.optionalParameterTypes,
-        context,
+        context: context,
         defaultValues: function.defaultParameterValues,
         elements: function.parameters.skip(required.length)
             .map((p) => p.element));
@@ -536,8 +558,17 @@
   @override
   void visitReturn(tree.Return stmt,
                    BuilderContext<Statement> context) {
-    Expression inner = visitExpression(stmt.value, context);
-    context.addStatement(new Return(inner));
+    if (context.currentElement.isGenerativeConstructor &&
+        !context.inInitializer) {
+      assert(() {
+        tree.Expression value = stmt.value;
+        return value is tree.Constant && value.value.isNull;
+      });
+      context.addStatement(new Return(null));
+    } else {
+      Expression inner = visitExpression(stmt.value, context);
+      context.addStatement(new Return(inner));
+    }
   }
 
   @override
@@ -600,7 +631,7 @@
   @override
   Expression visitConstant(tree.Constant exp,
                            BuilderContext<Statement> context) {
-    return emitConstant(exp.expression, context);
+    return ConstantEmitter.createExpression(exp.expression, context);
   }
 
   @override
@@ -626,7 +657,8 @@
   Expression visitLiteralList(tree.LiteralList exp,
                               BuilderContext<Statement> context) {
     return new LiteralList(visitExpressions(exp.values, context),
-        typeArgument: emitOptionalType(exp.type.typeArguments.single));
+        typeArgument:
+            TypeGenerator.createOptionalType(exp.type.typeArguments.single));
   }
 
   @override
@@ -634,11 +666,12 @@
                              BuilderContext<Statement> context) {
     List<LiteralMapEntry> entries = new List<LiteralMapEntry>.generate(
         exp.entries.length,
-        (i) => new LiteralMapEntry(visitExpression(exp.entries[i].key, context),
-                                   visitExpression(exp.entries[i].value, context)));
+        (i) => new LiteralMapEntry(
+            visitExpression(exp.entries[i].key, context),
+            visitExpression(exp.entries[i].value, context)));
     List<TypeAnnotation> typeArguments = exp.type.treatAsRaw
         ? null
-        : exp.type.typeArguments.map(createTypeAnnotation)
+        : exp.type.typeArguments.map(TypeGenerator.createType)
              .toList(growable: false);
     return new LiteralMap(entries, typeArguments: typeArguments);
   }
@@ -648,22 +681,28 @@
                                BuilderContext<Statement> context) {
     return new TypeOperator(visitExpression(exp.receiver, context),
                             exp.operator,
-                            createTypeAnnotation(exp.type));
+                            TypeGenerator.createType(exp.type));
   }
 
-  List<Argument> emitArguments(tree.Invoke exp,
-                               BuilderContext<Statement> context) {
-    List<tree.Expression> args = exp.arguments;
-    int positionalArgumentCount = exp.selector.positionalArgumentCount;
+  List<Argument> emitArguments(List<Expression> arguments,
+                               Selector selector) {
+    int positionalArgumentCount = selector.positionalArgumentCount;
     List<Argument> result = new List<Argument>.generate(positionalArgumentCount,
-        (i) => visitExpression(exp.arguments[i], context));
-    for (int i = 0; i < exp.selector.namedArgumentCount; ++i) {
-      result.add(new NamedArgument(exp.selector.namedArguments[i],
-          visitExpression(exp.arguments[positionalArgumentCount + i], context)));
+        (i) => arguments[i]);
+    for (int i = 0; i < selector.namedArgumentCount; ++i) {
+      result.add(new NamedArgument(selector.namedArguments[i],
+          arguments[positionalArgumentCount + i]));
     }
     return result;
   }
 
+  List<Expression> visitArgumentList(List<tree.Expression> arguments,
+                                     BuilderContext context) {
+    return arguments
+        .map((tree.Expression argument) => visitExpression(argument, context))
+        .toList();
+  }
+
   @override
   Expression visitInvokeStatic(tree.InvokeStatic exp,
                                BuilderContext<Statement> context) {
@@ -679,8 +718,10 @@
 
       case SelectorKind.CALL:
         return new CallStatic(
-            null, exp.target.name, emitArguments(exp, context))
-                   ..element = exp.target;
+            null, exp.target.name,
+            emitArguments(visitArgumentList(exp.arguments, context),
+                          exp.selector))
+            ..element = exp.target;
 
       default:
         throw "Unexpected selector kind: ${exp.selector.kind}";
@@ -689,7 +730,8 @@
 
   Expression emitMethodCall(tree.Invoke exp, Receiver receiver,
                             BuilderContext<Statement> context) {
-    List<Argument> args = emitArguments(exp, context);
+    List<Argument> args =
+        emitArguments(visitArgumentList(exp.arguments, context), exp.selector);
     switch (exp.selector.kind) {
       case SelectorKind.CALL:
         if (exp.selector.name == "call") {
@@ -743,10 +785,11 @@
   @override
   Expression visitInvokeConstructor(tree.InvokeConstructor exp,
                                     BuilderContext<Statement> context) {
-    List args = emitArguments(exp, context);
+    List<Argument> args =
+        emitArguments(visitArgumentList(exp.arguments, context), exp.selector);
     FunctionElement constructor = exp.target;
     String name = constructor.name.isEmpty ? null : constructor.name;
-    return new CallNew(createTypeAnnotation(exp.type),
+    return new CallNew(TypeGenerator.createType(exp.type),
                        args,
                        constructorName: name,
                        isConst: exp.constant != null)
@@ -814,51 +857,165 @@
     visitStatement(node.next, context);
   }
 
-  Expression emitConstant(ConstantExpression exp,
-                          BuilderContext<Statement> context) {
-    return const ConstantEmitter().visit(exp, context);
-  }
-}
-
-/// Like [createTypeAnnotation] except the dynamic type is converted to null.
-TypeAnnotation emitOptionalType(DartType type) {
-  if (type.treatAsDynamic) {
-    return null;
-  } else {
-    return createTypeAnnotation(type);
-  }
-}
-
-TypeAnnotation createTypeAnnotation(DartType type) {
-  if (type is GenericType) {
-    if (type.treatAsRaw) {
-      return new TypeAnnotation(type.element.name)..dartType = type;
+  List<Statement> buildInInitializerContext(tree.Statement root,
+                                     BuilderContext context) {
+    BuilderContext inner = new BuilderContext<Statement>.initializer(context);
+    inner.currentElement = context.currentElement;
+    visitStatement(root, inner);
+    List<Statement> bodyParts;
+    for (tree.Variable variable in inner.variableNames.keys) {
+      if (!context.declaredVariables.contains(variable)) {
+        inner.addDeclaration(variable);
+      }
     }
-    return new TypeAnnotation(
-        type.element.name,
-        type.typeArguments.map(createTypeAnnotation).toList(growable:false))
-        ..dartType = type;
-  } else if (type is VoidType) {
-    return new TypeAnnotation('void')
-        ..dartType = type;
-  } else if (type is TypeVariableType) {
-    return new TypeAnnotation(type.name)
-        ..dartType = type;
-  } else if (type is DynamicType) {
-    return new TypeAnnotation("dynamic")
-        ..dartType = type;
-  } else if (type is MalformedType) {
-    return new TypeAnnotation(type.name)
-        ..dartType = type;
-  } else {
-    throw "Unsupported type annotation: $type";
+    if (inner.variables.length > 0) {
+      bodyParts = new List<Statement>();
+      bodyParts.add(new VariableDeclarations(inner.variables));
+      bodyParts.addAll(inner.statements);
+    } else {
+      bodyParts = inner.statements;
+    }
+    return bodyParts;
+  }
+
+  @override
+  Expression visitFieldInitializer(tree.FieldInitializer node,
+                                   BuilderContext<Statement> context) {
+    return new FieldInitializer(node.element,
+        ensureExpression(buildInInitializerContext(node.body, context)));
+  }
+
+  @override
+  Expression visitSuperInitializer(tree.SuperInitializer node,
+                                   BuilderContext<Statement> context) {
+    List<Argument> arguments = node.arguments.map((tree.Statement argument) {
+      return ensureExpression(buildInInitializerContext(argument, context));
+    }).toList();
+    return new SuperInitializer(node.target,
+                                emitArguments(arguments, node.selector));
   }
 }
 
+class TypeGenerator {
+
+  /// TODO(johnniwinther): Remove this when issue 21283 has been resolved.
+  static int pseudoNameCounter = 0;
+
+  static Parameter emitParameter(DartType type,
+                                 BuilderContext<Statement> context,
+                                 {String name,
+                                  Element element,
+                                  ConstantExpression defaultValue}) {
+    if (name == null && element != null) {
+      name = element.name;
+    }
+    if (name == null) {
+      name = '_${pseudoNameCounter++}';
+    }
+    Parameter parameter;
+    if (type.isFunctionType) {
+      FunctionType functionType = type;
+      TypeAnnotation returnType = createOptionalType(functionType.returnType);
+      Parameters innerParameters =
+          createParametersFromType(functionType);
+      parameter = new Parameter.function(name, returnType, innerParameters);
+    } else {
+      TypeAnnotation typeAnnotation = createOptionalType(type);
+      parameter = new Parameter(name, type: typeAnnotation);
+    }
+    parameter.element = element;
+    if (defaultValue != null && !defaultValue.value.isNull) {
+      parameter.defaultValue =
+          ConstantEmitter.createExpression(defaultValue, context);
+    }
+    return parameter;
+  }
+
+  static Parameters createParametersFromType(FunctionType functionType) {
+    pseudoNameCounter = 0;
+    if (functionType.namedParameters.isEmpty) {
+      return new Parameters(
+          createParameters(functionType.parameterTypes),
+          createParameters(functionType.optionalParameterTypes),
+          false);
+    } else {
+      return new Parameters(
+          createParameters(functionType.parameterTypes),
+          createParameters(functionType.namedParameterTypes,
+                         names: functionType.namedParameters),
+          true);
+    }
+  }
+
+  static List<Parameter> createParameters(
+      Iterable<DartType> parameterTypes,
+      {BuilderContext<Statement> context,
+       Iterable<String> names: const <String>[],
+       Iterable<ConstantExpression> defaultValues: const <ConstantExpression>[],
+       Iterable<Element> elements: const <Element>[]}) {
+    Iterator<String> name = names.iterator;
+    Iterator<ConstantExpression> defaultValue = defaultValues.iterator;
+    Iterator<Element> element = elements.iterator;
+    return parameterTypes.map((DartType type) {
+      name.moveNext();
+      defaultValue.moveNext();
+      element.moveNext();
+      return emitParameter(type, context,
+                           name: name.current,
+                           defaultValue: defaultValue.current,
+                           element: element.current);
+    }).toList();
+  }
+
+  /// Like [createTypeAnnotation] except the dynamic type is converted to null.
+  static TypeAnnotation createOptionalType(DartType type) {
+    if (type.treatAsDynamic) {
+      return null;
+    } else {
+      return createType(type);
+    }
+  }
+
+  /// Creates the [TypeAnnotation] for a [type] that is not function type.
+  static TypeAnnotation createType(DartType type) {
+    if (type is GenericType) {
+      if (type.treatAsRaw) {
+        return new TypeAnnotation(type.element.name)..dartType = type;
+      }
+      return new TypeAnnotation(
+          type.element.name,
+          type.typeArguments.map(createType).toList(growable:false))
+          ..dartType = type;
+    } else if (type is VoidType) {
+      return new TypeAnnotation('void')
+          ..dartType = type;
+    } else if (type is TypeVariableType) {
+      return new TypeAnnotation(type.name)
+          ..dartType = type;
+    } else if (type is DynamicType) {
+      return new TypeAnnotation("dynamic")
+          ..dartType = type;
+    } else if (type is MalformedType) {
+      return new TypeAnnotation(type.name)
+          ..dartType = type;
+    } else {
+      throw "Unsupported type annotation: $type";
+    }
+  }
+
+}
+
+
 class ConstantEmitter
     extends ConstantExpressionVisitor<BuilderContext<Statement>, Expression> {
   const ConstantEmitter();
 
+  /// Creates the [Expression] for the constant [exp].
+  static Expression createExpression(ConstantExpression exp,
+                                     BuilderContext<Statement> context) {
+    return const ConstantEmitter().visit(exp, context);
+  }
+
   Expression handlePrimitiveConstant(PrimitiveConstantValue value) {
     // Num constants may be negative, while literals must be non-negative:
     // Literals are non-negative in the specification, and a negated literal
@@ -909,7 +1066,8 @@
     return new LiteralList(
         visitExpressions(exp.values, context),
         isConst: true,
-        typeArgument: emitOptionalType(exp.type.typeArguments.single));
+        typeArgument:
+            TypeGenerator.createOptionalType(exp.type.typeArguments.single));
   }
 
   @override
@@ -921,7 +1079,7 @@
                                    visit(exp.values[i], context)));
     List<TypeAnnotation> typeArguments = exp.type.treatAsRaw
         ? null
-        : exp.type.typeArguments.map(createTypeAnnotation).toList();
+        : exp.type.typeArguments.map(TypeGenerator.createType).toList();
     return new LiteralMap(entries, isConst: true, typeArguments: typeArguments);
   }
 
@@ -939,7 +1097,7 @@
 
     FunctionElement constructor = exp.target;
     String name = constructor.name.isEmpty ? null : constructor.name;
-    return new CallNew(createTypeAnnotation(exp.type),
+    return new CallNew(TypeGenerator.createType(exp.type),
                        args,
                        constructorName: name,
                        isConst: true)
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
index 2d113ed..f9292a5 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_nodes.dart
@@ -306,6 +306,22 @@
 
 // EXPRESSIONS
 
+abstract class Initializer extends Expression {}
+
+class FieldInitializer extends Initializer {
+  final elements.FieldElement element;
+  final Expression body;
+
+  FieldInitializer(this.element, this.body);
+}
+
+class SuperInitializer extends Initializer {
+  final elements.ConstructorElement target;
+  final List<Argument> arguments;
+
+  SuperInitializer(this.target, this.arguments);
+}
+
 class FunctionExpression extends Expression implements ExecutableDefinition {
   final TypeAnnotation returnType;
   String name;
@@ -327,6 +343,15 @@
   }
 }
 
+class ConstructorDefinition extends FunctionExpression {
+  final List<Initializer> initializers;
+  final bool isConst;
+
+  ConstructorDefinition(Parameters parameters, Statement body,
+                        this.initializers, String name, this.isConst)
+      : super(parameters, body, name: name);
+}
+
 class Conditional extends Expression {
   final Expression condition;
   final Expression thenExpression;
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
index e0c50d2..c2381f6 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
@@ -12,7 +12,7 @@
 import '../scanner/scannerlib.dart';
 import '../util/util.dart';
 import 'backend_ast_nodes.dart';
-import 'backend_ast_emitter.dart' show createTypeAnnotation;
+import 'backend_ast_emitter.dart' show TypeGenerator;
 
 /// Translates the backend AST to Dart frontend AST.
 tree.Node emit(dart2js.TreeElementMapping treeElements,
@@ -138,6 +138,7 @@
   final Token extendsToken = makeIdToken('extends');
   final Token withToken = makeIdToken('with');
   final Token implementsToken = makeIdToken('implements');
+  final Token typedefToken = makeIdToken('typedef');
 
   static tree.Identifier makeIdentifier(String name) {
     return new tree.Identifier(
@@ -342,6 +343,31 @@
         setElement(result, element, exp);
       }
       precedence = EXPRESSION;
+    } else if (exp is FieldInitializer) {
+      precedence = EXPRESSION;
+      tree.Node receiver = makeIdentifier('this');
+      tree.Node selector = makeIdentifier(exp.element.name);
+      tree.Operator op = new tree.Operator(assignmentToken("="));
+      // We pass CALLEE to ensure we write eg.:
+      // class B { var x; B() : x = (() {return a;}) {}}
+      // Not the invalid:
+      // class B { var x; B() : x = () {return a;} {}}
+      result = new tree.SendSet(receiver, selector, op,
+                                singleton(makeExp(exp.body, CALLEE)));
+      setElement(result, exp.element, exp);
+    } else if (exp is SuperInitializer) {
+      precedence = EXPRESSION;
+      tree.Node receiver = makeIdentifier('super');
+      tree.NodeList arguments =
+          argList(exp.arguments.map(makeArgument).toList());
+      if (exp.target.name == "") {
+        result = new tree.Send(null, receiver, arguments);
+      } else {
+        result = new tree.Send(receiver,
+                               makeIdentifier(exp.target.name),
+                               arguments);
+      }
+      setElement(result, exp.target, exp);
     } else if (exp is BinaryOperator) {
       precedence = BINARY_PRECEDENCE[exp.operator];
       int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1;
@@ -422,6 +448,25 @@
           ? null
           : makeExp(exp.object, PRIMARY, beginStmt: beginStmt);
       result = new tree.Send(receiver, makeIdentifier(exp.fieldName));
+    } else if (exp is ConstructorDefinition) {
+      precedence = EXPRESSION;
+      tree.NodeList parameters = makeParameters(exp.parameters);
+      tree.NodeList initializers =
+          exp.initializers == null || exp.initializers.isEmpty
+          ? null
+          : makeList(",", exp.initializers.map(makeExpression).toList());
+      tree.Node body = exp.isConst || exp.body == null
+          ? new tree.EmptyStatement(semicolon)
+          : makeFunctionBody(exp.body);
+      result = new tree.FunctionExpression(constructorName(exp),
+          parameters,
+          body,
+          null,  // return type
+          makeFunctionModifiers(exp),
+          initializers,
+          null,  // get/set
+          null); // async modifier
+      setElement(result, exp.element, exp);
     } else if (exp is FunctionExpression) {
       precedence = PRIMARY;
       if (beginStmt && exp.name != null) {
@@ -1008,7 +1053,8 @@
     if (exp.element == null) return makeEmptyModifiers();
     return makeModifiers(isExternal: exp.element.isExternal,
                          isStatic: exp.element.isStatic,
-                         isFactory: exp.element.isFactoryConstructor);
+                         isFactory: exp.element.isFactoryConstructor,
+                         isConst: exp.element.isConst);
   }
 
   tree.Node makeNodeForClassElement(elements.ClassElement cls) {
@@ -1019,6 +1065,24 @@
     }
   }
 
+  tree.Typedef makeTypedef(elements.TypedefElement typdef) {
+    types.FunctionType functionType = typdef.alias;
+    final tree.TypeAnnotation returnType =
+        makeType(TypeGenerator.createType(functionType.returnType));
+
+    final tree.Identifier name = makeIdentifier(typdef.name);
+    final tree.NodeList typeParameters =
+        makeTypeParameters(typdef.typeVariables);
+    final tree.NodeList formals =
+        makeParameters(TypeGenerator.createParametersFromType(functionType));
+
+    final Token typedefKeyword = typedefToken;
+    final Token endToken = semicolon;
+
+    return new tree.Typedef(returnType, name, typeParameters, formals,
+          typedefKeyword, endToken);
+  }
+
   /// Create a [tree.NodeList] containing the type variable declarations in
   /// [typeVaraiables.
   tree.NodeList makeTypeParameters(List<types.DartType> typeVariables) {
@@ -1031,7 +1095,8 @@
         treeElements[id] = typeVariable.element;
         tree.Node bound;
         if (!typeVariable.element.bound.isObject) {
-          bound = makeType(createTypeAnnotation(typeVariable.element.bound));
+          bound =
+              makeType(TypeGenerator.createType(typeVariable.element.bound));
         }
         tree.TypeVariable node = new tree.TypeVariable(id, bound);
         treeElements.setType(node, typeVariable);
@@ -1060,8 +1125,8 @@
          link = link.tail) {
       types.DartType interface = link.head;
       if (!mixinTypes.contains(interface)) {
-        typeAnnotations =
-            typeAnnotations.prepend(makeType(createTypeAnnotation(interface)));
+        typeAnnotations = typeAnnotations.prepend(
+            makeType(TypeGenerator.createType(interface)));
       }
     }
     if (typeAnnotations.isEmpty) {
@@ -1091,7 +1156,7 @@
 
     void addMixin(types.DartType mixinType) {
       mixinTypes.add(mixinType);
-      mixins = mixins.prepend(makeType(createTypeAnnotation(mixinType)));
+      mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType)));
     }
 
     addMixin(cls.mixinType);
@@ -1104,7 +1169,7 @@
       supertype = mixinApplication.supertype;
     }
     superclass =
-        makeType(createTypeAnnotation(cls.asInstanceOf(supertype.element)));
+        makeType(TypeGenerator.createType(cls.asInstanceOf(supertype.element)));
     tree.Node supernode = new tree.MixinApplication(
         superclass, new tree.NodeList(null, mixins, null, ','));
 
@@ -1131,7 +1196,7 @@
 
     void addMixin(types.DartType mixinType) {
       mixinTypes.add(mixinType);
-      mixins = mixins.prepend(makeType(createTypeAnnotation(mixinType)));
+      mixins = mixins.prepend(makeType(TypeGenerator.createType(mixinType)));
     }
 
     if (supertype != null) {
@@ -1142,12 +1207,12 @@
           addMixin(cls.asInstanceOf(mixinApplication.mixin));
           supertype = mixinApplication.supertype;
         }
-        tree.Node superclass =
-            makeType(createTypeAnnotation(cls.asInstanceOf(supertype.element)));
+        tree.Node superclass = makeType(
+            TypeGenerator.createType(cls.asInstanceOf(supertype.element)));
         supernode = new tree.MixinApplication(
             superclass, new tree.NodeList(null, mixins, null, ','));
       } else if (!supertype.isObject) {
-        supernode = makeType(createTypeAnnotation(supertype));
+        supernode = makeType(TypeGenerator.createType(supertype));
       }
     }
     tree.NodeList interfaces = makeInterfaces(
@@ -1161,6 +1226,16 @@
         closeBrace);
   }
 
+  tree.Node constructorName(ConstructorDefinition exp) {
+    String name = exp.name;
+    tree.Identifier className = makeIdentifier(exp.element.enclosingClass.name);
+    tree.Node result = name == ""
+        ? className
+        : new tree.Send(className, makeIdentifier(name));
+    setElement(result, exp.element, exp);
+    return result;
+  }
+
   tree.Node functionName(FunctionExpression exp) {
     String name = exp.name;
     if (name == null) return null;
diff --git a/pkg/compiler/lib/src/dart_backend/dart_backend.dart b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
index abb5d26..32be177 100644
--- a/pkg/compiler/lib/src/dart_backend/dart_backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/dart_backend.dart
@@ -32,6 +32,7 @@
                                          CLOSE_PAREN_INFO,
                                          SEMICOLON_INFO,
                                          IDENTIFIER_INFO;
+import '../js_backend/codegen/glue.dart';
 
 part 'backend.dart';
 part 'renamer.dart';
diff --git a/pkg/compiler/lib/src/dart_backend/outputter.dart b/pkg/compiler/lib/src/dart_backend/outputter.dart
index f705c52..4b8f22d 100644
--- a/pkg/compiler/lib/src/dart_backend/outputter.dart
+++ b/pkg/compiler/lib/src/dart_backend/outputter.dart
@@ -388,13 +388,17 @@
     backend2frontend.TreePrinter treePrinter =
         new backend2frontend.TreePrinter(treeElements);
     Node node = treePrinter.makeNodeForClassElement(classElement);
-    addTopLevel(classElement, new ElementAst.internal(node, treeElements));
+    addTopLevel(classElement, new ElementAst(node, treeElements));
     classMembers.putIfAbsent(classElement, () => new Set());
   }
 
   void newTypedefElementCallback(TypedefElement element) {
     if (!shouldOutput(element)) return;
-    addTopLevel(element, new ElementAst(element));
+    TreeElements treeElements = new TreeElementMapping(element);
+    backend2frontend.TreePrinter treePrinter =
+        new backend2frontend.TreePrinter(treeElements);
+    Node node = treePrinter.makeTypedef(element);
+    addTopLevel(element, new ElementAst(node, treeElements));
   }
 
   void newClassElementCallback(ClassElement classElement) {
diff --git a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
index 2b98939b..c403119 100644
--- a/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
+++ b/pkg/compiler/lib/src/dart_backend/placeholder_collector.dart
@@ -619,12 +619,14 @@
         id != null && Keyword.keywords[id.source] != null;
 
     Element element = treeElements[node];
-    // May get null here in case of A(int this.f());
+    // May get null;
     if (element != null) {
       tryMakePrivateIdentifier(node.name, element);
 
       // Rename only local functions.
-      if (topmostEnclosingFunction == null) {
+      if (topmostEnclosingFunction == null &&
+          element is! LocalParameterElement &&
+          element is! InitializingFormalElement) {
         topmostEnclosingFunction = element;
       }
       if (!identical(element, currentElement)) {
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index 22d949d..db5d2b8 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -6,6 +6,7 @@
 
 import 'dart:math' show min;
 
+import 'core_types.dart';
 import 'dart2jslib.dart' show Compiler, invariant, Script, Message;
 import 'elements/modelx.dart'
     show VoidElementX,
@@ -921,8 +922,9 @@
  */
 abstract class AbstractTypeRelation extends DartTypeVisitor<bool, DartType> {
   final Compiler compiler;
+  CoreTypes get coreTypes => compiler.coreTypes;
 
-  AbstractTypeRelation(Compiler this.compiler);
+  AbstractTypeRelation(this.compiler);
 
   bool visitType(DartType t, DartType s) {
     throw 'internal error: unknown type kind ${t.kind}';
@@ -972,7 +974,7 @@
   }
 
   bool visitFunctionType(FunctionType t, DartType s) {
-    if (s is InterfaceType && identical(s.element, compiler.functionClass)) {
+    if (s == coreTypes.functionType) {
       return true;
     }
     if (s is !FunctionType) return false;
@@ -1102,8 +1104,7 @@
   MoreSpecificVisitor(Compiler compiler) : super(compiler);
 
   bool isMoreSpecific(DartType t, DartType s) {
-    if (identical(t, s) || s.treatAsDynamic ||
-        identical(t.element, compiler.nullClass)) {
+    if (identical(t, s) || s.treatAsDynamic || t == coreTypes.nullType) {
       return true;
     }
     if (t.isVoid || s.isVoid) {
@@ -1112,7 +1113,7 @@
     if (t.treatAsDynamic) {
       return false;
     }
-    if (identical(s.element, compiler.objectClass)) {
+    if (s == coreTypes.objectType) {
       return true;
     }
     t = t.unalias(compiler);
@@ -1173,9 +1174,7 @@
   bool visitInterfaceType(InterfaceType t, DartType s) {
     if (super.visitInterfaceType(t, s)) return true;
 
-    if (s is InterfaceType &&
-        s.element == compiler.functionClass &&
-        t.element.callType != null) {
+    if (s == coreTypes.functionType && t.element.callType != null) {
       return true;
     } else if (s is FunctionType) {
       FunctionType callType = t.callType;
@@ -1195,12 +1194,24 @@
                                     TypeVariableType typeVariable,
                                     DartType bound);
 
-class Types {
+/// Basic interface for the Dart type system.
+abstract class DartTypes {
+  /// The types defined in 'dart:core'.
+  CoreTypes get coreTypes;
+
+  /// Returns `true` if [t] is a subtype of [s].
+  bool isSubtype(DartType t, DartType s);
+}
+
+class Types implements DartTypes {
+  // TODO(johnniwinther): Replace by [CoreTypes].
   final Compiler compiler;
   final MoreSpecificVisitor moreSpecificVisitor;
   final SubtypeVisitor subtypeVisitor;
   final PotentialSubtypeVisitor potentialSubtypeVisitor;
 
+  CoreTypes get coreTypes => compiler.coreTypes;
+
   Types(Compiler compiler)
       : this.compiler = compiler,
         this.moreSpecificVisitor = new MoreSpecificVisitor(compiler),
@@ -1500,7 +1511,7 @@
   DartType computeLeastUpperBoundFunctionTypes(FunctionType a,
                                                FunctionType b) {
     if (a.parameterTypes.length != b.parameterTypes.length) {
-      return compiler.functionClass.rawType;
+      return coreTypes.functionType;
     }
     DartType returnType = computeLeastUpperBound(a.returnType, b.returnType);
     List<DartType> parameterTypes =
@@ -1582,10 +1593,10 @@
     }
 
     if (a.isFunctionType) {
-      a = compiler.functionClass.rawType;
+      a = coreTypes.functionType;
     }
     if (b.isFunctionType) {
-      b = compiler.functionClass.rawType;
+      b = coreTypes.functionType;
     }
 
     if (a.isInterfaceType && b.isInterfaceType) {
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index ae262b7..f11b654 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -425,7 +425,7 @@
         ConstantExpression constant =
             backend.constants.getConstantForMetadata(metadata);
         if (constant != null) {
-          _mapDependencies(constant.value.computeType(compiler).element,
+          _mapDependencies(constant.value.getType(compiler.coreTypes).element,
               deferredImport);
         }
       }
@@ -434,7 +434,7 @@
           ConstantExpression constant =
               backend.constants.getConstantForMetadata(metadata);
           if (constant != null) {
-            _mapDependencies(constant.value.computeType(compiler).element,
+            _mapDependencies(constant.value.getType(compiler.coreTypes).element,
                 deferredImport);
           }
         }
@@ -469,7 +469,7 @@
         for (MetadataAnnotation metadata in metadatas) {
           metadata.ensureResolved(compiler);
           Element element =
-              metadata.constant.value.computeType(compiler).element;
+              metadata.constant.value.getType(compiler.coreTypes).element;
           if (element == deferredLibraryClass) {
             ConstructedConstantValue constant = metadata.constant.value;
             StringConstantValue s = constant.fields[0];
@@ -657,7 +657,7 @@
             for (MetadataAnnotation metadata in metadataList) {
               metadata.ensureResolved(compiler);
               Element element =
-                  metadata.constant.value.computeType(compiler).element;
+                  metadata.constant.value.getType(compiler.coreTypes).element;
               if (element == deferredLibraryClass) {
                  compiler.reportFatalError(
                      import, MessageKind.DEFERRED_OLD_SYNTAX);
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 65ea6bc..c2b3e41 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -11,6 +11,7 @@
 import '../universe/universe.dart';
 import '../util/util.dart';
 import '../types/types.dart' show TypeMask;
+import '../types/constants.dart' show computeTypeMask;
 import 'dart:collection' show IterableMixin;
 
 /**
@@ -750,7 +751,7 @@
     // The JavaScript backend may turn this literal into an integer at
     // runtime.
     return types.getConcreteTypeFor(
-        constantSystem.createDouble(node.value).computeMask(compiler));
+        computeTypeMask(compiler, constantSystem.createDouble(node.value)));
   }
 
   T visitLiteralInt(LiteralInt node) {
@@ -758,7 +759,7 @@
     // The JavaScript backend may turn this literal into a double at
     // runtime.
     return types.getConcreteTypeFor(
-        constantSystem.createInt(node.value).computeMask(compiler));
+        computeTypeMask(compiler, constantSystem.createInt(node.value)));
   }
 
   T visitLiteralList(LiteralList node) {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index ae3427a..f60b4c5 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -35,6 +35,8 @@
          TypeMask,
          TypesInferrer,
          ValueTypeMask;
+import '../types/constants.dart'
+    show computeTypeMask;
 import '../universe/universe.dart'
     show Selector,
          SideEffects,
@@ -807,7 +809,7 @@
                 // Although we might find a better type, we have to keep
                 // the old type around to ensure that we get a complete view
                 // of the type graph and do not drop any flow edges.
-                TypeMask refinedType = value.computeMask(compiler);
+                TypeMask refinedType = computeTypeMask(compiler, value);
                 assert(TypeMask.assertIsNormalized(refinedType, classWorld));
                 type = new NarrowTypeInformation(type, refinedType);
                 types.allocatedTypes.add(type);
diff --git a/pkg/compiler/lib/src/js/builder.dart b/pkg/compiler/lib/src/js/builder.dart
index cb002da..c79d537 100644
--- a/pkg/compiler/lib/src/js/builder.dart
+++ b/pkg/compiler/lib/src/js/builder.dart
@@ -327,6 +327,8 @@
 
   LiteralNumber number(num value) => new LiteralNumber('$value');
 
+  LiteralBool boolean(bool value) => new LiteralBool(value);
+
   ArrayInitializer numArray(Iterable<int> list) =>
       new ArrayInitializer(list.map(number).toList());
 
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index d6932e5..a606660 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -764,7 +764,7 @@
 
   void registerCompileTimeConstantInternal(ConstantValue constant,
                                            Registry registry) {
-    DartType type = constant.computeType(compiler);
+    DartType type = constant.getType(compiler.coreTypes);
     registerInstantiatedConstantType(type, registry);
 
     if (constant.isFunction) {
@@ -1951,7 +1951,7 @@
       metadata.ensureResolved(compiler);
       ConstantValue value = metadata.constant.value;
       if (value == null) continue;
-      DartType type = value.computeType(compiler);
+      DartType type = value.getType(compiler.coreTypes);
       if (metaTargetsUsed.contains(type.element)) return true;
     }
     return false;
diff --git a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
index 26fa923..05bacf5 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/codegen.dart
@@ -170,7 +170,6 @@
                                   Element target,
                                   List<js.Expression> arguments) {
     registry.registerStaticInvocation(target.declaration);
-
     js.Expression elementAccess = glue.staticFunctionAccess(target);
     List<js.Expression> compiledArguments =
         selector.makeArgumentsList(target.implementation,
@@ -197,20 +196,17 @@
 
   @override
   js.Expression visitInvokeMethod(tree_ir.InvokeMethod node) {
-    // TODO(sigurdm): Handle intercepted invocations.
-    if (glue.isIntercepted(node.selector)) giveup(node);
-    js.Expression receiver = visitExpression(node.receiver);
-
-    List<js.Expression> arguments = visitArguments(node.arguments);
-
-    String methodName = glue.invocationName(node.selector);
     registerMethodInvoke(node);
-
-    return js.propertyCall(receiver, methodName, arguments);
+    return js.propertyCall(visitExpression(node.receiver),
+                           glue.invocationName(node.selector),
+                           visitArguments(node.arguments));
   }
 
   @override
   js.Expression visitInvokeStatic(tree_ir.InvokeStatic node) {
+    if (node.target is! FunctionElement) {
+      giveup(node, 'static getters and setters are not supported.');
+    }
     return buildStaticInvoke(node.selector,
                              node.target,
                              visitArguments(node.arguments));
@@ -416,4 +412,16 @@
     accumulator.add(new js.Return(visitExpression(node.value)));
   }
 
+  @override
+  js.Expression visitFieldInitializer(tree_ir.FieldInitializer node) {
+    return giveup(node);
+    // TODO: implement FieldInitializer
+  }
+
+  @override
+  js.Expression visitSuperInitializer(tree_ir.SuperInitializer node) {
+    return giveup(node);
+    // TODO: implement SuperInitializer
+  }
+
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/glue.dart b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
index 2bdc115..d15a458 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/glue.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/glue.dart
@@ -62,8 +62,21 @@
     return _namer.invocationName(selector);
   }
 
-  bool isIntercepted(Selector selector) {
+  FunctionElement get getInterceptorMethod => _backend.getInterceptorMethod;
+
+  void registerUseInterceptorInCodegen() {
+    _backend.registerUseInterceptor(_compiler.enqueuer.codegen);
+  }
+
+  bool isInterceptedSelector(Selector selector) {
     return _backend.isInterceptedSelector(selector);
   }
 
+  Set<ClassElement> getInterceptedClassesOn(Selector selector) {
+    return _backend.getInterceptedClassesOn(selector.name);
+  }
+
+  void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
+    _backend.registerSpecializedGetInterceptor(classes);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/js_tree_builder.dart b/pkg/compiler/lib/src/js_backend/codegen/js_tree_builder.dart
new file mode 100644
index 0000000..32dde10
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/codegen/js_tree_builder.dart
@@ -0,0 +1,51 @@
+// 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 js_tree_ir_builder;
+
+import '../../tree_ir/tree_ir_builder.dart' show Builder;
+import 'glue.dart' show Glue;
+import '../../dart2jslib.dart' show Selector, InternalErrorFunction;
+import '../../elements/elements.dart';
+import '../../cps_ir/cps_ir_nodes.dart' as cps_ir;
+import '../../tree_ir/tree_ir_nodes.dart';
+
+/// Subclass of [Builder] that can translate nodes which are specific to the
+/// JavaScript backend.
+class JsTreeBuilder extends Builder {
+  final Glue _glue;
+  final Element identicalFunction;
+
+  JsTreeBuilder(
+      InternalErrorFunction internalError,
+      this.identicalFunction,
+      this._glue,
+      [Builder parent])
+    : super(internalError, parent);
+
+  JsTreeBuilder createInnerBuilder() {
+    return new JsTreeBuilder(internalError, identicalFunction, _glue, this);
+  }
+
+  Selector get identicalSelector {
+    return new Selector.call('identical', null, 2);
+  }
+
+  Expression visitIdentical(cps_ir.Identical node) {
+    return new InvokeStatic(
+        identicalFunction,
+        identicalSelector,
+        <Expression>[getVariableReference(node.left),
+                     getVariableReference(node.right)]);
+  }
+
+  Expression visitInterceptor(cps_ir.Interceptor node) {
+    Element getInterceptor = _glue.getInterceptorMethod;
+    _glue.registerUseInterceptorInCodegen();
+    return new InvokeStatic(
+        getInterceptor,
+        new Selector.fromElement(getInterceptor),
+        <Expression>[getVariableReference(node.input)]);
+  }
+}
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index 68e1d5b..8345894 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -16,6 +16,8 @@
 import '../../cps_ir/cps_ir_builder.dart';
 import '../../tree_ir/tree_ir_nodes.dart' as tree_ir;
 import '../../tree/tree.dart' as ast;
+import '../../types/types.dart' show TypeMask, UnionTypeMask, FlatTypeMask,
+    ForwardingTypeMask;
 import '../../scanner/scannerlib.dart' as scanner;
 import '../../elements/elements.dart';
 import '../../closure.dart';
@@ -28,6 +30,8 @@
 import '../../js_backend/codegen/codegen.dart';
 import '../../ssa/ssa.dart' as ssa;
 import '../../tree_ir/optimization/optimization.dart';
+import '../../cps_ir/cps_ir_nodes_sexpr.dart';
+import 'js_tree_builder.dart';
 
 class CspFunctionCompiler implements FunctionCompiler {
   final IrBuilderTask irBuilderTask;
@@ -35,6 +39,8 @@
   final Compiler compiler;
   final Glue glue;
 
+  TypeSystem types;
+
   // TODO(karlklose,sigurm): remove and update dart-doc of [compile].
   final FunctionCompiler fallbackCompiler;
 
@@ -55,6 +61,7 @@
   /// features not implemented it will fall back to the ssa pipeline (for
   /// platform code) or will cancel compilation (for user code).
   js.Fun compile(CodegenWorkItem work) {
+    types = new TypeMaskSystem(compiler);
     AstElement element = work.element;
     return compiler.withCurrentElement(element, () {
       try {
@@ -103,16 +110,49 @@
     if (cpsNode == null) {
       giveUp('unable to build cps definition of $element');
     }
-    const UnsugarVisitor().rewrite(cpsNode);
+    new UnsugarVisitor(glue).rewrite(cpsNode);
     return cpsNode;
   }
 
+  static const Pattern PRINT_TYPED_IR_FILTER = null;
+
+  String formatTypeMask(TypeMask type) {
+    if (type is UnionTypeMask) {
+      return '[${type.disjointMasks.map(formatTypeMask).join(', ')}]';
+    } else if (type is FlatTypeMask) {
+      if (type.isEmpty) {
+        return "null";
+      }
+      String suffix = (type.isExact ? "" : "+") + (type.isNullable ? "?" : "!");
+      return '${type.base.name}$suffix';
+    } else if (type is ForwardingTypeMask) {
+      return formatTypeMask(type.forwardTo);
+    }
+    throw 'unsupported: $type';
+  }
+
   cps.FunctionDefinition optimizeCpsIR(cps.FunctionDefinition cpsNode) {
     // Transformations on the CPS IR.
     traceGraph("IR Builder", cpsNode);
-    new ConstantPropagator(compiler, constantSystem)
-        .rewrite(cpsNode);
+
+    TypePropagator typePropagator = new TypePropagator<TypeMask>(
+        compiler.types,
+        constantSystem,
+        new TypeMaskSystem(compiler),
+        compiler.internalError);
+    typePropagator.rewrite(cpsNode);
     traceGraph("Sparse constant propagation", cpsNode);
+
+    if (PRINT_TYPED_IR_FILTER != null &&
+        PRINT_TYPED_IR_FILTER.matchAsPrefix(cpsNode.element.name) != null) {
+      String printType(cps.Node node, String s) {
+        var type = typePropagator.getType(node);
+        return type == null ? s : "$s:${formatTypeMask(type.type)}";
+      }
+      DEBUG_MODE = true;
+      print(new SExpressionStringifier(printType).visit(cpsNode));
+    }
+
     new RedundantPhiEliminator().rewrite(cpsNode);
     traceGraph("Redundant phi elimination", cpsNode);
     new ShrinkingReducer().rewrite(cpsNode);
@@ -126,7 +166,8 @@
   }
 
   tree_ir.FunctionDefinition compileToTreeIR(cps.FunctionDefinition cpsNode) {
-    tree_builder.Builder builder = new tree_builder.Builder(compiler);
+    tree_builder.Builder builder = new JsTreeBuilder(
+        compiler.internalError, compiler.identicalFunction, glue);
     tree_ir.FunctionDefinition treeNode = builder.buildFunction(cpsNode);
     assert(treeNode != null);
     traceGraph('Tree builder', treeNode);
@@ -194,5 +235,4 @@
   SourceFile sourceFileOfElement(Element element) {
     return element.implementation.compilationUnit.script.file;
   }
-
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
index 1dc3627..41eeb38 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/unsugar.dart
@@ -6,6 +6,9 @@
 import '../../cps_ir/optimizers.dart';
 import '../../constants/expressions.dart';
 import '../../constants/values.dart';
+import '../../elements/elements.dart' show ClassElement;
+import '../../js_backend/codegen/glue.dart';
+import '../../dart2jslib.dart' show Selector;
 
 /// Rewrites the initial CPS IR to make Dart semantics explicit and inserts
 /// special nodes that respect JavaScript behavior.
@@ -13,7 +16,9 @@
 /// Performs the following rewrites:
 ///  - rewrite [IsTrue] in a [Branch] to do boolean conversion.
 class UnsugarVisitor extends RecursiveVisitor {
-  const UnsugarVisitor();
+  Glue _glue;
+
+  UnsugarVisitor(this._glue);
 
   void rewrite(FunctionDefinition function) {
     // Set all parent pointers.
@@ -33,6 +38,37 @@
             new TrueConstantValue()));
   }
 
+  processInvokeMethod(InvokeMethod node) {
+    Selector selector = node.selector;
+    if (!_glue.isInterceptedSelector(selector)) return;
+
+    if (!selector.isCall && !selector.isOperator) {
+      // TODO(karlklose): handle special selectors.
+      return;
+    }
+
+    Set<ClassElement> interceptedClasses =
+        _glue.getInterceptedClassesOn(selector);
+    _glue.registerSpecializedGetInterceptor(interceptedClasses);
+    InteriorNode parent = node.parent;
+    Primitive receiver = node.receiver.definition;
+    Primitive intercepted = new Interceptor(receiver, interceptedClasses);
+    List<Reference<Primitive>> arguments =
+        new List<Reference<Primitive>>.generate(node.arguments.length + 1,
+        (int index) {
+          return index == 0 ? new Reference<Primitive>(receiver)
+                            : node.arguments[index - 1];
+    });
+    LetPrim newNode = new LetPrim(intercepted,
+        new InvokeMethod.internal(new Reference<Primitive>(intercepted),
+            selector,
+            new Reference<Continuation>(node.continuation.definition),
+            arguments));
+    node.continuation.unlink();
+    node.receiver.unlink();
+    parent.body = newNode;
+  }
+
   processBranch(Branch node) {
     // TODO(karlklose): implement the checked mode part of boolean conversion.
     InteriorNode parent = node.parent;
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 5f1cdc4..4abea1c 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -55,7 +55,7 @@
  * Do not use directly, use methods from [ConstantEmitter].
  */
 class ConstantReferenceEmitter
-    implements ConstantValueVisitor<jsAst.Expression> {
+    implements ConstantValueVisitor<jsAst.Expression, Null> {
   final Compiler compiler;
   final Namer namer;
 
@@ -64,13 +64,13 @@
   ConstantReferenceEmitter(this.compiler, this.namer, this.constantEmitter);
 
   JavaScriptBackend get backend => compiler.backend;
-  
+
   jsAst.Expression generate(ConstantValue constant) {
     return _visit(constant);
   }
 
   jsAst.Expression _visit(ConstantValue constant) {
-    return constant.accept(this);
+    return constant.accept(this, null);
   }
 
   jsAst.Expression emitCanonicalVersion(ConstantValue constant) {
@@ -83,27 +83,28 @@
       return constantEmitter.literal(constant);
   }
 
-  jsAst.Expression visitFunction(FunctionConstantValue constant) {
+  @override
+  jsAst.Expression visitFunction(FunctionConstantValue constant, [_]) {
     return backend.emitter.isolateStaticClosureAccess(constant.element);
   }
 
-  jsAst.Expression visitNull(NullConstantValue constant) {
+  @override
+  jsAst.Expression visitNull(NullConstantValue constant, [_]) {
     return literal(constant);
   }
 
-  jsAst.Expression visitInt(IntConstantValue constant) {
+  @override
+  jsAst.Expression visitInt(IntConstantValue constant, [_]) {
     return literal(constant);
   }
 
-  jsAst.Expression visitDouble(DoubleConstantValue constant) {
+  @override
+  jsAst.Expression visitDouble(DoubleConstantValue constant, [_]) {
     return literal(constant);
   }
 
-  jsAst.Expression visitTrue(TrueConstantValue constant) {
-    return literal(constant);
-  }
-
-  jsAst.Expression visitFalse(FalseConstantValue constant) {
+  @override
+  jsAst.Expression visitBool(BoolConstantValue constant, [_]) {
     return literal(constant);
   }
 
@@ -112,38 +113,46 @@
    * a form that is valid as JavaScript string literal content.
    * The string is assumed quoted by double quote characters.
    */
-  jsAst.Expression visitString(StringConstantValue constant) {
+  @override
+  jsAst.Expression visitString(StringConstantValue constant, [_]) {
     // TODO(sra): If the string is long *and repeated* (and not on a hot path)
     // then it should be assigned to a name.  We don't have reference counts (or
     // profile information) here, so this is the wrong place.
     return literal(constant);
   }
 
-  jsAst.Expression visitList(ListConstantValue constant) {
+  @override
+  jsAst.Expression visitList(ListConstantValue constant, [_]) {
     return emitCanonicalVersion(constant);
   }
 
-  jsAst.Expression visitMap(MapConstantValue constant) {
+  @override
+  jsAst.Expression visitMap(MapConstantValue constant, [_]) {
     return emitCanonicalVersion(constant);
   }
 
-  jsAst.Expression visitType(TypeConstantValue constant) {
+  @override
+  jsAst.Expression visitType(TypeConstantValue constant, [_]) {
     return emitCanonicalVersion(constant);
   }
 
-  jsAst.Expression visitConstructed(ConstructedConstantValue constant) {
+  @override
+  jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) {
     return emitCanonicalVersion(constant);
   }
 
-  jsAst.Expression visitInterceptor(InterceptorConstantValue constant) {
+  @override
+  jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) {
     return emitCanonicalVersion(constant);
   }
 
-  jsAst.Expression visitDummy(DummyConstantValue constant) {
+  @override
+  jsAst.Expression visitDummy(DummyConstantValue constant, [_]) {
     return literal(constant);
   }
 
-  jsAst.Expression visitDeferred(DeferredConstantValue constant) {
+  @override
+  jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) {
     return emitCanonicalVersion(constant);
   }
 }
@@ -153,7 +162,8 @@
  * [ConstantValue]s. These can be used for inlining constants or in
  * initializers. Do not use directly, use methods from [ConstantEmitter].
  */
-class ConstantLiteralEmitter implements ConstantValueVisitor<jsAst.Expression> {
+class ConstantLiteralEmitter
+    implements ConstantValueVisitor<jsAst.Expression, Null> {
 
   // Matches blank lines, comment lines and trailing comments that can't be part
   // of a string.
@@ -175,24 +185,28 @@
   }
 
   jsAst.Expression _visit(ConstantValue constant) {
-    return constant.accept(this);
+    return constant.accept(this, null);
   }
 
-  jsAst.Expression visitFunction(FunctionConstantValue constant) {
+  @override
+  jsAst.Expression visitFunction(FunctionConstantValue constant, [_]) {
     compiler.internalError(NO_LOCATION_SPANNABLE,
         "The function constant does not need specific JS code.");
     return null;
   }
 
-  jsAst.Expression visitNull(NullConstantValue constant) {
+  @override
+  jsAst.Expression visitNull(NullConstantValue constant, [_]) {
     return new jsAst.LiteralNull();
   }
 
-  jsAst.Expression visitInt(IntConstantValue constant) {
+  @override
+  jsAst.Expression visitInt(IntConstantValue constant, [_]) {
     return new jsAst.LiteralNumber('${constant.primitiveValue}');
   }
 
-  jsAst.Expression visitDouble(DoubleConstantValue constant) {
+  @override
+  jsAst.Expression visitDouble(DoubleConstantValue constant, [_]) {
     double value = constant.primitiveValue;
     if (value.isNaN) {
       return js("0/0");
@@ -205,21 +219,18 @@
     }
   }
 
-  jsAst.Expression visitTrue(TrueConstantValue constant) {
+  @override
+  jsAst.Expression visitBool(BoolConstantValue constant, [_]) {
     if (compiler.enableMinification) {
-      // Use !0 for true.
-      return js("!0");
+      if (constant.isTrue) {
+        // Use !0 for true.
+        return js("!0");
+      } else {
+        // Use !1 for false.
+        return js("!1");
+      }
     } else {
-      return js('true');
-    }
-  }
-
-  jsAst.Expression visitFalse(FalseConstantValue constant) {
-    if (compiler.enableMinification) {
-      // Use !1 for false.
-      return js("!1");
-    } else {
-      return js('false');
+      return constant.isTrue ? js('true') : js('false');
     }
   }
 
@@ -228,13 +239,15 @@
    * a form that is valid as JavaScript string literal content.
    * The string is assumed quoted by double quote characters.
    */
-  jsAst.Expression visitString(StringConstantValue constant) {
+  @override
+  jsAst.Expression visitString(StringConstantValue constant, [_]) {
     StringBuffer sb = new StringBuffer();
     writeJsonEscapedCharsOn(constant.primitiveValue.slowToString(), sb);
     return new jsAst.LiteralString('"$sb"');
   }
 
-  jsAst.Expression visitList(ListConstantValue constant) {
+  @override
+  jsAst.Expression visitList(ListConstantValue constant, [_]) {
     List<jsAst.Expression> elements = _array(constant.entries);
     jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements);
     jsAst.Expression value = makeConstantListTemplate.instantiate([array]);
@@ -245,7 +258,8 @@
     return backend.emitter.classAccess(element);
   }
 
-  jsAst.Expression visitMap(JavaScriptMapConstant constant) {
+  @override
+  jsAst.Expression visitMap(JavaScriptMapConstant constant, [_]) {
     jsAst.Expression jsMap() {
       List<jsAst.Property> properties = <jsAst.Property>[];
       for (int i = 0; i < constant.length; i++) {
@@ -327,7 +341,8 @@
     return backend.emitter.staticFunctionAccess(helper);
   }
 
-  jsAst.Expression visitType(TypeConstantValue constant) {
+  @override
+  jsAst.Expression visitType(TypeConstantValue constant, [_]) {
     DartType type = constant.representedType;
     String name = namer.getRuntimeTypeName(type.element);
     jsAst.Expression typeName = new jsAst.LiteralString("'$name'");
@@ -335,17 +350,20 @@
                           [typeName]);
   }
 
-  jsAst.Expression visitInterceptor(InterceptorConstantValue constant) {
+  @override
+  jsAst.Expression visitInterceptor(InterceptorConstantValue constant, [_]) {
     return new jsAst.PropertyAccess.field(
         getJsConstructor(constant.dispatchedType.element),
         'prototype');
   }
 
-  jsAst.Expression visitDummy(DummyConstantValue constant) {
+  @override
+  jsAst.Expression visitDummy(DummyConstantValue constant, [_]) {
     return new jsAst.LiteralNumber('0');
   }
 
-  jsAst.Expression visitConstructed(ConstructedConstantValue constant) {
+  @override
+  jsAst.Expression visitConstructed(ConstructedConstantValue constant, [_]) {
     Element element = constant.type.element;
     if (element.isForeign(backend)
         && element.name == 'JS_CONST') {
@@ -385,7 +403,8 @@
     return value;
   }
 
-  jsAst.Expression visitDeferred(DeferredConstantValue constant) {
+  @override
+  jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) {
     return constantEmitter.reference(constant.referenced);
   }
 }
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index 3d6e72f..9afb0884 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -233,21 +233,21 @@
   bool isBool(ConstantValue constant) => constant.isBool;
   bool isNull(ConstantValue constant) => constant.isNull;
 
-  bool isSubtype(Compiler compiler, DartType s, DartType t) {
+  bool isSubtype(DartTypes types, DartType s, DartType t) {
     // At runtime, an integer is both an integer and a double: the
     // integer type check is Math.floor, which will return true only
     // for real integers, and our double type check is 'typeof number'
     // which will return true for both integers and doubles.
-    if (s.element == compiler.intClass && t.element == compiler.doubleClass) {
+    if (s == types.coreTypes.intType && t == types.coreTypes.doubleType) {
       return true;
     }
-    return compiler.types.isSubtype(s, t);
+    return types.isSubtype(s, t);
   }
 
   MapConstantValue createMap(Compiler compiler,
-                        InterfaceType sourceType,
-                        List<ConstantValue> keys,
-                        List<ConstantValue> values) {
+                             InterfaceType sourceType,
+                             List<ConstantValue> keys,
+                             List<ConstantValue> values) {
     JavaScriptBackend backend = compiler.backend;
 
     bool onlyStringKeys = true;
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 2675aa8..6ba5f26 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -990,6 +990,13 @@
     }
   }
 
+  String get incrementalHelperName => r'$dart_unsafe_eval';
+
+  jsAst.Expression get accessIncrementalHelper {
+    assert(compiler.hasIncrementalSupport);
+    return js('self.${incrementalHelperName}');
+  }
+
   void forgetElement(Element element) {
     String globalName = globals[element];
     invariant(element, globalName != null, message: 'No global name.');
@@ -1079,19 +1086,22 @@
     }
   }
 
-  _visit(ConstantValue constant) {
-    return constant.accept(this);
+  void _visit(ConstantValue constant) {
+    constant.accept(this, null);
   }
 
-  visitFunction(FunctionConstantValue constant) {
+  @override
+  void visitFunction(FunctionConstantValue constant, [_]) {
     add(constant.element.name);
   }
 
-  visitNull(NullConstantValue constant) {
+  @override
+  void visitNull(NullConstantValue constant, [_]) {
     add('null');
   }
 
-  visitInt(IntConstantValue constant) {
+  @override
+  void visitInt(IntConstantValue constant, [_]) {
     // No `addRoot` since IntConstants are always inlined.
     if (constant.primitiveValue < 0) {
       add('m${-constant.primitiveValue}');
@@ -1100,24 +1110,24 @@
     }
   }
 
-  visitDouble(DoubleConstantValue constant) {
+  @override
+  void visitDouble(DoubleConstantValue constant, [_]) {
     failed = true;
   }
 
-  visitTrue(TrueConstantValue constant) {
-    add('true');
+  @override
+  void visitBool(BoolConstantValue constant, [_]) {
+    add(constant.isTrue ? 'true' : 'false');
   }
 
-  visitFalse(FalseConstantValue constant) {
-    add('false');
-  }
-
-  visitString(StringConstantValue constant) {
+  @override
+  void visitString(StringConstantValue constant, [_]) {
     // No `addRoot` since string constants are always inlined.
     addIdentifier(constant.primitiveValue.slowToString());
   }
 
-  visitList(ListConstantValue constant) {
+  @override
+  void visitList(ListConstantValue constant, [_]) {
     // TODO(9476): Incorporate type parameters into name.
     addRoot('List');
     int length = constant.length;
@@ -1133,7 +1143,8 @@
     }
   }
 
-  visitMap(JavaScriptMapConstant constant) {
+  @override
+  void visitMap(JavaScriptMapConstant constant, [_]) {
     // TODO(9476): Incorporate type parameters into name.
     addRoot('Map');
     if (constant.length == 0) {
@@ -1145,7 +1156,8 @@
     }
   }
 
-  visitConstructed(ConstructedConstantValue constant) {
+  @override
+  void visitConstructed(ConstructedConstantValue constant, [_]) {
     addRoot(constant.type.element.name);
     for (int i = 0; i < constant.fields.length; i++) {
       _visit(constant.fields[i]);
@@ -1153,7 +1165,8 @@
     }
   }
 
-  visitType(TypeConstantValue constant) {
+  @override
+  void visitType(TypeConstantValue constant, [_]) {
     addRoot('Type');
     DartType type = constant.representedType;
     JavaScriptBackend backend = compiler.backend;
@@ -1161,16 +1174,19 @@
     addIdentifier(name);
   }
 
-  visitInterceptor(InterceptorConstantValue constant) {
+  @override
+  void visitInterceptor(InterceptorConstantValue constant, [_]) {
     addRoot(constant.dispatchedType.element.name);
     add('methods');
   }
 
-  visitDummy(DummyConstantValue constant) {
+  @override
+  void visitDummy(DummyConstantValue constant, [_]) {
     add('dummy_receiver');
   }
 
-  visitDeferred(DeferredConstantValue constant) {
+  @override
+  void visitDeferred(DeferredConstantValue constant, [_]) {
     addRoot('Deferred');
   }
 }
@@ -1183,7 +1199,7 @@
  * between runs by basing hash values of the names of elements, rather than
  * their hashCodes.
  */
-class ConstantCanonicalHasher implements ConstantValueVisitor<int> {
+class ConstantCanonicalHasher implements ConstantValueVisitor<int, Null> {
 
   static const _MASK = 0x1fffffff;
   static const _UINT32_LIMIT = 4 * 1024 * 1024 * 1024;
@@ -1199,40 +1215,53 @@
   int _visit(ConstantValue constant) {
     int hash = hashes[constant];
     if (hash == null) {
-      hash = _finish(constant.accept(this));
+      hash = _finish(constant.accept(this, null));
       hashes[constant] = hash;
     }
     return hash;
   }
 
-  int visitNull(NullConstantValue constant) => 1;
-  int visitTrue(TrueConstantValue constant) => 2;
-  int visitFalse(FalseConstantValue constant) => 3;
+  @override
+  int visitNull(NullConstantValue constant, [_]) => 1;
 
-  int visitFunction(FunctionConstantValue constant) {
+  @override
+  int visitBool(BoolConstantValue constant, [_]) {
+    return constant.isTrue ? 2 : 3;
+  }
+
+  @override
+  int visitFunction(FunctionConstantValue constant, [_]) {
     return _hashString(1, constant.element.name);
   }
 
-  int visitInt(IntConstantValue constant) => _hashInt(constant.primitiveValue);
+  @override
+  int visitInt(IntConstantValue constant, [_]) {
+    return _hashInt(constant.primitiveValue);
+  }
 
-  int visitDouble(DoubleConstantValue constant) {
+  @override
+  int visitDouble(DoubleConstantValue constant, [_]) {
     return _hashDouble(constant.primitiveValue);
   }
 
-  int visitString(StringConstantValue constant) {
+  @override
+  int visitString(StringConstantValue constant, [_]) {
     return _hashString(2, constant.primitiveValue.slowToString());
   }
 
-  int visitList(ListConstantValue constant) {
+  @override
+  int visitList(ListConstantValue constant, [_]) {
     return _hashList(constant.length, constant.entries);
   }
 
-  int visitMap(MapConstantValue constant) {
+  @override
+  int visitMap(MapConstantValue constant, [_]) {
     int hash = _hashList(constant.length, constant.keys);
     return _hashList(hash, constant.values);
   }
 
-  int visitConstructed(ConstructedConstantValue constant) {
+  @override
+  int visitConstructed(ConstructedConstantValue constant, [_]) {
     int hash = _hashString(3, constant.type.element.name);
     for (int i = 0; i < constant.fields.length; i++) {
       hash = _combine(hash, _visit(constant.fields[i]));
@@ -1240,26 +1269,30 @@
     return hash;
   }
 
-  int visitType(TypeConstantValue constant) {
+  @override
+  int visitType(TypeConstantValue constant, [_]) {
     DartType type = constant.representedType;
     JavaScriptBackend backend = compiler.backend;
     String name = backend.rti.getTypeRepresentationForTypeConstant(type);
     return _hashString(4, name);
   }
 
-  visitInterceptor(InterceptorConstantValue constant) {
+  @override
+  int visitInterceptor(InterceptorConstantValue constant, [_]) {
     String typeName = constant.dispatchedType.element.name;
     return _hashString(5, typeName);
   }
 
-  visitDummy(DummyConstantValue constant) {
+  @override
+  visitDummy(DummyConstantValue constant, [_]) {
     compiler.internalError(NO_LOCATION_SPANNABLE,
         'DummyReceiverConstant should never be named and never be subconstant');
   }
 
-  visitDeferred(DeferredConstantValue constant) {
+  @override
+  int visitDeferred(DeferredConstantValue constant, [_]) {
     int hash = constant.prefix.hashCode;
-    return _combine(hash, constant.referenced.accept(this));
+    return _combine(hash, _visit(constant.referenced));
   }
 
   int _hashString(int hash, String s) {
diff --git a/pkg/compiler/lib/src/js_backend/native_emitter.dart b/pkg/compiler/lib/src/js_backend/native_emitter.dart
index fe81f43..4d2008c 100644
--- a/pkg/compiler/lib/src/js_backend/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/native_emitter.dart
@@ -279,16 +279,6 @@
   }
 
   ClassBuilder generateNativeClass(ClassElement classElement) {
-    ClassBuilder builder;
-    if (compiler.hasIncrementalSupport) {
-      builder = cachedBuilders[classElement];
-      if (builder != null) return builder;
-      builder = new ClassBuilder(classElement, backend.namer);
-      cachedBuilders[classElement] = builder;
-    } else {
-      builder = new ClassBuilder(classElement, backend.namer);
-    }
-
     // TODO(sra): Issue #13731- this is commented out as part of custom element
     // constructor work.
     //assert(!classElement.hasBackendMembers);
@@ -304,10 +294,21 @@
 
     String superName = backend.namer.getNameOfClass(superclass);
 
+    ClassBuilder builder;
+    if (compiler.hasIncrementalSupport) {
+      builder = cachedBuilders[classElement];
+      if (builder != null) return builder;
+      builder = new ClassBuilder(classElement, backend.namer);
+      cachedBuilders[classElement] = builder;
+    } else {
+      builder = new ClassBuilder(classElement, backend.namer);
+    }
+    builder.superName = superName;
+
     emitterTask.oldEmitter.classEmitter.emitClassConstructor(
         classElement, builder);
     bool hasFields = emitterTask.oldEmitter.classEmitter.emitFields(
-        classElement, builder, superName, classIsNative: true);
+        classElement, builder, classIsNative: true);
     int propertyCount = builder.properties.length;
     emitterTask.oldEmitter.classEmitter.emitClassGettersSetters(
         classElement, builder);
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 0aaf241..6dcc012 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -347,21 +347,24 @@
 
     backend.generatedCode.keys.forEach(addSurroundingLibraryToSet);
     neededClasses.forEach(addSurroundingLibraryToSet);
-}
+  }
+
+  void computeAllNeededEntities() {
+    // Compute the required type checks to know which classes need a
+    // 'is$' method.
+    typeTestRegistry.computeRequiredTypeChecks();
+
+    computeNeededDeclarations();
+    computeNeededConstants();
+    computeNeededStatics();
+    computeNeededLibraries();
+  }
 
   void assembleProgram() {
     measure(() {
       emitter.invalidateCaches();
 
-      // Compute the required type checks to know which classes need a
-      // 'is$' method.
-      typeTestRegistry.computeRequiredTypeChecks();
-
-      computeNeededDeclarations();
-      computeNeededConstants();
-      computeNeededStatics();
-      computeNeededLibraries();
-
+      computeAllNeededEntities();
 
       Program program;
       if (USE_NEW_EMITTER) {
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index 1d16321..81e1a95 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -71,7 +71,8 @@
     $z;
 
 import '../util/util.dart' show
-    NO_LOCATION_SPANNABLE;
+    NO_LOCATION_SPANNABLE,
+    Setlet;
 
 import '../util/uri_extras.dart' show
     relativize;
@@ -82,7 +83,6 @@
 import '../deferred_load.dart' show
     OutputUnit;
 
-import 'package:_internal/compiler/js_lib/shared/runtime_data.dart' as encoding;
 import 'package:_internal/compiler/js_lib/shared/embedded_names.dart'
     as embeddedNames;
 
@@ -92,6 +92,7 @@
 part 'code_emitter_task.dart';
 part 'helpers.dart';
 part 'interceptor_stub_generator.dart';
+part 'type_test_generator.dart';
 part 'type_test_registry.dart';
 
 part 'old_emitter/class_builder.dart';
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/class_builder.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/class_builder.dart
index db06675..c065090 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/class_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/class_builder.dart
@@ -34,16 +34,27 @@
     fields.add(field);
   }
 
+  static String functionTypeEncodingDescription =
+      'For simple function types the function type is stored in the metadata '
+      'and the index is encoded into the superclass field.';
+
+  static String fieldEncodingDescription =
+      'Fields are encoded as a comma separated list. If there is a superclass '
+      '(and possibly a function type encoding) the fields are separated from '
+      'the superclass by a semicolon.';
+
   jsAst.ObjectInitializer toObjectInitializer(
-      {bool omitClassDescriptor: false}) {
+      {bool emitClassDescriptor: true}) {
     StringBuffer buffer = new StringBuffer();
     if (superName != null) {
-      buffer.write('$superName');
+      buffer.write(superName);
       if (functionType != null) {
+        // See [functionTypeEncodingDescription] above.
         buffer.write(':$functionType');
       }
       buffer.write(';');
     }
+    // See [fieldEncodingDescription] above.
     buffer.writeAll(fields, ',');
     var classData = js.string('$buffer');
     if (fieldMetadata != null) {
@@ -54,13 +65,12 @@
           new jsAst.ArrayInitializer([classData]..addAll(fieldMetadata));
     }
     List<jsAst.Property> fieldsAndProperties;
-    if (!omitClassDescriptor) {
+    if (emitClassDescriptor) {
       fieldsAndProperties = <jsAst.Property>[];
       fieldsAndProperties.add(
           new jsAst.Property(
               js.string(namer.classDescriptorProperty), classData));
-      fieldsAndProperties
-          ..addAll(properties);
+      fieldsAndProperties.addAll(properties);
     } else {
       fieldsAndProperties = properties;
     }
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
index 5461648..d8fc4d5 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/class_emitter.dart
@@ -39,8 +39,9 @@
     }
 
     ClassBuilder builder = new ClassBuilder(classElement, namer);
+    builder.superName = superName;
     emitClassConstructor(classElement, builder, onlyForRti: onlyForRti);
-    emitFields(classElement, builder, superName, onlyForRti: onlyForRti);
+    emitFields(classElement, builder, onlyForRti: onlyForRti);
     emitClassGettersSetters(classElement, builder, onlyForRti: onlyForRti);
     emitInstanceMembers(classElement, builder, onlyForRti: onlyForRti);
     emitter.typeTestEmitter.emitIsTests(classElement, builder);
@@ -91,7 +92,6 @@
   /// Returns `true` if fields added.
   bool emitFields(Element element,
                   ClassBuilder builder,
-                  String superName,
                   { bool classIsNative: false,
                     bool emitStatics: false,
                     bool onlyForRti: false }) {
@@ -102,12 +102,6 @@
       throw new SpannableAssertionFailure(
           element, 'Must be a ClassElement or a LibraryElement');
     }
-    if (emitStatics) {
-      assert(invariant(element, superName == null, message: superName));
-    } else {
-      assert(invariant(element, superName != null));
-      builder.superName = superName;
-    }
     var fieldMetadata = [];
     bool hasMetadata = false;
     bool fieldsAdded = false;
@@ -311,7 +305,7 @@
 
     List<jsAst.Property> statics = new List<jsAst.Property>();
     ClassBuilder staticsBuilder = new ClassBuilder(classElement, namer);
-    if (emitFields(classElement, staticsBuilder, null, emitStatics: true)) {
+    if (emitFields(classElement, staticsBuilder, emitStatics: true)) {
       jsAst.ObjectInitializer initializer =
         staticsBuilder.toObjectInitializer();
       compiler.dumpInfoTask.registerElementAst(classElement,
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
index 09e1d7e..5b981ea 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/emitter.dart
@@ -159,8 +159,10 @@
       => '${namer.isolateName}.\$finishIsolateConstructor';
   String get isolatePropertiesName
       => '${namer.isolateName}.${namer.isolatePropertiesName}';
+  String get lazyInitializerProperty
+      => r'$lazy';
   String get lazyInitializerName
-      => '${namer.isolateName}.\$lazy';
+      => '${namer.isolateName}.${lazyInitializerProperty}';
   String get initName => 'init';
   String get makeConstListProperty
       => namer.getMappedInstanceName('makeConstantList');
@@ -353,7 +355,7 @@
 
     if (compiler.hasIncrementalSupport) {
       result.add(
-          js(r'self.$dart_unsafe_eval.defineClass = defineClass'));
+          js(r'#.defineClass = defineClass', [namer.accessIncrementalHelper]));
     }
 
     if (hasIsolateSupport) {
@@ -409,6 +411,17 @@
           function tmp() {}
           var hasOwnProperty = Object.prototype.hasOwnProperty;
           return function (constructor, superConstructor) {
+            if (superConstructor == null) {
+              // TODO(21896): this test shouldn't be necessary. Without it
+              // we have a crash in language/mixin_only_for_rti and
+              // pkg/analysis_server/tool/spec/check_all_test.
+              if (constructor == null) return;
+
+              // Fix up the the Dart Object class' prototype.
+              var prototype = constructor.prototype;
+              prototype.constructor = constructor;
+              return prototype;
+            }
             tmp.prototype = superConstructor.prototype;
             var object = new tmp();
             var properties = constructor.prototype;
@@ -424,7 +437,8 @@
         }()
       ''');
     if (compiler.hasIncrementalSupport) {
-      result = js(r'self.$dart_unsafe_eval.inheritFrom = #', [result]);
+      result = js(
+          r'#.inheritFrom = #', [namer.accessIncrementalHelper, result]);
     }
     return js(r'var inheritFrom = #', [result]);
   }
@@ -513,9 +527,11 @@
                 classData instanceof Array) {
               classData = fields = classData[0];
             }
+          // ${ClassBuilder.fieldEncodingDescription}.
           var s = fields.split(";");
           fields = s[1] == "" ? [] : s[1].split(",");
           supr = s[0];
+          // ${ClassBuilder.functionTypeEncodingDescription}.
           split = supr.split(":");
           if (split.length == 2) {
             supr = split[0];
@@ -526,19 +542,6 @@
                 })(functionSignature);
           }
 
-          if (#needsMixinSupport)
-            if (supr && supr.indexOf("+") > 0) {
-              s = supr.split("+");
-              supr = s[0];
-              var mixin = collectedClasses[s[1]];
-              if (mixin instanceof Array) mixin = mixin[1];
-              for (var d in mixin) {
-                if (hasOwnProperty.call(mixin, d) &&
-                    !hasOwnProperty.call(desc, d))
-                  desc[d] = mixin[d];
-              }
-            }
-
           if (typeof dart_precompiled != "function") {
             combinedConstructorFunction += defineClass(cls, fields);
             constructorsList.push(cls);
@@ -581,7 +584,6 @@
               'debugFastObjects': DEBUG_FAST_OBJECTS,
               'hasRetainedMetadata': backend.hasRetainedMetadata,
               'metadata': metadataAccess,
-              'needsMixinSupport': needsMixinSupport,
               'isTreeShakingDisabled': backend.isTreeShakingDisabled,
               'finishClassFunction': buildFinishClass(),
               'trivialNsmHandlers': nsmEmitter.buildTrivialNsmHandlers()});
@@ -611,11 +613,37 @@
         finishedClasses[cls] = true;
 
         var superclass = pendingClasses[cls];
+
+        if (#needsMixinSupport) {
+          if (superclass && superclass.indexOf("+") > 0) {
+            var s = superclass.split("+");
+            superclass = s[0];
+            var mixinClass = s[1];
+            finishClass(mixinClass);
+            var mixin = allClasses[mixinClass];
+            // TODO(21896): this test shouldn't be necessary. Without it
+            // we have a crash in language/mixin_only_for_rti and
+            // pkg/analysis_server/tool/spec/check_all_test.
+            if (mixin) {
+              var mixinPrototype = mixin.prototype;
+              var clsPrototype = allClasses[cls].prototype;
+              for (var d in mixinPrototype) {
+                if (hasOwnProperty.call(mixinPrototype, d) &&
+                    !hasOwnProperty.call(clsPrototype, d))
+                  clsPrototype[d] = mixinPrototype[d];
+              }
+            }
+          }
+        }
+
         // The superclass is only false (empty string) for the Dart Object
         // class.  The minifier together with noSuchMethod can put methods on
         // the Object.prototype object, and they show through here, so we check
         // that we have a string.
-        if (!superclass || typeof superclass != "string") return;
+        if (!superclass || typeof superclass != "string") {
+          inheritFrom(allClasses[cls], null);
+          return;
+        }
         finishClass(superclass);
         var superConstructor = allClasses[superclass];
 
@@ -676,6 +704,7 @@
         }
       }
     }''', {'finishedClassesAccess': finishedClassesAccess,
+           'needsMixinSupport': needsMixinSupport,
            'hasNativeClasses': nativeClasses.isNotEmpty,
            'interceptorsByTagAccess': interceptorsByTagAccess,
            'leafTagsAccess': leafTagsAccess,
@@ -688,9 +717,10 @@
     //
     // We also copy over old values like the prototype, and the
     // isolateProperties themselves.
-    return js('''
+    return js(
+        """
       function (oldIsolate) {
-        var isolateProperties = oldIsolate.#;  // isolatePropertiesName
+        var isolateProperties = oldIsolate.#isolatePropertiesName;
         function Isolate() {
           var hasOwnProperty = Object.prototype.hasOwnProperty;
           for (var staticName in isolateProperties)
@@ -722,17 +752,25 @@
         }
         Isolate.prototype = oldIsolate.prototype;
         Isolate.prototype.constructor = Isolate;
-        Isolate.# = isolateProperties;  // isolatePropertiesName
-        if (#)  // needsDefineClass.
-          Isolate.# = oldIsolate.#;  // finishClassesProperty * 2
-        if (#)  // outputContainsConstantList
-          Isolate.# = oldIsolate.#; // makeConstListProperty * 2
-        return Isolate;
-      }''',
-        [namer.isolatePropertiesName, namer.isolatePropertiesName,
-         needsDefineClass, finishClassesProperty, finishClassesProperty,
-         task.outputContainsConstantList,
-         makeConstListProperty, makeConstListProperty ]);
+        Isolate.#isolatePropertiesName = isolateProperties;
+        if (#needsDefineClass)
+          Isolate.#finishClassesProperty = oldIsolate.#finishClassesProperty;
+        if (#outputContainsConstantList)
+          Isolate.#makeConstListProperty = oldIsolate.#makeConstListProperty;
+        if (#hasIncrementalSupport)
+          Isolate.#lazyInitializerProperty =
+              oldIsolate.#lazyInitializerProperty;
+         return Isolate;
+      }
+""",
+        { 'isolatePropertiesName': namer.isolatePropertiesName,
+          'needsDefineClass': needsDefineClass,
+          'finishClassesProperty': finishClassesProperty,
+          'outputContainsConstantList': task.outputContainsConstantList,
+          'makeConstListProperty': makeConstListProperty,
+          'hasIncrementalSupport': compiler.hasIncrementalSupport,
+          'lazyInitializerProperty': lazyInitializerProperty,
+        });
   }
 
   jsAst.Fun get lazyInitializerFunction {
@@ -994,7 +1032,8 @@
     }
   }
 
-  void emitStaticNonFinalFieldInitializations(CodeBuffer buffer) {
+  void emitStaticNonFinalFieldInitializations(CodeBuffer buffer,
+                                              OutputUnit outputUnit) {
     JavaScriptConstantCompiler handler = backend.constants;
     Iterable<VariableElement> staticNonFinalFields =
         handler.getStaticNonFinalFieldsForEmission();
@@ -1004,11 +1043,25 @@
       // `mapTypeToInterceptor` is handled in [emitMapTypeToInterceptor].
       if (element == backend.mapTypeToInterceptor) continue;
       compiler.withCurrentElement(element, () {
-        ConstantValue initialValue = handler.getInitialValueFor(element).value;
+        jsAst.Expression initialValue;
+        if (outputUnit !=
+            compiler.deferredLoadTask.outputUnitForElement(element)) {
+          if (outputUnit == compiler.deferredLoadTask.mainOutputUnit) {
+            // In the main output-unit we output a stub initializer for deferred
+            // variables, such that `isolateProperties` stays a fast object.
+            initialValue = jsAst.number(0);
+          } else {
+            // Don't output stubs outside the main output file.
+            return;
+          }
+        } else {
+          initialValue = constantEmitter.referenceInInitializationContext(
+              handler.getInitialValueFor(element).value);
+
+        }
         jsAst.Expression init =
           js('$isolateProperties.# = #',
-              [namer.getNameOfGlobalField(element),
-               constantEmitter.referenceInInitializationContext(initialValue)]);
+              [namer.getNameOfGlobalField(element), initialValue]);
         buffer.write(jsAst.prettyPrint(init, compiler,
                                        monitor: compiler.dumpInfoTask));
         buffer.write('$N');
@@ -1023,30 +1076,37 @@
     if (!lazyFields.isEmpty) {
       needsLazyInitializer = true;
       for (VariableElement element in Elements.sortedByPosition(lazyFields)) {
-        jsAst.Expression code = backend.generatedCode[element];
-        // The code is null if we ended up not needing the lazily
-        // initialized field after all because of constant folding
-        // before code generation.
-        if (code == null) continue;
-        // The code only computes the initial value. We build the lazy-check
-        // here:
-        //   lazyInitializer(prototype, 'name', fieldName, getterName, initial);
-        // The name is used for error reporting. The 'initial' must be a
-        // closure that constructs the initial value.
-        jsAst.Expression init = js('#(#,#,#,#,#)',
-            [js(lazyInitializerName),
-                js(isolateProperties),
-                js.string(element.name),
-                js.string(namer.getNameX(element)),
-                js.string(namer.getLazyInitializerName(element)),
-                code]);
-        buffer.write(jsAst.prettyPrint(init, compiler,
-                                       monitor: compiler.dumpInfoTask));
+        jsAst.Expression init =
+            buildLazilyInitializedStaticField(element, isolateProperties);
+        if (init == null) continue;
+        buffer.write(
+            jsAst.prettyPrint(init, compiler, monitor: compiler.dumpInfoTask));
         buffer.write("$N");
       }
     }
   }
 
+  jsAst.Expression buildLazilyInitializedStaticField(
+      VariableElement element, String isolateProperties) {
+    jsAst.Expression code = backend.generatedCode[element];
+    // The code is null if we ended up not needing the lazily
+    // initialized field after all because of constant folding
+    // before code generation.
+    if (code == null) return null;
+    // The code only computes the initial value. We build the lazy-check
+    // here:
+    //   lazyInitializer(prototype, 'name', fieldName, getterName, initial);
+    // The name is used for error reporting. The 'initial' must be a
+    // closure that constructs the initial value.
+    return js('#(#,#,#,#,#)',
+        [js(lazyInitializerName),
+            js(isolateProperties),
+            js.string(element.name),
+            js.string(namer.getNameX(element)),
+            js.string(namer.getLazyInitializerName(element)),
+            code]);
+  }
+
   bool isConstantInlinedOrAlreadyEmitted(ConstantValue constant) {
     if (constant.isFunction) return true;    // Already emitted.
     if (constant.isPrimitive) return true;   // Inlined.
@@ -1092,10 +1152,7 @@
         if (cachedEmittedConstants.contains(constant)) continue;
         cachedEmittedConstants.add(constant);
       }
-      String name = namer.constantName(constant);
-      jsAst.Expression init = js('#.# = #',
-          [namer.globalObjectForConstant(constant), name,
-           constantInitializerExpression(constant)]);
+      jsAst.Expression init = buildConstantInitializer(constant);
       buffer.write(jsAst.prettyPrint(init, compiler,
                                      monitor: compiler.dumpInfoTask));
       buffer.write('$N');
@@ -1105,6 +1162,13 @@
     }
   }
 
+  jsAst.Expression buildConstantInitializer(ConstantValue constant) {
+    String name = namer.constantName(constant);
+    return js('#.# = #',
+              [namer.globalObjectForConstant(constant), name,
+               constantInitializerExpression(constant)]);
+  }
+
   jsAst.Template get makeConstantListTemplate {
     // TODO(floitsch): there is no harm in caching the template.
     return jsAst.js.uncachedExpressionTemplate(
@@ -1424,7 +1488,7 @@
     for (LibraryElement element in libraries) {
       LibraryElement library = element;
       ClassBuilder builder = new ClassBuilder(library, namer);
-      if (classEmitter.emitFields(library, builder, null, emitStatics: true)) {
+      if (classEmitter.emitFields(library, builder, emitStatics: true)) {
         jsAst.ObjectInitializer initializer = builder.toObjectInitializer();
         compiler.dumpInfoTask.registerElementAst(builder.element, initializer);
         getElementDescriptor(library).properties.addAll(initializer.properties);
@@ -1444,12 +1508,18 @@
       // TODO(karlklose): add a TypedefBuilder and move this code there.
       DartType type = typedef.alias;
       int typeIndex = metadataEmitter.reifyType(type);
-      String typeReference =
-          encoding.encodeTypedefFieldDescriptor(typeIndex);
-      jsAst.Property descriptor = new jsAst.Property(
-          js.string(namer.classDescriptorProperty),
-          js.string(typeReference));
-      jsAst.Node declaration = new jsAst.ObjectInitializer([descriptor]);
+      ClassBuilder builder = new ClassBuilder(typedef, namer);
+      builder.addProperty(embeddedNames.TYPEDEF_TYPE_PROPERTY_NAME,
+                          js.number(typeIndex));
+      builder.addProperty(embeddedNames.TYPEDEF_PREDICATE_PROPERTY_NAME,
+                          js.boolean(true));
+
+      // We can be pretty sure that the objectClass is initialized, since
+      // typedefs are only emitted with reflection, which requires lots of
+      // classes.
+      assert(compiler.objectClass != null);
+      builder.superName = namer.getNameOfClass(compiler.objectClass);
+      jsAst.Node declaration = builder.toObjectInitializer();
       String mangledName = namer.getNameX(typedef);
       String reflectionName = getReflectionName(typedef, mangledName);
       getElementDescriptor(library)
@@ -1549,19 +1619,22 @@
     // Chrome/V8.
     mainBuffer.add('(function(${namer.currentIsolate})$_{\n');
     if (compiler.hasIncrementalSupport) {
-      mainBuffer.add(
-          'this.\$dart_unsafe_eval ='
-          ' this.\$dart_unsafe_eval || Object.create(null)$N');
-      mainBuffer.add(
-          'this.\$dart_unsafe_eval.patch = function(a) { eval(a) }$N');
-      String schemaChange =
-          jsAst.prettyPrint(buildSchemaChangeFunction(), compiler).getText();
-      String addMethod =
-          jsAst.prettyPrint(buildIncrementalAddMethod(), compiler).getText();
-      mainBuffer.add(
-          'this.\$dart_unsafe_eval.schemaChange$_=$_$schemaChange$N');
-      mainBuffer.add(
-          'this.\$dart_unsafe_eval.addMethod$_=$_$addMethod$N');
+      mainBuffer.add(jsAst.prettyPrint(js.statement(
+          """
+{
+  #helper = #helper || Object.create(null);
+  #helper.patch = function(a) { eval(a)};
+  #helper.schemaChange = #schemaChange;
+  #helper.addMethod = #addMethod;
+  #helper.extractStubs = function(array, name, isStatic, originalDescriptor) {
+    var descriptor = Object.create(null);
+    this.addStubs(descriptor, array, name, isStatic, originalDescriptor, []);
+    return descriptor;
+  };
+}""",
+          { 'helper': js('this.#', [namer.incrementalHelperName]),
+            'schemaChange': buildSchemaChangeFunction(),
+            'addMethod': buildIncrementalAddMethod() }), compiler));
     }
     if (isProgramSplit) {
       /// We collect all the global state of the, so it can be passed to the
@@ -1598,7 +1671,8 @@
     emitStaticFunctions(task.outputStaticLists[mainOutputUnit]);
 
     // Only output the classesCollector if we actually have any classes.
-    if (!(nativeClasses.isEmpty &&
+    if (needsDefineClass ||
+        !(nativeClasses.isEmpty &&
           compiler.codegenWorld.staticFunctionsNeedingGetter.isEmpty &&
           outputClassLists.values.every((classList) => classList.isEmpty) &&
           typedefsNeededForReflection.isEmpty)) {
@@ -1652,7 +1726,6 @@
       emitFinishClassesInvocationIfNecessary(mainBuffer);
     }
 
-    typeTestEmitter.emitRuntimeTypeSupport(mainBuffer, mainOutputUnit);
     interceptorEmitter.emitGetInterceptorMethods(mainBuffer);
     interceptorEmitter.emitOneShotInterceptors(mainBuffer);
 
@@ -1670,7 +1743,7 @@
 
     // Static field initializations require the classes and compile-time
     // constants to be set up.
-    emitStaticNonFinalFieldInitializations(mainBuffer);
+    emitStaticNonFinalFieldInitializations(mainBuffer, mainOutputUnit);
     interceptorEmitter.emitInterceptedNames(mainBuffer);
     interceptorEmitter.emitMapTypeToInterceptor(mainBuffer);
     emitLazilyInitializedStaticFields(mainBuffer);
@@ -1805,10 +1878,20 @@
   if (arrayOrFunction.constructor === Array) {
     var existing = holder[name];
     var array = arrayOrFunction;
-    var descriptor = Object.create(null);
-    this.addStubs(
-        descriptor, arrayOrFunction, name, isStatic, originalDescriptor, []);
+
+    // Each method may have a number of stubs associated. For example, if an
+    // instance method supports multiple arguments, a stub for each matching
+    // selector. There is also a getter stub for tear-off getters. For example,
+    // an instance method foo([a]) may have the following stubs: foo$0, foo$1,
+    // and get$foo (here exemplified using unminified names).
+    // [extractStubs] returns a JavaScript object whose own properties
+    // corresponds to the stubs.
+    var descriptor =
+        this.extractStubs(array, name, isStatic, originalDescriptor);
     method = descriptor[name];
+
+    // Iterate through the properties of descriptor and copy the stubs to the
+    // existing holder (for instance methods, a prototype).
     for (var property in descriptor) {
       if (!Object.prototype.hasOwnProperty.call(descriptor, property)) continue;
       var stub = descriptor[property];
@@ -1838,6 +1921,8 @@
           // prototype.
           stub = stub.call(receiver);
 
+          // Copy the properties from the new tear-off's prototype to the
+          // prototype of the existing tear-off.
           var newProto = stub.constructor.prototype;
           var existingProto = existingStub.constructor.prototype;
           for (var stubProperty in newProto) {
@@ -1967,8 +2052,10 @@
       // native elements.
       ClassElement cls =
           element.enclosingClassOrCompilationUnit.declaration;
-      if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls)
-          && !cls.isNative) {
+      if (compiler.codegenWorld.directlyInstantiatedClasses.contains(cls) &&
+          !cls.isNative &&
+          compiler.deferredLoadTask.outputUnitForElement(element) ==
+              compiler.deferredLoadTask.outputUnitForElement(cls)) {
         owner = cls;
       }
     }
@@ -2109,9 +2196,9 @@
       // point to the current Isolate. Otherwise all methods/functions
       // accessing isolate variables will access the wrong object.
       outputBuffer.write("${namer.currentIsolate}$_=${_}arguments[1]$N");
-      typeTestEmitter.emitRuntimeTypeSupport(outputBuffer, outputUnit);
 
       emitCompileTimeConstants(outputBuffer, outputUnit);
+      emitStaticNonFinalFieldInitializations(outputBuffer, outputUnit);
       outputBuffer.write('}$N');
 
       if (compiler.useContentSecurityPolicy) {
diff --git a/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart b/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart
index aba512b..af0bd0c 100644
--- a/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/old_emitter/type_test_emitter.dart
@@ -5,245 +5,14 @@
 part of dart2js.js_emitter;
 
 class TypeTestEmitter extends CodeEmitterHelper {
-  Set<ClassElement> get checkedClasses =>
-      emitter.typeTestRegistry.checkedClasses;
-
-  Iterable<ClassElement> get classesUsingTypeVariableTests =>
-      emitter.typeTestRegistry.classesUsingTypeVariableTests;
-
-  Set<FunctionType> get checkedFunctionTypes =>
-      emitter.typeTestRegistry.checkedFunctionTypes;
-
   void emitIsTests(ClassElement classElement, ClassBuilder builder) {
-    assert(invariant(classElement, classElement.isDeclaration));
-
-    void generateIsTest(Element other) {
-      if (other == compiler.objectClass && other != classElement) {
-        // Avoid emitting [:$isObject:] on all classes but [Object].
-        return;
-      }
-      builder.addProperty(namer.operatorIs(other), js('true'));
-    }
-
-    void generateFunctionTypeSignature(FunctionElement method,
-                                       FunctionType type) {
-      assert(method.isImplementation);
-      jsAst.Expression thisAccess = new jsAst.This();
-      Node node = method.node;
-      ClosureClassMap closureData =
-          compiler.closureToClassMapper.closureMappingCache[node];
-      if (closureData != null) {
-        ClosureFieldElement thisLocal =
-            closureData.getFreeVariableElement(closureData.thisLocal);
-        if (thisLocal != null) {
-          String thisName = namer.instanceFieldPropertyName(thisLocal);
-          thisAccess = js('this.#', thisName);
-        }
-      }
-      RuntimeTypes rti = backend.rti;
-      jsAst.Expression encoding = rti.getSignatureEncoding(type, thisAccess);
-      String operatorSignature = namer.operatorSignature;
-      if (!type.containsTypeVariables) {
-        builder.functionType = '${emitter.metadataEmitter.reifyType(type)}';
-      } else {
-        builder.addProperty(operatorSignature, encoding);
-      }
-    }
-
-    void generateSubstitution(ClassElement cls, {bool emitNull: false}) {
-      if (cls.typeVariables.isEmpty) return;
-      RuntimeTypes rti = backend.rti;
-      jsAst.Expression expression;
-      bool needsNativeCheck = emitter.nativeEmitter.requiresNativeIsCheck(cls);
-      expression = rti.getSupertypeSubstitution(classElement, cls);
-      if (expression == null && (emitNull || needsNativeCheck)) {
-        expression = new jsAst.LiteralNull();
-      }
-      if (expression != null) {
-        builder.addProperty(namer.substitutionName(cls), expression);
-      }
-    }
-
-    generateIsTestsOn(classElement, generateIsTest,
-        generateFunctionTypeSignature,
-        generateSubstitution);
-  }
-
-  /**
-   * Generate "is tests" for [cls]: itself, and the "is tests" for the
-   * classes it implements and type argument substitution functions for these
-   * tests.   We don't need to add the "is tests" of the super class because
-   * they will be inherited at runtime, but we may need to generate the
-   * substitutions, because they may have changed.
-   */
-  void generateIsTestsOn(ClassElement cls,
-                         void emitIsTest(Element element),
-                         FunctionTypeSignatureEmitter emitFunctionTypeSignature,
-                         SubstitutionEmitter emitSubstitution) {
-    if (checkedClasses.contains(cls)) {
-      emitIsTest(cls);
-      emitSubstitution(cls);
-    }
-
-    RuntimeTypes rti = backend.rti;
-    ClassElement superclass = cls.superclass;
-
-    bool haveSameTypeVariables(ClassElement a, ClassElement b) {
-      if (a.isClosure) return true;
-      return backend.rti.isTrivialSubstitution(a, b);
-    }
-
-    if (superclass != null && superclass != compiler.objectClass &&
-        !haveSameTypeVariables(cls, superclass)) {
-      // We cannot inherit the generated substitutions, because the type
-      // variable layout for this class is different.  Instead we generate
-      // substitutions for all checks and make emitSubstitution a NOP for the
-      // rest of this function.
-      Set<ClassElement> emitted = new Set<ClassElement>();
-      // TODO(karlklose): move the computation of these checks to
-      // RuntimeTypeInformation.
-      while (superclass != null) {
-        if (backend.classNeedsRti(superclass)) {
-          emitSubstitution(superclass, emitNull: true);
-          emitted.add(superclass);
-        }
-        superclass = superclass.superclass;
-      }
-      for (DartType supertype in cls.allSupertypes) {
-        ClassElement superclass = supertype.element;
-        if (classesUsingTypeVariableTests.contains(superclass)) {
-          emitSubstitution(superclass, emitNull: true);
-          emitted.add(superclass);
-        }
-        for (ClassElement check in checkedClasses) {
-          if (supertype.element == check && !emitted.contains(check)) {
-            // Generate substitution.  If no substitution is necessary, emit
-            // [:null:] to overwrite a (possibly) existing substitution from the
-            // super classes.
-            emitSubstitution(check, emitNull: true);
-            emitted.add(check);
-          }
-        }
-      }
-      void emitNothing(_, {emitNull}) {};
-      emitSubstitution = emitNothing;
-    }
-
-    Set<Element> generated = new Set<Element>();
-    // A class that defines a [:call:] method implicitly implements
-    // [Function] and needs checks for all typedefs that are used in is-checks.
-    if (checkedClasses.contains(compiler.functionClass) ||
-        !checkedFunctionTypes.isEmpty) {
-      Element call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
-      if (call == null) {
-        // If [cls] is a closure, it has a synthetic call operator method.
-        call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME);
-      }
-      if (call != null && call.isFunction) {
-        // A superclass might already implement the Function interface. In such
-        // a case, we can avoid emiting the is test here.
-        if (!cls.superclass.implementsFunction(compiler)) {
-          generateInterfacesIsTests(compiler.functionClass,
-                                    emitIsTest,
-                                    emitSubstitution,
-                                    generated);
-        }
-        FunctionType callType = call.computeType(compiler);
-        emitFunctionTypeSignature(call, callType);
-      }
-    }
-
-    for (DartType interfaceType in cls.interfaces) {
-      generateInterfacesIsTests(interfaceType.element, emitIsTest,
-                                emitSubstitution, generated);
-    }
-  }
-
-  /**
-   * Generate "is tests" where [cls] is being implemented.
-   */
-  void generateInterfacesIsTests(ClassElement cls,
-                                 void emitIsTest(ClassElement element),
-                                 SubstitutionEmitter emitSubstitution,
-                                 Set<Element> alreadyGenerated) {
-    void tryEmitTest(ClassElement check) {
-      if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
-        alreadyGenerated.add(check);
-        emitIsTest(check);
-        emitSubstitution(check);
-      }
-    };
-
-    tryEmitTest(cls);
-
-    for (DartType interfaceType in cls.interfaces) {
-      Element element = interfaceType.element;
-      tryEmitTest(element);
-      generateInterfacesIsTests(element, emitIsTest, emitSubstitution,
-                                alreadyGenerated);
-    }
-
-    // We need to also emit "is checks" for the superclass and its supertypes.
-    ClassElement superclass = cls.superclass;
-    if (superclass != null) {
-      tryEmitTest(superclass);
-      generateInterfacesIsTests(superclass, emitIsTest, emitSubstitution,
-                                alreadyGenerated);
-    }
-  }
-
-  void emitRuntimeTypeSupport(CodeBuffer buffer, OutputUnit outputUnit) {
-    emitter.addComment('Runtime type support', buffer);
-    RuntimeTypes rti = backend.rti;
-    TypeChecks typeChecks = rti.requiredChecks;
-
-    // Add checks to the constructors of instantiated classes.
-    // TODO(sigurdm): We should avoid running through this list for each
-    // output unit.
-
-    jsAst.Statement variables = js.statement('var TRUE = !0, _;');
-    List<jsAst.Statement> statements = <jsAst.Statement>[];
-
-    for (ClassElement cls in typeChecks) {
-      OutputUnit destination =
-          compiler.deferredLoadTask.outputUnitForElement(cls);
-      if (destination != outputUnit) continue;
-      // TODO(9556).  The properties added to 'holder' should be generated
-      // directly as properties of the class object, not added later.
-
-      // Each element is a pair: [propertyName, valueExpression]
-      List<List> properties = <List>[];
-
-      for (TypeCheck check in typeChecks[cls]) {
-        ClassElement checkedClass = check.cls;
-        properties.add([namer.operatorIs(checkedClass), js('TRUE')]);
-        Substitution substitution = check.substitution;
-        if (substitution != null) {
-          jsAst.Expression body = substitution.getCode(rti);
-          properties.add([namer.substitutionName(checkedClass), body]);
-        }
-      }
-
-      jsAst.Expression holder = backend.emitter.classAccess(cls);
-      if (properties.length > 1) {
-        // Use temporary shortened reference.
-        statements.add(js.statement('_ = #;', holder));
-        holder = js('#', '_');
-      }
-      for (List nameAndValue in properties) {
-        statements.add(
-            js.statement('#.# = #',
-                [holder, nameAndValue[0], nameAndValue[1]]));
-      }
-    }
-
-    if (statements.isNotEmpty) {
-      buffer.write(';');
-      buffer.write(
-          jsAst.prettyPrint(
-              js.statement('(function() { #; #; })()', [variables, statements]),
-              compiler));
-      buffer.write('$N');
+    assert(builder.functionType == null);
+    TypeTestGenerator generator =
+        new TypeTestGenerator(compiler, emitter.task, namer);
+    TypeTestProperties typeTests = generator.generateIsTests(classElement);
+    typeTests.properties.forEach(builder.addProperty);
+    if (typeTests.functionTypeIndex != null) {
+      builder.functionType = '${typeTests.functionTypeIndex}';
     }
   }
 }
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_generator.dart b/pkg/compiler/lib/src/js_emitter/type_test_generator.dart
new file mode 100644
index 0000000..2c9ce0d
--- /dev/null
+++ b/pkg/compiler/lib/src/js_emitter/type_test_generator.dart
@@ -0,0 +1,264 @@
+// 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.
+
+part of dart2js.js_emitter;
+
+class TypeTestProperties {
+  /// The index of the function type into the metadata.
+  ///
+  /// If the class doesn't have a function type this field is `null`.
+  ///
+  /// If the is tests were generated with `storeFunctionTypeInMetadata` set to
+  /// `false`, this field is `null`, and the [properties] contain a property
+  /// that encodes the function type.
+  int functionTypeIndex;
+
+  /// The properties that must be installed on the prototype of the
+  /// JS constructor of the [ClassElement] for which the is checks were
+  /// generated.
+  final Map<String, jsAst.Node> properties = <String, jsAst.Node>{};
+}
+
+class TypeTestGenerator {
+  final Compiler compiler;
+  final CodeEmitterTask emitterTask;
+  final Namer namer;
+
+  TypeTestGenerator(this.compiler, this.emitterTask, this.namer);
+
+  JavaScriptBackend get backend => compiler.backend;
+  OldEmitter get oldEmitter => emitterTask.oldEmitter;
+  TypeTestRegistry get typeTestRegistry => emitterTask.typeTestRegistry;
+
+  Set<ClassElement> get checkedClasses =>
+      typeTestRegistry.checkedClasses;
+
+  Iterable<ClassElement> get classesUsingTypeVariableTests =>
+      typeTestRegistry.classesUsingTypeVariableTests;
+
+  Set<FunctionType> get checkedFunctionTypes =>
+      typeTestRegistry.checkedFunctionTypes;
+
+  /// Generates all properties necessary for is-checks on the [classElement].
+  ///
+  /// Returns an instance of [TypeTestProperties] that contains the properties
+  /// that must be installed on the prototype of the JS constructor of the
+  /// [classElement].
+  ///
+  /// If [storeFunctionTypeInMetadata] is `true`, stores the reified function
+  /// type (if class has one) in the metadata object and stores its index in
+  /// the result. This is only possible for function types that do not contain
+  /// type variables.
+  TypeTestProperties generateIsTests(
+      ClassElement classElement,
+      { bool storeFunctionTypeInMetadata: true}) {
+    assert(invariant(classElement, classElement.isDeclaration));
+
+    TypeTestProperties result = new TypeTestProperties();
+
+    void generateIsTest(Element other) {
+      if (other == compiler.objectClass && other != classElement) {
+        // Avoid emitting `$isObject` on all classes but [Object].
+        return;
+      }
+      result.properties[namer.operatorIs(other)] = js('true');
+    }
+
+    void generateFunctionTypeSignature(FunctionElement method,
+                                       FunctionType type) {
+      assert(method.isImplementation);
+      jsAst.Expression thisAccess = new jsAst.This();
+      Node node = method.node;
+      ClosureClassMap closureData =
+          compiler.closureToClassMapper.closureMappingCache[node];
+      if (closureData != null) {
+        ClosureFieldElement thisLocal =
+            closureData.getFreeVariableElement(closureData.thisLocal);
+        if (thisLocal != null) {
+          String thisName = namer.instanceFieldPropertyName(thisLocal);
+          thisAccess = js('this.#', thisName);
+        }
+      }
+
+      if (storeFunctionTypeInMetadata && !type.containsTypeVariables) {
+        result.functionTypeIndex = oldEmitter.metadataEmitter.reifyType(type);
+      } else {
+        RuntimeTypes rti = backend.rti;
+        jsAst.Expression encoding = rti.getSignatureEncoding(type, thisAccess);
+        String operatorSignature = namer.operatorSignature;
+        result.properties[operatorSignature] = encoding;
+      }
+    }
+
+    void generateSubstitution(ClassElement cls, {bool emitNull: false}) {
+      if (cls.typeVariables.isEmpty) return;
+      RuntimeTypes rti = backend.rti;
+      jsAst.Expression expression;
+      bool needsNativeCheck =
+          oldEmitter.nativeEmitter.requiresNativeIsCheck(cls);
+      expression = rti.getSupertypeSubstitution(classElement, cls);
+      if (expression == null && (emitNull || needsNativeCheck)) {
+        expression = new jsAst.LiteralNull();
+      }
+      if (expression != null) {
+        result.properties[namer.substitutionName(cls)] = expression;
+      }
+    }
+
+    void generateTypeCheck(TypeCheck check) {
+      ClassElement checkedClass = check.cls;
+      // We must not call [generateIsTest] since we also want is$Object.
+      result.properties[namer.operatorIs(checkedClass)] = js('true');
+      Substitution substitution = check.substitution;
+      if (substitution != null) {
+        jsAst.Expression body = substitution.getCode(backend.rti);
+        result.properties[namer.substitutionName(checkedClass)] = body;
+      }
+    }
+
+    _generateIsTestsOn(classElement, generateIsTest,
+        generateFunctionTypeSignature,
+        generateSubstitution,
+        generateTypeCheck);
+
+    return result;
+  }
+
+  /**
+   * Generate "is tests" for [cls] itself, and the "is tests" for the
+   * classes it implements and type argument substitution functions for these
+   * tests.   We don't need to add the "is tests" of the super class because
+   * they will be inherited at runtime, but we may need to generate the
+   * substitutions, because they may have changed.
+   */
+  void _generateIsTestsOn(
+      ClassElement cls,
+      void generateIsTest(Element element),
+      FunctionTypeSignatureEmitter generateFunctionTypeSignature,
+      SubstitutionEmitter generateSubstitution,
+      void emitTypeCheck(TypeCheck check)) {
+    Setlet<Element> generated = new Setlet<Element>();
+
+    if (checkedClasses.contains(cls)) {
+      generateIsTest(cls);
+      generateSubstitution(cls);
+      generated.add(cls);
+    }
+
+    // Precomputed is checks.
+    TypeChecks typeChecks = backend.rti.requiredChecks;
+    Iterable<TypeCheck> classChecks = typeChecks[cls];
+    if (classChecks != null) {
+      for (TypeCheck check in classChecks) {
+        if (!generated.contains(check.cls)) {
+          emitTypeCheck(check);
+          generated.add(check.cls);
+        }
+      }
+    }
+
+    RuntimeTypes rti = backend.rti;
+    ClassElement superclass = cls.superclass;
+
+    bool haveSameTypeVariables(ClassElement a, ClassElement b) {
+      if (a.isClosure) return true;
+      return backend.rti.isTrivialSubstitution(a, b);
+    }
+
+    if (superclass != null && superclass != compiler.objectClass &&
+        !haveSameTypeVariables(cls, superclass)) {
+      // We cannot inherit the generated substitutions, because the type
+      // variable layout for this class is different.  Instead we generate
+      // substitutions for all checks and make emitSubstitution a NOP for the
+      // rest of this function.
+
+      // TODO(karlklose): move the computation of these checks to
+      // RuntimeTypeInformation.
+      while (superclass != null) {
+        if (backend.classNeedsRti(superclass)) {
+          generateSubstitution(superclass, emitNull: true);
+          generated.add(superclass);
+        }
+        superclass = superclass.superclass;
+      }
+      for (DartType supertype in cls.allSupertypes) {
+        ClassElement superclass = supertype.element;
+        if (generated.contains(superclass)) continue;
+
+        if (classesUsingTypeVariableTests.contains(superclass) ||
+            checkedClasses.contains(superclass)) {
+          // Generate substitution.  If no substitution is necessary, emit
+          // `null` to overwrite a (possibly) existing substitution from the
+          // super classes.
+          generateSubstitution(superclass, emitNull: true);
+        }
+      }
+
+      void emitNothing(_, {emitNull}) {};
+
+      generateSubstitution = emitNothing;
+    }
+
+    // A class that defines a `call` method implicitly implements
+    // [Function] and needs checks for all typedefs that are used in is-checks.
+    if (checkedClasses.contains(compiler.functionClass) ||
+        checkedFunctionTypes.isNotEmpty) {
+      Element call = cls.lookupLocalMember(Compiler.CALL_OPERATOR_NAME);
+      if (call == null) {
+        // If [cls] is a closure, it has a synthetic call operator method.
+        call = cls.lookupBackendMember(Compiler.CALL_OPERATOR_NAME);
+      }
+      if (call != null && call.isFunction) {
+        // A superclass might already implement the Function interface. In such
+        // a case, we can avoid emiting the is test here.
+        if (!cls.superclass.implementsFunction(compiler)) {
+          _generateInterfacesIsTests(compiler.functionClass,
+                                    generateIsTest,
+                                    generateSubstitution,
+                                    generated);
+        }
+        FunctionType callType = call.computeType(compiler);
+        generateFunctionTypeSignature(call, callType);
+      }
+    }
+
+    for (DartType interfaceType in cls.interfaces) {
+      _generateInterfacesIsTests(interfaceType.element, generateIsTest,
+                                 generateSubstitution, generated);
+    }
+  }
+
+  /**
+   * Generate "is tests" where [cls] is being implemented.
+   */
+  void _generateInterfacesIsTests(ClassElement cls,
+                                  void generateIsTest(ClassElement element),
+                                  SubstitutionEmitter generateSubstitution,
+                                  Set<Element> alreadyGenerated) {
+    void tryEmitTest(ClassElement check) {
+      if (!alreadyGenerated.contains(check) && checkedClasses.contains(check)) {
+        alreadyGenerated.add(check);
+        generateIsTest(check);
+        generateSubstitution(check);
+      }
+    };
+
+    tryEmitTest(cls);
+
+    for (DartType interfaceType in cls.interfaces) {
+      Element element = interfaceType.element;
+      tryEmitTest(element);
+      _generateInterfacesIsTests(element, generateIsTest, generateSubstitution,
+                                 alreadyGenerated);
+    }
+
+    // We need to also emit "is checks" for the superclass and its supertypes.
+    ClassElement superclass = cls.superclass;
+    if (superclass != null) {
+      tryEmitTest(superclass);
+      _generateInterfacesIsTests(superclass, generateIsTest,
+                                 generateSubstitution, alreadyGenerated);
+    }
+  }
+}
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index b2db0bb..25b5288 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -435,23 +435,8 @@
     });
   }
 
-  /// True if the uris are pointing to a library that is shared between dart2js
-  /// and the core libraries. By construction they must be imported into the
-  /// runtime, and, at the same time, into dart2js. This can lead to
-  /// duplicated imports, like in the docgen.
-  // TODO(johnniwinther): is this necessary, or should we change docgen not
-  //   to include both libraries (compiler and lib) at the same time?
-  bool _isSharedDart2jsLibrary(Uri uri1, Uri uri2) {
-    bool inJsLibShared(Uri uri) {
-      List<String> segments = uri.pathSegments;
-      if (segments.length < 3) return false;
-      if (segments[segments.length - 2] != 'shared') return false;
-      return (segments[segments.length - 3] == 'js_lib');
-    }
-    return inJsLibShared(uri1) && inJsLibShared(uri2);
-  }
-
   void checkDuplicatedLibraryName(LibraryElement library) {
+    if (library.isInternalLibrary) return;
     Uri resourceUri = library.entryCompilationUnit.script.resourceUri;
     LibraryName tag = library.libraryTag;
     LibraryElement existing =
@@ -476,8 +461,7 @@
     } else if (tag != null) {
       String name = library.getLibraryOrScriptName();
       existing = libraryNames.putIfAbsent(name, () => library);
-      if (!identical(existing, library) &&
-          !_isSharedDart2jsLibrary(resourceUri, existing.canonicalUri)) {
+      if (!identical(existing, library)) {
         compiler.withCurrentElement(library, () {
           compiler.reportWarning(tag.name,
               MessageKind.DUPLICATED_LIBRARY_NAME,
@@ -525,7 +509,7 @@
   Future registerLibraryFromTag(LibraryDependencyHandler handler,
                                 LibraryElement library,
                                 LibraryDependency tag) {
-    Uri base = library.entryCompilationUnit.script.readableUri;
+    Uri base = library.canonicalUri;
     Uri resolvedUri = base.resolve(tag.uri.dartString.slowToString());
     return createLibrary(handler, library, resolvedUri, tag.uri)
         .then((LibraryElement loadedLibrary) {
@@ -708,6 +692,9 @@
    */
   Link<ImportLink> imports = const Link<ImportLink>();
 
+  /// A linked list of all libraries directly exported by [library].
+  Link<LibraryElement> exports = const Link<LibraryElement>();
+
   /**
    * A linked list of the export tags the dependent upon this node library.
    * This is used to propagate exports during the computation of export scopes.
@@ -750,6 +737,10 @@
    */
   void registerExportDependency(Export export,
                                 LibraryDependencyNode exportingLibraryNode) {
+    // Register the exported library in the exporting library node.
+    exportingLibraryNode.exports =
+        exportingLibraryNode.exports.prepend(library);
+    // Register the export in the exported library node.
     dependencies =
         dependencies.prepend(new ExportLink(export, exportingLibraryNode));
   }
@@ -1104,16 +1095,18 @@
       List<Link<Uri>> suffixes = [];
       if (targetUri != canonicalUri) {
         LibraryDependencyNode node = nodeMap[library];
-        for (ImportLink import in node.imports.reverse()) {
+
+        /// Process the import (or export) of [importedLibrary].
+        void processLibrary(LibraryElement importedLibrary) {
           bool suffixesArePrecomputed =
-              suffixChainMap.containsKey(import.importedLibrary);
+              suffixChainMap.containsKey(importedLibrary);
 
           if (!suffixesArePrecomputed) {
-            computeSuffixes(import.importedLibrary, prefix);
+            computeSuffixes(importedLibrary, prefix);
             if (aborted) return;
           }
 
-          for (Link<Uri> suffix in suffixChainMap[import.importedLibrary]) {
+          for (Link<Uri> suffix in suffixChainMap[importedLibrary]) {
             suffixes.add(suffix.prepend(canonicalUri));
 
             if (suffixesArePrecomputed) {
@@ -1132,6 +1125,15 @@
             }
           }
         }
+
+        for (ImportLink import in node.imports.reverse()) {
+          processLibrary(import.importedLibrary);
+          if (aborted) return;
+        }
+        for (LibraryElement exportedLibrary in node.exports.reverse()) {
+          processLibrary(exportedLibrary);
+          if (aborted) return;
+        }
       } else { // Here `targetUri == canonicalUri`.
         if (!callback(prefix)) {
           aborted = true;
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
index 6520b36..f5e4b11 100644
--- a/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
+++ b/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
@@ -84,7 +84,7 @@
 
   ClassMirror get type {
     return mirrorSystem._getTypeDeclarationMirror(
-        _value.computeType(mirrorSystem.compiler).element);
+        _value.getType(mirrorSystem.compiler.coreTypes).element);
   }
 
   int get hashCode => 13 * _constant.hashCode;
diff --git a/pkg/compiler/lib/src/mirrors_used.dart b/pkg/compiler/lib/src/mirrors_used.dart
index 208904e..5c2476c 100644
--- a/pkg/compiler/lib/src/mirrors_used.dart
+++ b/pkg/compiler/lib/src/mirrors_used.dart
@@ -265,7 +265,8 @@
     List<MirrorUsage> result = <MirrorUsage>[];
     for (MetadataAnnotation metadata in tag.metadata) {
       metadata.ensureResolved(compiler);
-      Element element = metadata.constant.value.computeType(compiler).element;
+      Element element =
+          metadata.constant.value.getType(compiler.coreTypes).element;
       if (element == compiler.mirrorsUsedClass) {
         result.add(buildUsage(metadata.constant.value));
       }
@@ -438,7 +439,7 @@
 
   /// Find the first non-implementation interface of constant.
   DartType apiTypeOf(ConstantValue constant) {
-    DartType type = constant.computeType(compiler);
+    DartType type = constant.getType(compiler.coreTypes);
     LibraryElement library = type.element.library;
     if (type.isInterfaceType && library.isInternalLibrary) {
       InterfaceType interface = type;
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 0899be3..51b5cac 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -379,7 +379,7 @@
                 Element element,
                 MetadataAnnotation annotation,
                 ConstantValue constant) {
-    if (constant.computeType(compiler).element !=
+    if (constant.getType(compiler.coreTypes).element !=
             compiler.nativeAnnotationClass) {
       compiler.internalError(annotation, 'Invalid @Native(...) annotation.');
     }
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 137126a..80d5b82 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -2788,6 +2788,12 @@
         } else {
           // The node itself is not a constant but we register the selector (the
           // identifier that refers to the class/typedef) as a constant.
+          if (node.receiver != null) {
+            // This is a hack for the case of prefix.Type, we need to store
+            // the element on the selector, so [analyzeConstant] can build
+            // the type literal from the selector.
+            registry.useElement(node.selector, target);
+          }
           analyzeConstantDeferred(node.selector);
         }
       }
@@ -3280,7 +3286,7 @@
                 argumentNode, registry.mapping);
         ConstantValue name = constant.value;
         if (!name.isString) {
-          DartType type = name.computeType(compiler);
+          DartType type = name.getType(compiler.coreTypes);
           compiler.reportError(argumentNode, MessageKind.STRING_EXPECTED,
                                    {'type': type});
         } else {
diff --git a/pkg/compiler/lib/src/scanner/parser.dart b/pkg/compiler/lib/src/scanner/parser.dart
index 057cc30..8e64787 100644
--- a/pkg/compiler/lib/src/scanner/parser.dart
+++ b/pkg/compiler/lib/src/scanner/parser.dart
@@ -1570,8 +1570,8 @@
   }
 
   Token peekIdentifierAfterOptionalType(Token token) {
-    Token peek = peekIdentifierAfterType(token);
-    if (peek != null) {
+    Token peek = peekAfterIfType(token);
+    if (peek != null && peek.isIdentifier()) {
       // We are looking at "type identifier".
       return peek;
     } else if (token.isIdentifier()) {
diff --git a/pkg/compiler/lib/src/scanner/scanner_task.dart b/pkg/compiler/lib/src/scanner/scanner_task.dart
index 955fd87..ccfbc0e 100644
--- a/pkg/compiler/lib/src/scanner/scanner_task.dart
+++ b/pkg/compiler/lib/src/scanner/scanner_task.dart
@@ -11,7 +11,7 @@
   void scanLibrary(LibraryElement library) {
     CompilationUnitElement compilationUnit = library.entryCompilationUnit;
     String canonicalUri = library.canonicalUri.toString();
-    String resolvedUri = compilationUnit.script.readableUri.toString();
+    String resolvedUri = compilationUnit.script.resourceUri.toString();
     if (canonicalUri == resolvedUri) {
       compiler.log("Scanning library $canonicalUri");
     } else {
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 239aea9..1a1e7d0 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -934,6 +934,7 @@
   final CodegenWorkItem work;
   final RuntimeTypes rti;
   final bool generateSourceMap;
+  bool inLazyInitializerExpression = false;
 
   /* This field is used by the native handler. */
   final NativeEmitter nativeEmitter;
@@ -1275,16 +1276,33 @@
       return true;
     }
 
+    bool reductiveHeuristic() {
+      // The call is on a path which is executed rarely, so inline only if it
+      // does not make the program larger.
+      if (isCalledOnce(element)) {
+        return InlineWeeder.canBeInlined(function.node, -1, false);
+      }
+      // TODO(sra): Measure if inlining would 'reduce' the size.  One desirable
+      // case we miss my doing nothing is inlining very simple constructors
+      // where all fields are initialized with values from the arguments at this
+      // call site.  The code is slightly larger (`new Foo(1)` vs `Foo$(1)`) but
+      // that usually means the factory constructor is left unused and not
+      // emitted.
+      return false;
+    }
+
     bool heuristicSayGoodToGo() {
-      // Don't inline recursivly
+      // Don't inline recursively
       if (inliningStack.any((entry) => entry.function == function)) {
         return false;
       }
 
-      if (inExpressionOfThrow) return false;
-
       if (element.isSynthesized) return true;
 
+      if (inExpressionOfThrow || inLazyInitializerExpression) {
+        return reductiveHeuristic();
+      }
+
       if (cachedCanBeInlined == true) return cachedCanBeInlined;
 
       if (backend.functionsToAlwaysInline.contains(function)) {
@@ -1308,8 +1326,7 @@
       // If a method is called only once, and all the methods in the
       // inlining stack are called only once as well, we know we will
       // save on output size by inlining this method.
-      TypesInferrer inferrer = compiler.typesTask.typesInferrer;
-      if (inferrer.isCalledOnce(element) && allInlinedFunctionsCalledOnce) {
+      if (isCalledOnce(element)) {
         useMaxInliningNodes = false;
       }
       bool canInline;
@@ -1364,6 +1381,12 @@
     return inliningStack.isEmpty || inliningStack.last.allFunctionsCalledOnce;
   }
 
+  bool isCalledOnce(Element element) {
+    if (!allInlinedFunctionsCalledOnce) return false;
+    TypesInferrer inferrer = compiler.typesTask.typesInferrer;
+    return inferrer.isCalledOnce(element);
+  }
+
   inlinedFrom(Element element, f()) {
     assert(element is FunctionElement || element is VariableElement);
     return compiler.withCurrentElement(element, () {
@@ -1519,6 +1542,7 @@
   }
 
   HGraph buildLazyInitializer(VariableElement variable) {
+    inLazyInitializerExpression = true;
     ast.Node node = variable.node;
     openFunction(variable, node);
     assert(invariant(variable, variable.initializer != null,
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 2973145..a8050bd 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -173,7 +173,7 @@
   HConstant addConstant(ConstantValue constant, Compiler compiler) {
     HConstant result = constants[constant];
     if (result == null) {
-      TypeMask type = constant.computeMask(compiler);
+      TypeMask type = computeTypeMask(compiler, constant);
       result = new HConstant.internal(constant, type);
       entry.addAtExit(result);
       constants[constant] = result;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index c95d5db..38bf3cf 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -982,6 +982,8 @@
   final Compiler compiler;
   final SsaOptimizerTask optimizer;
   SsaLiveBlockAnalyzer analyzer;
+  Map<HInstruction, bool> trivialDeadStoreReceivers =
+      new Maplet<HInstruction, bool>();
   bool eliminatedSideEffects = false;
   SsaDeadCodeEliminator(this.compiler, this.optimizer);
 
@@ -1022,8 +1024,34 @@
     return false;
   }
 
+  bool isTrivialDeadStoreReceiver(HInstruction instruction) {
+    // For an allocation, if all the loads are dead (awaiting removal after
+    // SsaLoadElimination) and the only other uses are stores, then the
+    // allocation does not escape which makes all the stores dead too.
+    bool isDeadUse(HInstruction use) {
+      if (use is HFieldSet) {
+        // The use must be the receiver.  Even if the use is also the argument,
+        // i.e.  a.x = a, the store is still dead if all other uses are dead.
+        if (use.getDartReceiver(compiler) == instruction) return true;
+      } else if (use is HFieldGet) {
+        assert(use.getDartReceiver(compiler) == instruction);
+        if (isDeadCode(use)) return true;
+      }
+      return false;
+    }
+    return instruction is HForeignNew
+        && trivialDeadStoreReceivers.putIfAbsent(instruction,
+            () => instruction.usedBy.every(isDeadUse));
+  }
+
+  bool isTrivialDeadStore(HInstruction instruction) {
+    return instruction is HFieldSet
+        && isTrivialDeadStoreReceiver(instruction.getDartReceiver(compiler));
+  }
+
   bool isDeadCode(HInstruction instruction) {
     if (!instruction.usedBy.isEmpty) return false;
+    if (isTrivialDeadStore(instruction)) return true;
     if (instruction.sideEffects.hasSideEffects()) return false;
     if (instruction.canThrow()
         && instruction.onlyThrowsNSM()
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index a6bb41a..a951917 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -28,6 +28,7 @@
 import '../source_map_builder.dart';
 import '../tree/tree.dart' as ast;
 import '../types/types.dart';
+import '../types/constants.dart' show computeTypeMask;
 import '../universe/universe.dart';
 import '../util/util.dart';
 import '../js_backend/codegen/task.dart';
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart b/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart
index e85e16a..0e3c61aa 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/copy_propagator.dart
@@ -28,9 +28,9 @@
     root.body = visitStatement(root.body);
   }
 
-  rewriteFunctionDefinition(FunctionDefinition function) {
-    if (function.isAbstract) return;
-    rewriteExecutableDefinition(function);
+  rewriteFunctionDefinition(FunctionDefinition node) {
+    if (node.isAbstract) return;
+    rewriteExecutableDefinition(node);
 
     // Try to propagate moving assignments into function parameters.
     // For example:
@@ -51,17 +51,55 @@
     //   BODY
     // }
     // Cannot declare function as foo(x,x)!
-    function.parameters.forEach(visitVariable);
+    node.parameters.forEach(visitVariable);
 
     // Now do the propagation.
-    for (int i = 0; i < function.parameters.length; i++) {
-      Variable param = function.parameters[i];
+    for (int i = 0; i < node.parameters.length; i++) {
+      Variable param = node.parameters[i];
       Variable replacement = copyPropagateVariable(param);
       replacement.element = param.element; // Preserve parameter name.
-      function.parameters[i] = replacement;
+      node.parameters[i] = replacement;
     }
   }
 
+  rewriteConstructorDefinition(ConstructorDefinition node) {
+    if (node.isAbstract) return;
+    node.initializers.forEach(visitExpression);
+    rewriteExecutableDefinition(node);
+
+
+    // Try to propagate moving assignments into function parameters.
+    // For example:
+    // foo(x) {
+    //   var v1 = x;
+    //   BODY
+    // }
+    //   ==>
+    // foo(v1) {
+    //   BODY
+    // }
+
+    // Variables must not occur more than once in the parameter list, so
+    // invalidate all moving assignments that would propagate a parameter
+    // into another parameter. For example:
+    // foo(x,y) {
+    //   y = x;
+    //   BODY
+    // }
+    // Cannot declare function as foo(x,x)!
+    node.parameters.forEach(visitVariable);
+
+    // Now do the propagation.
+    for (int i = 0; i < node.parameters.length; i++) {
+      Variable param = node.parameters[i];
+      Variable replacement = copyPropagateVariable(param);
+      replacement.element = param.element; // Preserve parameter name.
+      node.parameters[i] = replacement;
+    }
+
+  }
+
+
   Statement visitBasicBlock(Statement node) {
     node = visitStatement(node);
     move.clear();
@@ -190,4 +228,8 @@
     new CopyPropagator().rewrite(node.definition);
   }
 
+  void visitFieldInitializer(FieldInitializer node) {
+    visitStatement(node.body);
+  }
+
 }
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
index 7138381..a78f8b6 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/logical_rewriter.dart
@@ -65,6 +65,28 @@
     root.body = visitStatement(root.body);
   }
 
+  void rewriteConstructorDefinition(ConstructorDefinition root) {
+    if (root.isAbstract) return;
+    List<Initializer> initializers = root.initializers;
+    for (int i = 0; i < initializers.length; ++i) {
+      initializers[i] = visitExpression(initializers[i]);
+    }
+    root.body = visitStatement(root.body);
+  }
+
+  Expression visitFieldInitializer(FieldInitializer node) {
+    node.body = visitStatement(node.body);
+    return node;
+  }
+
+  visitSuperInitializer(SuperInitializer node) {
+    List<Statement> arguments = node.arguments;
+    for (int i = 0; i < arguments.length; ++i) {
+      arguments[i] = visitStatement(arguments[i]);
+    }
+    return node;
+  }
+
   Statement visitLabeledStatement(LabeledStatement node) {
     Statement savedFallthrough = fallthrough;
     fallthrough = node.next;
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart b/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
index 737ac3f..ff815ba 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/optimization.dart
@@ -15,6 +15,7 @@
   void rewrite(ExecutableDefinition root) => root.applyPass(this);
   void rewriteFieldDefinition(FieldDefinition root);
   void rewriteFunctionDefinition(FunctionDefinition root);
+  void rewriteConstructorDefinition(ConstructorDefinition root);
 }
 
 
@@ -29,4 +30,8 @@
     if (root.isAbstract) return;
     rewriteExecutableDefinition(root);
   }
+  void rewriteConstructorDefinition(ConstructorDefinition root) {
+    if (root.isAbstract) return;
+    rewriteExecutableDefinition(root);
+  }
 }
\ No newline at end of file
diff --git a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
index 49b61c9..a483add 100644
--- a/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
+++ b/pkg/compiler/lib/src/tree_ir/optimization/statement_rewriter.dart
@@ -91,7 +91,7 @@
  * This may trigger a flattening of nested ifs in case the eliminated label
  * separated two ifs.
  */
-class StatementRewriter extends Visitor<Statement, Expression> implements Pass {
+class StatementRewriter extends Visitor<Statement, Expression> with PassMixin {
   // The binding environment.  The rightmost element of the list is the nearest
   // available enclosing binding.
   List<Assign> environment;
@@ -107,32 +107,41 @@
     return newJump != null ? newJump : jump;
   }
 
-  void rewrite(ExecutableDefinition definition) => definition.applyPass(this);
 
-  void rewriteFieldDefinition(FieldDefinition definition) {
-    if (!definition.hasInitializer) return;
-
-    environment = <Assign>[];
-    definition.body = visitStatement(definition.body);
-
-    // TODO(kmillikin):  Allow definitions that are not propagated.  Here,
-    // this means rebuilding the binding with a recursively unnamed definition,
-    // or else introducing a variable definition and an assignment.
-    assert(environment.isEmpty);
+  rewriteExecutableDefinition(ExecutableDefinition definition) {
+    definition.body = rewriteInEmptyEnvironment(definition.body);
   }
 
-  void rewriteFunctionDefinition(FunctionDefinition definition) {
+  void rewriteConstructorDefinition(ConstructorDefinition definition) {
     if (definition.isAbstract) return;
+    definition.initializers.forEach(visitExpression);
+    rewriteExecutableDefinition(definition);
+  }
 
+  Statement rewriteInEmptyEnvironment(Statement body) {
+    List<Assign> oldEnvironment = environment;
     environment = <Assign>[];
-    definition.body = visitStatement(definition.body);
 
+    Statement result = visitStatement(body);
     // TODO(kmillikin):  Allow definitions that are not propagated.  Here,
     // this means rebuilding the binding with a recursively unnamed definition,
     // or else introducing a variable definition and an assignment.
     assert(environment.isEmpty);
+    environment = oldEnvironment;
+    return result;
   }
 
+  Expression visitFieldInitializer(FieldInitializer node) {
+    node.body = rewriteInEmptyEnvironment(node.body);
+    return node;
+  }
+
+  Expression visitSuperInitializer(SuperInitializer node) {
+    for (int i = node.arguments.length - 1; i >= 0; --i) {
+      node.arguments[i] = rewriteInEmptyEnvironment(node.arguments[i]);
+    }
+    return node;
+  }
 
   Expression visitExpression(Expression e) => e.processed ? e : e.accept(this);
 
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
index 4c614c9..d0f01f4 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_builder.dart
@@ -8,6 +8,7 @@
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../cps_ir/cps_ir_nodes.dart' as cps_ir;
+import '../util/util.dart' show CURRENT_ELEMENT_SPANNABLE;
 import 'tree_ir_nodes.dart';
 
 /**
@@ -43,7 +44,7 @@
  * still all named.
  */
 class Builder extends cps_ir.Visitor<Node> {
-  final dart2js.Compiler compiler;
+  final dart2js.InternalErrorFunction internalError;
 
   /// Maps variable/parameter elements to the Tree variables that represent it.
   final Map<Element, List<Variable>> element2variables =
@@ -62,11 +63,11 @@
 
   Builder parent;
 
-  Builder(this.compiler);
+  Builder(this.internalError, [this.parent]);
 
-  Builder.inner(Builder parent)
-      : this.parent = parent,
-        compiler = parent.compiler;
+  Builder createInnerBuilder() {
+    return new Builder(internalError, this);
+  }
 
   /// Variable used in [buildPhiAssignments] as a temporary when swapping
   /// variables.
@@ -101,8 +102,8 @@
   Expression getVariableReference(cps_ir.Reference reference) {
     Variable variable = getVariable(reference.definition);
     if (variable == null) {
-      compiler.internalError(
-          compiler.currentElement,
+      internalError(
+          CURRENT_ELEMENT_SPANNABLE,
           "Reference to ${reference.definition} has no register");
     }
     ++variable.readCount;
@@ -112,17 +113,23 @@
   ExecutableDefinition build(cps_ir.ExecutableDefinition node) {
     if (node is cps_ir.FieldDefinition) {
       return buildField(node);
-    } else if (node is cps_ir.FunctionDefinition) {
+    } else if (node is cps_ir.ConstructorDefinition) {
+      return buildConstructor(node);
+    } else {
+      assert(dart2js.invariant(
+          CURRENT_ELEMENT_SPANNABLE,
+          node is cps_ir.FunctionDefinition,
+          message: 'expected FunctionDefinition or FieldDefinition, '
+            ' found $node'));
       return buildFunction(node);
     }
-    assert(false);
   }
 
   FieldDefinition buildField(cps_ir.FieldDefinition node) {
     Statement body;
     if (node.hasInitializer) {
       currentElement = node.element;
-      returnContinuation = node.returnContinuation;
+      returnContinuation = node.body.returnContinuation;
 
       phiTempVar = new Variable(node.element, null);
 
@@ -148,10 +155,10 @@
       ++parameter.writeCount; // Being a parameter counts as a write.
       parameters.add(parameter);
     }
-    returnContinuation = node.returnContinuation;
 
     Statement body;
     if (!node.isAbstract) {
+      returnContinuation = node.body.returnContinuation;
       phiTempVar = new Variable(node.element, null);
       body = visit(node.body);
     }
@@ -160,9 +167,34 @@
         body, node.localConstants, node.defaultParameterValues);
   }
 
+  ConstructorDefinition buildConstructor(cps_ir.ConstructorDefinition node) {
+    currentElement = node.element;
+    List<Variable> parameters = <Variable>[];
+    for (cps_ir.Definition p in node.parameters) {
+      Variable parameter = getFunctionParameter(p);
+      assert(parameter != null);
+      ++parameter.writeCount; // Being a parameter counts as a write.
+      parameters.add(parameter);
+    }
+    List<Initializer> initializers;
+    Statement body;
+    if (!node.isAbstract) {
+      initializers = node.initializers.map(visit).toList();
+      returnContinuation = node.body.returnContinuation;
+
+      phiTempVar = new Variable(node.element, null);
+      body = visit(node.body);
+    }
+
+    return new ConstructorDefinition(node.element, parameters,
+        body, initializers, node.localConstants, node.defaultParameterValues);
+  }
+
+
   List<Expression> translateArguments(List<cps_ir.Reference> args) {
     return new List<Expression>.generate(args.length,
-         (int index) => getVariableReference(args[index]));
+         (int index) => getVariableReference(args[index]),
+         growable: false);
   }
 
   List<Variable> translatePhiArguments(List<cps_ir.Reference> args) {
@@ -269,7 +301,27 @@
     return first;
   }
 
-  visitNode(cps_ir.Node node) => throw "Unhandled node: $node";
+  visitNode(cps_ir.Node node) {
+    if (node is cps_ir.JsSpecificNode) {
+      throw "Cannot handle JS specific IR nodes in this visitor";
+    } else {
+      throw "Unhandled node: $node";
+    }
+  }
+
+  Initializer visitFieldInitializer(cps_ir.FieldInitializer node) {
+    returnContinuation = node.body.returnContinuation;
+    return new FieldInitializer(node.element, visit(node.body.body));
+  }
+
+  Initializer visitSuperInitializer(cps_ir.SuperInitializer node) {
+    List<Statement> arguments =
+        node.arguments.map((cps_ir.RunnableBody argument) {
+      returnContinuation = argument.returnContinuation;
+      return visit(argument.body);
+    }).toList();
+    return new SuperInitializer(node.target, node.selector, arguments);
+  }
 
   Statement visitLetPrim(cps_ir.LetPrim node) {
     Variable variable = getVariable(node.primitive);
@@ -289,6 +341,10 @@
     }
   }
 
+  Statement visitRunnableBody(cps_ir.RunnableBody node) {
+    return visit(node.body);
+  }
+
   Statement visitLetCont(cps_ir.LetCont node) {
     Label label;
     if (node.continuation.hasMultipleUses) {
@@ -316,9 +372,9 @@
   }
 
   Statement visitInvokeMethod(cps_ir.InvokeMethod node) {
-    Expression receiver = getVariableReference(node.receiver);
-    List<Expression> arguments = translateArguments(node.arguments);
-    Expression invoke = new InvokeMethod(receiver, node.selector, arguments);
+    Expression invoke = new InvokeMethod(getVariableReference(node.receiver),
+                                         node.selector,
+                                         translateArguments(node.arguments));
     return continueWithExpression(node.continuation, invoke);
   }
 
@@ -461,7 +517,7 @@
   }
 
   FunctionDefinition makeSubFunction(cps_ir.FunctionDefinition function) {
-    return new Builder.inner(this).buildFunction(function);
+    return createInnerBuilder().buildFunction(function);
   }
 
   Node visitCreateFunction(cps_ir.CreateFunction node) {
@@ -480,31 +536,19 @@
   Expression visitParameter(cps_ir.Parameter node) {
     // Continuation parameters are not visited (continuations themselves are
     // not visited yet).
-    compiler.internalError(compiler.currentElement, 'Unexpected IR node.');
+    internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node');
     return null;
   }
 
   Expression visitContinuation(cps_ir.Continuation node) {
     // Until continuations with multiple uses are supported, they are not
     // visited.
-    compiler.internalError(compiler.currentElement, 'Unexpected IR node.');
+    internalError(CURRENT_ELEMENT_SPANNABLE, 'Unexpected IR node: $node.');
     return null;
   }
 
   Expression visitIsTrue(cps_ir.IsTrue node) {
     return getVariableReference(node.value);
   }
-
-  dart2js.Selector get identicalSelector {
-    return new dart2js.Selector.call('identical', null, 2);
-  }
-
-  Expression visitIdentical(cps_ir.Identical node) {
-    return new InvokeStatic(
-        compiler.identicalFunction,
-        identicalSelector,
-        <Expression>[getVariableReference(node.left),
-                     getVariableReference(node.right)]);
-  }
 }
 
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
index 6dc960f..947df50 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_nodes.dart
@@ -513,6 +513,8 @@
 class Return extends Statement {
   /// Should not be null. Use [Constant] with [NullConstantValue] for void
   /// returns.
+  /// Even in constructors this holds true. Take special care when translating
+  /// back to dart, where `return null;` in a constructor is an error.
   Expression value;
 
   Statement get next => null;
@@ -605,6 +607,49 @@
   applyPass(Pass pass) => pass.rewriteFunctionDefinition(this);
 }
 
+abstract class Initializer implements Expression {}
+
+class FieldInitializer extends Initializer {
+  final FieldElement element;
+  Statement body;
+  bool processed = false;
+
+  FieldInitializer(this.element, this.body);
+
+  accept(ExpressionVisitor visitor) => visitor.visitFieldInitializer(this);
+  accept1(ExpressionVisitor1 visitor, arg) {
+    return visitor.visitFieldInitializer(this, arg);
+  }
+}
+
+class SuperInitializer extends Initializer {
+  final ConstructorElement target;
+  final Selector selector;
+  final List<Statement> arguments;
+  bool processed = false;
+
+  SuperInitializer(this.target, this.selector, this.arguments);
+  accept(ExpressionVisitor visitor) => visitor.visitSuperInitializer(this);
+  accept1(ExpressionVisitor1 visitor, arg) {
+    return visitor.visitSuperInitializer(this, arg);
+  }
+}
+
+class ConstructorDefinition extends FunctionDefinition {
+  final List<Initializer> initializers;
+
+  ConstructorDefinition(ConstructorElement element,
+                        List<Variable> parameters,
+                        Statement body,
+                        this.initializers,
+                        List<ConstDeclaration> localConstants,
+                        List<ConstantExpression> defaultParameterValues)
+      : super(element, parameters, body, localConstants,
+              defaultParameterValues);
+
+  applyPass(Pass pass) => pass.rewriteConstructorDefinition(this);
+}
+
 abstract class ExpressionVisitor<E> {
   E visitExpression(Expression e) => e.accept(this);
   E visitVariable(Variable node);
@@ -623,6 +668,8 @@
   E visitLiteralMap(LiteralMap node);
   E visitTypeOperator(TypeOperator node);
   E visitFunctionExpression(FunctionExpression node);
+  E visitFieldInitializer(FieldInitializer node);
+  E visitSuperInitializer(SuperInitializer node);
 }
 
 abstract class ExpressionVisitor1<E, A> {
@@ -643,6 +690,8 @@
   E visitLiteralMap(LiteralMap node, A arg);
   E visitTypeOperator(TypeOperator node, A arg);
   E visitFunctionExpression(FunctionExpression node, A arg);
+  E visitFieldInitializer(FieldInitializer node, A arg);
+  E visitSuperInitializer(SuperInitializer node, A arg);
 }
 
 abstract class StatementVisitor<S> {
@@ -797,4 +846,12 @@
     visitExpression(node.expression);
     visitStatement(node.next);
   }
+
+  visitFieldInitializer(FieldInitializer node) {
+    visitStatement(node.body);
+  }
+
+  visitSuperInitializer(SuperInitializer node) {
+    node.arguments.forEach(visitStatement);
+  }
 }
diff --git a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
index e78f426..be1fb18 100644
--- a/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
+++ b/pkg/compiler/lib/src/tree_ir/tree_ir_tracer.dart
@@ -7,6 +7,7 @@
 import 'dart:async' show EventSink;
 import '../tracer.dart';
 import 'tree_ir_nodes.dart';
+import 'optimization/optimization.dart';
 
 class Block {
   Label label;
@@ -52,6 +53,13 @@
 
   void collect(ExecutableDefinition node) {
     if (node.body != null) {
+      if (node is ConstructorDefinition) {
+        for (Initializer initializer in node.initializers) {
+          if (initializer is FieldInitializer) {
+            visitStatement(initializer.body);
+          }
+        }
+      }
       visitStatement(node.body);
     }
   }
@@ -142,9 +150,10 @@
     _addStatement(node);
     visitStatement(node.next);
   }
+
 }
 
-class TreeTracer extends TracerUtil with StatementVisitor {
+class TreeTracer extends TracerUtil with StatementVisitor, PassMixin {
   final EventSink<String> output;
 
   TreeTracer(this.output);
@@ -154,16 +163,23 @@
   int statementCounter;
 
   void traceGraph(String name, ExecutableDefinition node) {
+    if (node is FunctionDefinition && node.isAbstract) return;
+    if (node is FieldDefinition && node.body == null) return;
+    tag("cfg", () {
+      printProperty("name", name);
+      rewrite(node);
+      collector.blocks.forEach(printBlock);
+    });
+  }
+
+  @override
+  void rewriteExecutableDefinition(ExecutableDefinition node) {
+    collector = new BlockCollector();
     names = new Names();
     statementCounter = 0;
     collector = new BlockCollector();
     collector.collect(node);
-    tag("cfg", () {
-      printProperty("name", name);
-      int blockCounter = 0;
-      collector.blocks.forEach(printBlock);
-    });
-    names = null;
+    collector.blocks.forEach(printBlock);
   }
 
   void printBlock(Block block) {
@@ -393,6 +409,14 @@
     return "function ${node.definition.element.name}";
   }
 
+  String visitFieldInitializer(FieldInitializer node) {
+    throw "$node should not be visited by $this";
+  }
+
+  String visitSuperInitializer(SuperInitializer node) {
+    throw "$node should not be visited by $this";
+  }
+
 }
 
 /**
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
new file mode 100644
index 0000000..7ba2621
--- /dev/null
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -0,0 +1,100 @@
+// 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 types.constants;

+

+import '../constants/values.dart';

+import '../dart2jslib.dart';

+import 'types.dart';

+

+/// Computes the [TypeMask] for the constant [value].

+TypeMask computeTypeMask(Compiler compiler, ConstantValue value) {

+  return value.accept(const ConstantValueTypeMasks(), compiler);

+}

+

+class ConstantValueTypeMasks extends ConstantValueVisitor<TypeMask, Compiler> {

+  const ConstantValueTypeMasks();

+

+  @override

+  TypeMask visitConstructed(ConstructedConstantValue constant,

+                            Compiler compiler) {

+    if (compiler.backend.isInterceptorClass(constant.type.element)) {

+      return compiler.typesTask.nonNullType;

+    }

+    return new TypeMask.nonNullExact(constant.type.element, compiler.world);

+  }

+

+  @override

+  TypeMask visitDeferred(DeferredConstantValue constant, Compiler compiler) {

+    return constant.referenced.accept(this, compiler);

+  }

+

+  @override

+  TypeMask visitDouble(DoubleConstantValue constant, Compiler compiler) {

+    // We have to distinguish -0.0 from 0, but for all practical purposes

+    // -0.0 is an integer.

+    // TODO(17235): this kind of special casing should only happen in the

+    // backend.

+    if (constant.isMinusZero &&

+        compiler.backend.constantSystem.isInt(constant)) {

+      return compiler.typesTask.uint31Type;

+    }

+    assert(!compiler.backend.constantSystem.isInt(constant));

+    return compiler.typesTask.doubleType;

+  }

+

+  @override

+  TypeMask visitDummy(DummyConstantValue constant, Compiler compiler) {

+    return constant.typeMask;

+  }

+

+  @override

+  TypeMask visitBool(BoolConstantValue constant, Compiler compiler) {

+    return compiler.typesTask.boolType;

+  }

+

+  @override

+  TypeMask visitFunction(FunctionConstantValue constant, Compiler compiler) {

+    return compiler.typesTask.functionType;

+  }

+

+  @override

+  TypeMask visitInt(IntConstantValue constant, Compiler compiler) {

+    if (constant.isUInt31()) return compiler.typesTask.uint31Type;

+    if (constant.isUInt32()) return compiler.typesTask.uint32Type;

+    if (constant.isPositive()) return compiler.typesTask.positiveIntType;

+    return compiler.typesTask.intType;

+  }

+

+  @override

+  TypeMask visitInterceptor(InterceptorConstantValue constant,

+                            Compiler compiler) {

+    return compiler.typesTask.nonNullType;

+  }

+

+  @override

+  TypeMask visitList(ListConstantValue constant, Compiler compiler) {

+    return compiler.typesTask.constListType;

+  }

+

+  @override

+  TypeMask visitMap(MapConstantValue constant, Compiler compiler) {

+    return compiler.typesTask.constMapType;

+  }

+

+  @override

+  TypeMask visitNull(NullConstantValue constant, Compiler compiler) {

+    return compiler.typesTask.nullType;

+  }

+

+  @override

+  TypeMask visitString(StringConstantValue constant, Compiler compiler) {

+    return compiler.typesTask.stringType;

+  }

+

+  @override

+  TypeMask visitType(TypeConstantValue constant, Compiler compiler) {

+    return compiler.typesTask.typeType;

+  }

+}

diff --git a/pkg/compiler/samples/darttags/darttags.dart b/pkg/compiler/samples/darttags/darttags.dart
index a62b618..c44cdf0 100644
--- a/pkg/compiler/samples/darttags/darttags.dart
+++ b/pkg/compiler/samples/darttags/darttags.dart
@@ -13,7 +13,10 @@
 //       # Replace "xcodebuild" with "out" on Linux, and "build" on Windows.
 //       "-pdart/xcodebuild/ReleaseIA32/packages/",
 //       "dart/pkg/compiler/samples/darttags/darttags.dart",
-//       "dart/TAGS"
+//       "dart/TAGS",
+//       # Modify the following list to your preferences:
+//       "dart/tests/try/web/incremental_compilation_update_test.dart",
+//       "package:compiler/src/dart2js.dart",
 //     ],
 //   },
 // ]
@@ -43,8 +46,8 @@
 import 'package:compiler/src/source_file_provider.dart';
 import 'package:compiler/src/util/uri_extras.dart';
 
-const DART2JS = '../../lib/src/dart2js.dart';
-const DART2JS_MIRROR = '../../lib/src/mirrors/dart2js_mirrors.dart';
+const DART2JS = 'package:compiler/src/dart2js.dart';
+const DART2JS_MIRROR = 'package:compiler/src/mirrors/dart2js_mirrors.dart';
 const SDK_ROOT = '../../../../sdk/';
 
 bool isPublicDart2jsLibrary(String name) {
@@ -66,15 +69,23 @@
   Uri myLocation =
       handler.provider.cwd.resolveUri(Platform.script);
 
+  List<Uri> uris = <Uri>[];
+
+  if (arguments.length > 1) {
+    // Compute tags for libraries requested by the user.
+    uris.addAll(
+        arguments.skip(1).map((argument) => Uri.base.resolve(argument)));
+  } else {
+    // Compute tags for dart2js itself.
+    uris.add(myLocation.resolve(DART2JS));
+    uris.add(myLocation.resolve(DART2JS_MIRROR));
+  }
+
   // Get the names of public dart2js libraries.
   Iterable<String> names = LIBRARIES.keys.where(isPublicDart2jsLibrary);
 
   // Prepend "dart:" to the names.
-  List<Uri> uris = names.map((String name) => Uri.parse('dart:$name')).toList();
-
-  // Append dart2js itself.
-  uris.add(myLocation.resolve(DART2JS));
-  uris.add(myLocation.resolve(DART2JS_MIRROR));
+  uris.addAll(names.map((String name) => Uri.parse('dart:$name')));
 
   Uri libraryRoot = myLocation.resolve(SDK_ROOT);
   Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
diff --git a/pkg/compiler_unsupported/changelog.md b/pkg/compiler_unsupported/changelog.md
index e5d2021..6381c02 100644
--- a/pkg/compiler_unsupported/changelog.md
+++ b/pkg/compiler_unsupported/changelog.md
@@ -1,5 +1,10 @@
 # Changelog
 
-## Version 0.7.1
-Upgrade to SDK 1.3.0-dev.3.2.
+## Version 0.7.3
+- upgrade to SDK 1.9.0
 
+## Version 0.7.2
+- upgrade to SDK 1.6.0
+
+## Version 0.7.1
+- upgrade to SDK 1.3.0-dev.3.2.
diff --git a/pkg/compiler_unsupported/pubspec.yaml b/pkg/compiler_unsupported/pubspec.yaml
index 988747b..1124b72 100644
--- a/pkg/compiler_unsupported/pubspec.yaml
+++ b/pkg/compiler_unsupported/pubspec.yaml
@@ -1,10 +1,9 @@
 name: compiler_unsupported
-version: 0.7.2
+version: 0.7.3
 author: Dart2js Team <compiler-dev@dartlang.org>
 homepage: http://www.dartlang.org
 description: >
   This is an unsupported copy of the dart2js source. The API of this package
-  can and will change in unpredictable and incompatible ways. This release
-  tracks the 1.6.0-dev.1.2 dart2js version.
+  can and will change in unpredictable and incompatible ways.
 environment:
   sdk: ">=1.0.0 <2.0.0"
diff --git a/pkg/compiler_unsupported/tool/create_library.py b/pkg/compiler_unsupported/tool/create_library.py
index e84853e..a4744d7 100755
--- a/pkg/compiler_unsupported/tool/create_library.py
+++ b/pkg/compiler_unsupported/tool/create_library.py
@@ -57,17 +57,25 @@
   # copy dart2js code
   shutil.copy(join(PKG_SOURCE, 'compiler', 'lib', 'compiler.dart'), TARGET)
   shutil.copy(join(SOURCE, 'libraries.dart'), TARGET)
+  shutil.copytree(join(SOURCE, 'compiler'), join(TARGET, '_internal', 'compiler'))
   shutil.copytree(
       join(PKG_SOURCE, 'compiler', 'lib', 'src'),
       join(TARGET, 'src'))
 
-  # patch up the libraries.dart references
-  replace = [(r'\.\./\.\./libraries\.dart', r'\.\./libraries\.dart')]
+  # patch up the libraries.dart and package references
+  replace1 = [(
+      r'package:_internal/', 
+      r'package:compiler_unsupported/_internal/')]
+      
+  replace2 = [(
+      r'package:compiler_unsupported/_internal/libraries.dart', 
+      r'package:compiler_unsupported/libraries.dart')]
 
   for root, dirs, files in os.walk(join(TARGET, 'src')):
     for name in files:
       if name.endswith('.dart'):
-        ReplaceInFiles([join(root, name)], replace)
+        ReplaceInFiles([join(root, name)], replace1)
+        ReplaceInFiles([join(root, name)], replace2)
 
 
 if __name__ == '__main__':
diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart
index f364acd..30300f4 100644
--- a/pkg/dart2js_incremental/lib/caching_compiler.dart
+++ b/pkg/dart2js_incremental/lib/caching_compiler.dart
@@ -67,8 +67,11 @@
     JavaScriptBackend backend = compiler.backend;
 
     // Much like a scout, an incremental compiler is always prepared. For
-    // mixins, at least.
-    backend.emitter.oldEmitter.needsMixinSupport = true;
+    // mixins, classes, and lazy statics, at least.
+    backend.emitter.oldEmitter
+        ..needsDefineClass = true
+        ..needsMixinSupport = true
+        ..needsLazyInitializer = true;
 
     Uri core = Uri.parse("dart:core");
     return compiler.libraryLoader.loadLibrary(core).then((_) {
@@ -141,6 +144,7 @@
         ..deferredConstants.clear()
         ..isolateProperties = null
         ..classesCollector = null
+        ..neededClasses.clear()
         ..outputClassLists.clear()
         ..nativeClasses.clear()
         ..mangledFieldNames.clear()
diff --git a/pkg/dart2js_incremental/lib/dart2js_incremental.dart b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
index d5074f8..5ece461 100644
--- a/pkg/dart2js_incremental/lib/dart2js_incremental.dart
+++ b/pkg/dart2js_incremental/lib/dart2js_incremental.dart
@@ -29,6 +29,7 @@
     LibraryElement;
 
 import 'library_updater.dart' show
+    IncrementalCompilerContext,
     LibraryUpdater,
     Logger;
 
@@ -51,6 +52,7 @@
   final CompilerOutputProvider outputProvider;
   final Map<String, dynamic> environment;
   final List<String> _updates = <String>[];
+  final IncrementalCompilerContext _context = new IncrementalCompilerContext();
 
   Compiler _compiler;
 
@@ -73,6 +75,7 @@
     if (diagnosticHandler == null) {
       throw new ArgumentError('diagnosticHandler is null.');
     }
+    _context.incrementalCompiler = this;
   }
 
   LibraryElement get mainApp => _compiler.mainApp;
@@ -120,9 +123,10 @@
     LibraryUpdater updater = new LibraryUpdater(
         _compiler,
         mappingInputProvider,
-        _compiler.mainApp.canonicalUri,
         logTime,
-        logVerbose);
+        logVerbose,
+        _context);
+    _context.registerUriWithUpdates(updatedFiles.keys);
     Future<Compiler> future = _reuseCompiler(updater.reuseLibrary);
     return future.then((Compiler compiler) {
       _compiler = compiler;
diff --git a/pkg/dart2js_incremental/lib/library_updater.dart b/pkg/dart2js_incremental/lib/library_updater.dart
index 2331ffb..09cb6f4 100644
--- a/pkg/dart2js_incremental/lib/library_updater.dart
+++ b/pkg/dart2js_incremental/lib/library_updater.dart
@@ -76,10 +76,16 @@
 import 'package:compiler/src/universe/universe.dart' show
     Selector;
 
+import 'package:compiler/src/constants/values.dart' show
+    ConstantValue;
+
 import 'diff.dart' show
     Difference,
     computeDifference;
 
+import 'dart2js_incremental.dart' show
+    IncrementalCompiler;
+
 typedef void Logger(message);
 
 typedef bool Reuser(
@@ -100,8 +106,46 @@
   }
 }
 
-// TODO(ahe): Generalize this class. For now only works for Compiler.mainApp,
-// and only if that library has exactly one compilation unit.
+abstract class _IncrementalCompilerContext {
+  IncrementalCompiler incrementalCompiler;
+
+  Set<ClassElementX> _emittedClasses;
+
+  Set<ClassElementX> _directlyInstantiatedClasses;
+
+  Set<ConstantValue> _compiledConstants;
+}
+
+class IncrementalCompilerContext extends _IncrementalCompilerContext {
+  final Set<Uri> _uriWithUpdates = new Set<Uri>();
+
+  void set incrementalCompiler(IncrementalCompiler value) {
+    if (super.incrementalCompiler != null) {
+      throw new StateError("Can't set [incrementalCompiler] more than once.");
+    }
+    super.incrementalCompiler = value;
+  }
+
+  void registerUriWithUpdates(Iterable<Uri> uris) {
+    _uriWithUpdates.addAll(uris);
+  }
+
+  void _captureState(Compiler compiler) {
+    _emittedClasses = new Set.from(compiler.backend.emitter.neededClasses);
+
+    _directlyInstantiatedClasses =
+        new Set.from(compiler.codegenWorld.directlyInstantiatedClasses);
+
+    List<ConstantValue> constants =
+        compiler.backend.emitter.outputConstantLists[
+            compiler.deferredLoadTask.mainOutputUnit];
+    if (constants == null) constants = <ConstantValue>[];
+    _compiledConstants = new Set<ConstantValue>.identity()..addAll(constants);
+  }
+
+  bool _uriHasUpdate(Uri uri) => _uriWithUpdates.contains(uri);
+}
+
 class LibraryUpdater extends JsFeatures {
   final Compiler compiler;
 
@@ -111,10 +155,6 @@
 
   final Logger logVerbose;
 
-  // TODO(ahe): Get rid of this field. It assumes that only one library has
-  // changed.
-  final Uri uri;
-
   final List<Update> updates = <Update>[];
 
   final List<FailedUpdate> _failedUpdates = <FailedUpdate>[];
@@ -126,19 +166,38 @@
   final Set<ClassElementX> _classesWithSchemaChanges =
       new Set<ClassElementX>();
 
-  final Set<ClassElementX> _existingClasses = new Set();
+  final IncrementalCompilerContext _context;
+
+  bool _hasComputedNeeds = false;
+
+  bool _hasCapturedCompilerState = false;
 
   LibraryUpdater(
       this.compiler,
       this.inputProvider,
-      this.uri,
       this.logTime,
-      this.logVerbose) {
-    if (compiler != null) {
-      _existingClasses.addAll(emitter.neededClasses);
-    }
+      this.logVerbose,
+      this._context) {
+    // TODO(ahe): Would like to remove this from the constructor. However, the
+    // state must be captured before calling [reuseCompiler].
+    // Proper solution might be: [reuseCompiler] should not clear the sets that
+    // are captured in [IncrementalCompilerContext._captureState].
+    _ensureCompilerStateCaptured();
   }
 
+  /// Returns the classes emitted by [compiler].
+  Set<ClassElementX> get _emittedClasses => _context._emittedClasses;
+
+  /// Returns the directly instantantiated classes seen by [compiler] (this
+  /// includes interfaces and may be different from [_emittedClasses] that only
+  /// includes interfaces used in type tests).
+  Set<ClassElementX> get _directlyInstantiatedClasses {
+    return _context._directlyInstantiatedClasses;
+  }
+
+  /// Returns the constants emitted by [compiler].
+  Set<ConstantValue> get _compiledConstants => _context._compiledConstants;
+
   /// When [true], updates must be applied (using [applyUpdates]) before the
   /// [compiler]'s state correctly reflects the updated program.
   bool get hasPendingUpdates => !updates.isEmpty;
@@ -147,16 +206,38 @@
 
   /// Used as tear-off passed to [LibraryLoaderTask.resetAsync].
   Future<bool> reuseLibrary(LibraryElement library) {
+    _ensureCompilerStateCaptured();
     assert(compiler != null);
-    if (library.isPlatformLibrary || library.isPackageLibrary) {
-      logTime('Reusing $library.');
+    if (library.isPlatformLibrary) {
+      logTime('Reusing $library (assumed read-only).');
       return new Future.value(true);
-    } else if (library != compiler.mainApp) {
-      return new Future.value(false);
     }
-    return inputProvider(uri).then((bytes) {
-      return canReuseLibrary(library, bytes);
-    });
+    for (CompilationUnitElementX unit in library.compilationUnits) {
+      Uri uri = unit.script.resourceUri;
+      if (_context._uriHasUpdate(uri)) {
+        if (!library.compilationUnits.tail.isEmpty) {
+          // TODO(ahe): Remove this restriction.
+          cannotReuse(library, "Multiple compilation units not supported.");
+          return new Future.value(true);
+        }
+        return inputProvider(uri).then((bytes) {
+          return canReuseLibrary(library, bytes);
+        });
+      }
+    }
+
+    logTime("Reusing $library, source didn't change.");
+    // Source code of [library] wasn't changed.
+    return new Future.value(true);
+  }
+
+  void _ensureCompilerStateCaptured() {
+    // TODO(ahe): [compiler] shouldn't be null, remove the following line.
+    if (compiler == null) return;
+
+    if (_hasCapturedCompilerState) return;
+    _context._captureState(compiler);
+    _hasCapturedCompilerState = true;
   }
 
   /// Returns true if [library] can be reused.
@@ -164,19 +245,11 @@
   /// This methods also computes the [updates] (patches) needed to have
   /// [library] reflect the modifications in [bytes].
   bool canReuseLibrary(LibraryElement library, bytes) {
-    logTime('Attempting to reuse mainApp.');
+    logTime('Attempting to reuse ${library}.');
     String newSource = bytes is String ? bytes : UTF8.decode(bytes);
     logTime('Decoded UTF8');
 
-    // TODO(ahe): Can't use compiler.mainApp in general.
-    if (false && newSource == compiler.mainApp.compilationUnit.script.text) {
-      // TODO(ahe): Need to update the compilationUnit's source code when
-      // doing incremental analysis for this to work.
-      logTime("Source didn't change");
-      return true;
-    }
-
-    logTime("Source did change");
+    Uri uri = library.entryCompilationUnit.script.resourceUri;
     Script sourceScript = new Script(
         uri, uri, new StringSourceFile('$uri', newSource));
     var dartPrivacyIsBroken = compiler.libraryLoader;
@@ -301,17 +374,10 @@
 
   void addField(FieldElementX element, ScopeContainerElement container) {
     invalidateScopesAffectedBy(element, container);
-    if (!element.isInstanceMember) {
-      cannotReuse(element, "Not an instance field.");
-    } else {
-      addInstanceField(element, container);
+    if (element.isInstanceMember) {
+      _classesWithSchemaChanges.add(container);
     }
-  }
-
-  void addInstanceField(FieldElementX element, ClassElementX cls) {
-    _classesWithSchemaChanges.add(cls);
-
-    updates.add(new AddedFieldUpdate(compiler, element, cls));
+    updates.add(new AddedFieldUpdate(compiler, element, container));
   }
 
   bool canReuseRemovedElement(
@@ -603,20 +669,24 @@
 
     List<jsAst.Statement> updates = <jsAst.Statement>[];
 
-    // TODO(ahe): allInstantiatedClasses seem to include interfaces that aren't
-    // needed.
     Set<ClassElementX> newClasses = new Set.from(
-        compiler.codegenWorld.allInstantiatedClasses.where(
-            emitter.computeClassFilter()));
-    newClasses.removeAll(_existingClasses);
+        compiler.codegenWorld.directlyInstantiatedClasses);
+    newClasses.removeAll(_directlyInstantiatedClasses);
 
-    // TODO(ahe): When more than one updated is computed, we need to make sure
-    // that existing classes aren't overwritten. No test except the one test
-    // that tests more than one update is affected by this problem, and only
-    // because main is closurized because we always enable tear-off. Is that
-    // really necessary? Also, add a test which tests directly that what
-    // happens when tear-off is introduced in second update.
-    emitter.neededClasses.addAll(newClasses);
+    if (!newClasses.isEmpty) {
+      // Ask the emitter to compute "needs" (only) if new classes were
+      // instantiated.
+      _ensureAllNeededEntitiesComputed();
+      newClasses = new Set.from(emitter.neededClasses);
+      newClasses.removeAll(_emittedClasses);
+    } else {
+      // Make sure that the set of emitted classes is preserved for subsequent
+      // updates.
+      // TODO(ahe): This is a bit convoluted, find a better approach.
+      emitter.neededClasses
+          ..clear()
+          ..addAll(_emittedClasses);
+    }
 
     List<jsAst.Statement> inherits = <jsAst.Statement>[];
 
@@ -633,8 +703,7 @@
         jsAst.Node superAccess = emitter.classAccess(superclass);
         inherits.add(
             js.statement(
-                r'self.$dart_unsafe_eval.inheritFrom(#, #)',
-                [classAccess, superAccess]));
+                r'#.inheritFrom(#, #)', [helper, classAccess, superAccess]));
       }
     }
 
@@ -651,29 +720,48 @@
       jsAst.Node classAccess = emitter.classAccess(cls);
       updates.add(
           js.statement(
-              r'# = self.$dart_unsafe_eval.schemaChange(#, #, #)',
-              [classAccess, invokeDefineClass(cls), classAccess, superAccess]));
+              r'# = #.schemaChange(#, #, #)',
+              [classAccess, helper,
+               invokeDefineClass(cls), classAccess, superAccess]));
     }
 
     for (RemovalUpdate update in removals) {
       update.writeUpdateJsOn(updates);
     }
     for (Element element in enqueuer.codegen.newlyEnqueuedElements) {
-      if (!element.isField) {
-        updates.add(computeMemberUpdateJs(element));
+      if (element.isField) {
+        updates.addAll(computeFieldUpdateJs(element));
       } else {
-        if (backend.constants.lazyStatics.contains(element)) {
-          throw new StateError("$element requires lazy initializer.");
+        updates.add(computeMethodUpdateJs(element));
+      }
+    }
+
+    Set<ConstantValue> newConstants = new Set<ConstantValue>.identity()..addAll(
+        compiler.backend.constants.compiledConstants);
+    newConstants.removeAll(_compiledConstants);
+
+    if (!newConstants.isEmpty) {
+      _ensureAllNeededEntitiesComputed();
+      List<ConstantValue> constants =
+          emitter.outputConstantLists[compiler.deferredLoadTask.mainOutputUnit];
+      if (constants != null) {
+        for (ConstantValue constant in constants) {
+          if (!_compiledConstants.contains(constant)) {
+            jsAst.Statement constantInitializer =
+                emitter.oldEmitter.buildConstantInitializer(constant)
+                .toStatement();
+            updates.add(constantInitializer);
+          }
         }
       }
     }
 
     updates.add(js.statement(r'''
-if (self.$dart_unsafe_eval.pendingStubs) {
-  self.$dart_unsafe_eval.pendingStubs.map(function(e) { return e(); });
-  self.$dart_unsafe_eval.pendingStubs = void 0;
+if (#helper.pendingStubs) {
+  #helper.pendingStubs.map(function(e) { return e(); });
+  #helper.pendingStubs = void 0;
 }
-'''));
+''', {'helper': helper}));
 
     if (updates.length == 1) {
       return prettyPrintJs(updates.single);
@@ -689,13 +777,15 @@
         r'''
 (new Function(
     "$collectedClasses", "$desc",
-    self.$dart_unsafe_eval.defineClass(#, #) +"\n;return " + #))({#: #})''',
-        [js.string(name), js.stringArray(computeFields(cls)),
-         js.string(name),
-         js.string(name), descriptor]);
+    #helper.defineClass(#name, #computeFields) +"\n;return " + #name))(
+        {#name: #descriptor})''',
+        {'helper': helper,
+         'name': js.string(name),
+         'computeFields': js.stringArray(computeFields(cls)),
+         'descriptor': descriptor});
   }
 
-  jsAst.Node computeMemberUpdateJs(Element element) {
+  jsAst.Node computeMethodUpdateJs(Element element) {
     MemberInfo info = containerBuilder.analyzeMemberMethod(element);
     if (info == null) {
       compiler.internalError(element, '${element.runtimeType}');
@@ -703,7 +793,7 @@
     ClassBuilder builder = new ClassBuilder(element, namer);
     containerBuilder.addMemberMethodFromInfo(info, builder);
     jsAst.Node partialDescriptor =
-        builder.toObjectInitializer(omitClassDescriptor: true);
+        builder.toObjectInitializer(emitClassDescriptor: false);
 
     String name = info.name;
     jsAst.Node function = info.code;
@@ -723,11 +813,38 @@
         emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
 
     return js.statement(
-        r'self.$dart_unsafe_eval.addMethod(#, #, #, #, #)',
-        [partialDescriptor, js.string(name), holder,
+        r'#.addMethod(#, #, #, #, #)',
+        [helper, partialDescriptor, js.string(name), holder,
          new jsAst.LiteralBool(isStatic), globalFunctionsAccess]);
   }
 
+  List<jsAst.Statement> computeFieldUpdateJs(FieldElementX element) {
+    if (element.isInstanceMember) {
+      // Any initializers are inlined in factory methods, and the field is
+      // declared by adding its class to [_classesWithSchemaChanges].
+      return const <jsAst.Statement>[];
+    }
+    // A static (or top-level) field.
+    if (backend.constants.lazyStatics.contains(element)) {
+      jsAst.Expression init =
+          emitter.oldEmitter.buildLazilyInitializedStaticField(
+              element, namer.currentIsolate);
+      if (init == null) {
+        throw new StateError("Initializer optimized away for $element");
+      }
+      return <jsAst.Statement>[init.toStatement()];
+    } else {
+      // TODO(ahe): When a field is referenced it is enqueued. If the field has
+      // no initializer, it will not have any associated code, so it will
+      // appear as if it was newly enqueued.
+      if (element.initializer == null) {
+        return const <jsAst.Statement>[];
+      } else {
+        throw new StateError("Don't know how to compile $element");
+      }
+    }
+  }
+
   String prettyPrintJs(jsAst.Node node) {
     jsAst.Printer printer = new jsAst.Printer(compiler, null);
     printer.blockOutWithoutBraces(node);
@@ -744,6 +861,12 @@
   List<String> computeFields(ClassElement cls) {
     return new EmitterHelper(compiler).computeFields(cls);
   }
+
+  void _ensureAllNeededEntitiesComputed() {
+    if (_hasComputedNeeds) return;
+    emitter.computeAllNeededEntities();
+    _hasComputedNeeds = true;
+  }
 }
 
 /// Represents an update (aka patch) of [before] to [after]. We use the word
@@ -1062,7 +1185,12 @@
   PartialFieldList get after => element.declarationSite;
 
   FieldElementX apply() {
-    FieldElementX copy = element.copyWithEnclosing(container);
+    Element enclosing = container;
+    if (enclosing.isLibrary) {
+      // TODO(ahe): Reuse compilation unit of element instead?
+      enclosing = enclosing.compilationUnit;
+    }
+    FieldElementX copy = element.copyWithEnclosing(enclosing);
     NO_WARN(container).addMember(copy, compiler);
     return copy;
   }
@@ -1191,6 +1319,8 @@
   ContainerBuilder get containerBuilder => emitter.oldEmitter.containerBuilder;
 
   EnqueueTask get enqueuer => compiler.enqueuer;
+
+  jsAst.Expression get helper => namer.accessIncrementalHelper;
 }
 
 class EmitterHelper extends JsFeatures {
@@ -1203,7 +1333,7 @@
   List<String> computeFields(ClassElement cls) {
     // TODO(ahe): Rewrite for new emitter.
     ClassBuilder builder = new ClassBuilder(cls, namer);
-    classEmitter.emitFields(cls, builder, "");
+    classEmitter.emitFields(cls, builder);
     return builder.fields;
   }
 }
diff --git a/pkg/docgen/lib/src/viewer.dart b/pkg/docgen/lib/src/viewer.dart
index b76bd9e..f5b7172 100644
--- a/pkg/docgen/lib/src/viewer.dart
+++ b/pkg/docgen/lib/src/viewer.dart
@@ -89,7 +89,7 @@
     if (processResult.exitCode == 0) {
       /// Move the generated json/yaml docs directory to the dartdoc-viewer
       /// directory, to run as a webpage.
-      var processResult = Process.runSync(gen.pubScript, ['upgrade'],
+      var processResult = Process.runSync(gen.pubScript, ['get'],
           runInShell: true, workingDirectory: _viewerCodePath);
       print('process output: ${processResult.stdout}');
       print('process stderr: ${processResult.stderr}');
diff --git a/pkg/glob/CHANGELOG.md b/pkg/glob/CHANGELOG.md
deleted file mode 100644
index 4a1e352..0000000
--- a/pkg/glob/CHANGELOG.md
+++ /dev/null
@@ -1,14 +0,0 @@
-## 1.0.3
-
-* Fix a bug where `Glob.list()` and `Glob.listSync()` would incorrectly throw
-  exceptions when a directory didn't exist on the filesystem.
-
-## 1.0.2
-
-* Fixed `Glob.list()` on Windows.
-
-## 1.0.1
-
-* Fix several analyzer warnings.
-
-* Fix the tests on Windows.
diff --git a/pkg/glob/LICENSE b/pkg/glob/LICENSE
deleted file mode 100644
index 5c60afe..0000000
--- a/pkg/glob/LICENSE
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright 2014, the Dart project authors. All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of Google Inc. nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/glob/README.md b/pkg/glob/README.md
deleted file mode 100644
index 5091a1e..0000000
--- a/pkg/glob/README.md
+++ /dev/null
@@ -1,124 +0,0 @@
-`glob` is a file and directory globbing library that supports both checking
-whether a path matches a glob and listing all entities that match a glob.
-
-A "glob" is a pattern designed specifically to match files and directories. Most
-shells support globs natively.
-
-## Usage
-
-To construct a glob, just use `new Glob()`. As with `RegExp`s, it's a good idea
-to keep around a glob if you'll be using it more than once so that it doesn't
-have to be compiled over and over. You can check whether a path matches the glob
-using `Glob.matches()`:
-
-```dart
-import 'package:glob/glob.dart';
-
-final dartFile = new Glob("**.dart");
-
-// Print all command-line arguments that are Dart files.
-void main(List<String> arguments) {
-  for (var argument in arguments) {
-    if (dartFile.matches(argument)) print(argument);
-  }
-}
-```
-
-You can also list all files that match a glob using `Glob.list()` or
-`Glob.listSync()`:
-
-```dart
-import 'package:glob/glob.dart';
-
-final dartFile = new Glob("**.dart");
-
-// Recursively list all Dart files in the current directory.
-void main(List<String> arguments) {
-  for (var entity in dartFile.listSync()) {
-    print(entity.path);
-  }
-}
-```
-
-## Syntax
-
-The glob syntax hews closely to the widely-known Bash glob syntax, with a few
-exceptions that are outlined below.
-
-In order to be as cross-platform and as close to the Bash syntax as possible,
-all globs use POSIX path syntax, including using `/` as a directory separator
-regardless of which platform they're on. This is true even for Windows roots;
-for example, a glob matching all files in the C drive would be `C:/*`.
-
-### Match any characters in a filename: `*`
-
-The `*` character matches zero or more of any character other than `/`. This
-means that it can be used to match all files in a given directory that match a
-pattern without also matching files in a subdirectory. For example, `lib/*.dart`
-will match `lib/glob.dart` but not `lib/src/utils.dart`.
-
-### Match any characters across directories: `**`
-
-`**` is like `*`, but matches `/` as well. It's useful for matching files or
-listing directories recursively. For example, `lib/**.dart` will match both
-`lib/glob.dart` and `lib/src/utils.dart`.
-
-If `**` appears at the beginning of a glob, it won't match absolute paths or
-paths beginning with `../`. For example, `**.dart` won't match `/foo.dart`,
-although `/**.dart` will. This is to ensure that listing a bunch of paths and
-checking whether they match a glob produces the same results as listing that
-glob. In the previous example, `/foo.dart` wouldn't be listed for `**.dart`, so
-it shouldn't be matched by it either.
-
-This is an extension to Bash glob syntax that's widely supported by other glob
-implementations.
-
-### Match any single character: `?`
-
-The `?` character matches a single character other than `/`. Unlike `*`, it
-won't match any more or fewer than one character. For example, `test?.dart` will
-match `test1.dart` but not `test10.dart` or `test.dart`.
-
-### Match a range of characters: `[...]`
-
-The `[...]` construction matches one of several characters. It can contain
-individual characters, such as `[abc]`, in which case it will match any of those
-characters; it can contain ranges, such as `[a-zA-Z]`, in which case it will
-match any characters that fall within the range; or it can contain a mix of
-both. It will only ever match a single character. For example,
-`test[a-zA-Z_].dart` will match `testx.dart`, `testA.dart`, and `test_.dart`,
-but not `test-.dart`.
-
-If it starts with `^` or `!`, the construction will instead match all characters
-*not* mentioned. For example, `test[^a-z].dart` will match `test1.dart` but not
-`testa.dart`.
-
-This construction never matches `/`.
-
-### Match one of several possibilities: `{...,...}`
-
-The `{...,...}` construction matches one of several options, each of which is a
-glob itself. For example, `lib/{*.dart,src/*}` matches `lib/glob.dart` and
-`lib/src/data.txt`. It can contain any number of options greater than one, and
-can even contain nested options.
-
-This is an extension to Bash glob syntax, although it is supported by other
-layers of Bash and is often used in conjunction with globs.
-
-### Escaping a character: `\`
-
-The `\` character can be used in any context to escape a character that would
-otherwise be semantically meaningful. For example, `\*.dart` matches `*.dart`
-but not `test.dart`.
-
-### Syntax errors
-
-Because they're used as part of the shell, almost all strings are valid Bash
-globs. This implementation is more picky, and performs some validation to ensure
-that globs are meaningful. For instance, unclosed `{` and `[` are disallowed.
-
-### Reserved syntax: `(...)`
-
-Parentheses are reserved in case this package adds support for Bash extended
-globbing in the future. For the time being, using them will throw an error
-unless they're escaped.
diff --git a/pkg/glob/lib/glob.dart b/pkg/glob/lib/glob.dart
deleted file mode 100644
index 2d2a83f..0000000
--- a/pkg/glob/lib/glob.dart
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library glob;
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:path/path.dart' as p;
-
-import 'src/ast.dart';
-import 'src/list_tree.dart';
-import 'src/parser.dart';
-import 'src/utils.dart';
-
-/// Regular expression used to quote globs.
-final _quoteRegExp = new RegExp(r'[*{[?\\}\],\-()]');
-
-/// A glob for matching and listing files and directories.
-///
-/// A glob matches an entire string as a path. Although the glob pattern uses
-/// POSIX syntax, it can match against POSIX, Windows, or URL paths. The format
-/// it expects paths to use is based on the `context` parameter to [new Glob];
-/// it defaults to the current system's syntax.
-///
-/// Paths are normalized before being matched against a glob, so for example the
-/// glob `foo/bar` matches the path `foo/./bar`. A relative glob can match an
-/// absolute path and vice versa; globs and paths are both interpreted as
-/// relative to `context.current`, which defaults to the current working
-/// directory.
-///
-/// When used as a [Pattern], a glob will return either one or zero matches for
-/// a string depending on whether the entire string matches the glob. These
-/// matches don't currently have capture groups, although this may change in the
-/// future.
-class Glob implements Pattern {
-  /// The pattern used to create this glob.
-  final String pattern;
-
-  /// The context in which paths matched against this glob are interpreted.
-  final p.Context context;
-
-  /// If true, a path matches if it matches the glob itself or is recursively
-  /// contained within a directory that matches.
-  final bool recursive;
-
-  /// The parsed AST of the glob.
-  final AstNode _ast;
-
-  ListTree _listTree;
-
-  /// Whether [context]'s current directory is absolute.
-  bool get _contextIsAbsolute {
-    if (_contextIsAbsoluteCache == null) {
-      _contextIsAbsoluteCache = context.isAbsolute(context.current);
-    }
-    return _contextIsAbsoluteCache;
-  }
-  bool _contextIsAbsoluteCache;
-
-  /// Whether [pattern] could match absolute paths.
-  bool get _patternCanMatchAbsolute {
-    if (_patternCanMatchAbsoluteCache == null) {
-      _patternCanMatchAbsoluteCache = _ast.canMatchAbsolute;
-    }
-    return _patternCanMatchAbsoluteCache;
-  }
-  bool _patternCanMatchAbsoluteCache;
-
-  /// Whether [pattern] could match relative paths.
-  bool get _patternCanMatchRelative {
-    if (_patternCanMatchRelativeCache == null) {
-      _patternCanMatchRelativeCache = _ast.canMatchRelative;
-    }
-    return _patternCanMatchRelativeCache;
-  }
-  bool _patternCanMatchRelativeCache;
-
-  /// Returns [contents] with characters that are meaningful in globs
-  /// backslash-escaped.
-  static String quote(String contents) =>
-      contents.replaceAllMapped(_quoteRegExp, (match) => '\\${match[0]}');
-
-  /// Creates a new glob with [pattern].
-  ///
-  /// Paths matched against the glob are interpreted according to [context]. It
-  /// defaults to the system context.
-  ///
-  /// If [recursive] is true, this glob will match and list not only the files
-  /// and directories it explicitly lists, but anything beneath those as well.
-  Glob(String pattern, {p.Context context, bool recursive: false})
-      : this._(
-          pattern,
-          context == null ? p.context : context,
-          recursive);
-
-  // Internal constructor used to fake local variables for [context] and [ast].
-  Glob._(String pattern, p.Context context, bool recursive)
-      : pattern = pattern,
-        context = context,
-        recursive = recursive,
-        _ast = new Parser(pattern + (recursive ? "{,/**}" : ""), context)
-            .parse();
-
-  /// Lists all [FileSystemEntity]s beneath [root] that match the glob.
-  ///
-  /// This works much like [Directory.list], but it only lists directories that
-  /// could contain entities that match the glob. It provides no guarantees
-  /// about the order of the returned entities, although it does guarantee that
-  /// only one entity with a given path will be returned.
-  ///
-  /// [root] defaults to the current working directory.
-  ///
-  /// [followLinks] works the same as for [Directory.list].
-  Stream<FileSystemEntity> list({String root, bool followLinks: true}) {
-    if (context.style != p.style) {
-      throw new StateError("Can't list glob \"$this\"; it matches "
-          "${context.style} paths, but this platform uses ${p.style} paths.");
-    }
-
-    if (_listTree == null) _listTree = new ListTree(_ast);
-    return _listTree.list(root: root, followLinks: followLinks);
-  }
-
-  /// Synchronously lists all [FileSystemEntity]s beneath [root] that match the
-  /// glob.
-  ///
-  /// This works much like [Directory.listSync], but it only lists directories
-  /// that could contain entities that match the glob. It provides no guarantees
-  /// about the order of the returned entities, although it does guarantee that
-  /// only one entity with a given path will be returned.
-  ///
-  /// [root] defaults to the current working directory.
-  ///
-  /// [followLinks] works the same as for [Directory.list].
-  List<FileSystemEntity> listSync({String root, bool followLinks: true}) {
-    if (context.style != p.style) {
-      throw new StateError("Can't list glob \"$this\"; it matches "
-          "${context.style} paths, but this platform uses ${p.style} paths.");
-    }
-
-    if (_listTree == null) _listTree = new ListTree(_ast);
-    return _listTree.listSync(root: root, followLinks: followLinks);
-  }
-
-  /// Returns whether this glob matches [path].
-  bool matches(String path) => matchAsPrefix(path) != null;
-
-  Match matchAsPrefix(String path, [int start = 0]) {
-    // Globs are like anchored RegExps in that they only match entire paths, so
-    // if the match starts anywhere after the first character it can't succeed.
-    if (start != 0) return null;
-
-    if (_patternCanMatchAbsolute &&
-        (_contextIsAbsolute || context.isAbsolute(path))) {
-      var absolutePath = context.normalize(context.absolute(path));
-      if (_ast.matches(toPosixPath(context, absolutePath))) {
-        return new GlobMatch(path, this);
-      }
-    }
-
-    if (_patternCanMatchRelative) {
-      var relativePath = context.relative(path);
-      if (_ast.matches(toPosixPath(context, relativePath))) {
-        return new GlobMatch(path, this);
-      }
-    }
-
-    return null;
-  }
-
-  Iterable<Match> allMatches(String path, [int start = 0]) {
-    var match = matchAsPrefix(path, start);
-    return match == null ? [] : [match];
-  }
-
-  String toString() => pattern;
-}
diff --git a/pkg/glob/lib/src/ast.dart b/pkg/glob/lib/src/ast.dart
deleted file mode 100644
index 1913477..0000000
--- a/pkg/glob/lib/src/ast.dart
+++ /dev/null
@@ -1,372 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library glob.ast;
-
-import 'package:path/path.dart' as p;
-import 'package:collection/collection.dart';
-
-import 'utils.dart';
-
-const _SEPARATOR = 0x2F; // "/"
-
-/// A node in the abstract syntax tree for a glob.
-abstract class AstNode {
-  /// The cached regular expression that this AST was compiled into.
-  RegExp _regExp;
-
-  /// Whether this glob could match an absolute path.
-  ///
-  /// Either this or [canMatchRelative] or both will be true.
-  final bool canMatchAbsolute = false;
-
-  /// Whether this glob could match a relative path.
-  ///
-  /// Either this or [canMatchRelative] or both will be true.
-  final bool canMatchRelative = true;
-
-  /// Returns a new glob with all the options bubbled to the top level.
-  ///
-  /// In particular, this returns a glob AST with two guarantees:
-  ///
-  /// 1. There are no [OptionsNode]s other than the one at the top level.
-  /// 2. It matches the same set of paths as [this].
-  ///
-  /// For example, given the glob `{foo,bar}/{click/clack}`, this would return
-  /// `{foo/click,foo/clack,bar/click,bar/clack}`.
-  OptionsNode flattenOptions() => new OptionsNode([new SequenceNode([this])]);
-
-  /// Returns whether this glob matches [string].
-  bool matches(String string) {
-    if (_regExp == null) _regExp = new RegExp('^${_toRegExp()}\$');
-    return _regExp.hasMatch(string);
-  }
-
-  /// Subclasses should override this to return a regular expression component.
-  String _toRegExp();
-}
-
-/// A sequence of adjacent AST nodes.
-class SequenceNode extends AstNode {
-  /// The nodes in the sequence.
-  final List<AstNode> nodes;
-
-  bool get canMatchAbsolute => nodes.first.canMatchAbsolute;
-  bool get canMatchRelative => nodes.first.canMatchRelative;
-
-  SequenceNode(Iterable<AstNode> nodes)
-      : nodes = nodes.toList();
-
-  OptionsNode flattenOptions() {
-    if (nodes.isEmpty) return new OptionsNode([this]);
-
-    var sequences = nodes.first.flattenOptions().options
-        .map((sequence) => sequence.nodes);
-    for (var node in nodes.skip(1)) {
-      // Concatenate all sequences in the next options node ([nextSequences])
-      // onto all previous sequences ([sequences]).
-      var nextSequences = node.flattenOptions().options;
-      sequences = sequences.expand((sequence) {
-        return nextSequences.map((nextSequence) {
-          return sequence.toList()..addAll(nextSequence.nodes);
-        });
-      });
-    }
-
-    return new OptionsNode(sequences.map((sequence) {
-      // Combine any adjacent LiteralNodes in [sequence].
-      return new SequenceNode(sequence.fold([], (combined, node) {
-        if (combined.isEmpty || combined.last is! LiteralNode ||
-            node is! LiteralNode) {
-          return combined..add(node);
-        }
-
-        combined[combined.length - 1] =
-            new LiteralNode(combined.last.text + node.text);
-        return combined;
-      }));
-    }));
-  }
-
-  /// Splits this glob into components along its path separators.
-  ///
-  /// For example, given the glob `foo/*/*.dart`, this would return three globs:
-  /// `foo`, `*`, and `*.dart`.
-  ///
-  /// Path separators within options nodes are not split. For example,
-  /// `foo/{bar,baz/bang}/qux` will return three globs: `foo`, `{bar,baz/bang}`,
-  /// and `qux`.
-  ///
-  /// [context] is used to determine what absolute roots look like for this
-  /// glob.
-  List<SequenceNode> split(p.Context context) {
-    var componentsToReturn = [];
-    var currentComponent;
-
-    addNode(node) {
-      if (currentComponent == null) currentComponent = [];
-      currentComponent.add(node);
-    }
-
-    finishComponent() {
-      if (currentComponent == null) return;
-      componentsToReturn.add(new SequenceNode(currentComponent));
-      currentComponent = null;
-    }
-
-    for (var node in nodes) {
-      if (node is! LiteralNode || !node.text.contains('/')) {
-        addNode(node);
-        continue;
-      }
-
-      var text = node.text;
-      if (context.style == p.Style.windows) text = text.replaceAll("/", "\\");
-      var components = context.split(text);
-
-      // If the first component is absolute, that means it's a separator (on
-      // Windows some non-separator things are also absolute, but it's invalid
-      // to have "C:" show up in the middle of a path anyway).
-      if (context.isAbsolute(components.first)) {
-        // If this is the first component, it's the root.
-        if (componentsToReturn.isEmpty && currentComponent == null) {
-          var root = components.first;
-          if (context.style == p.Style.windows) {
-            // Above, we switched to backslashes to make [context.split] handle
-            // roots properly. That means that if there is a root, it'll still
-            // have backslashes, where forward slashes are required for globs.
-            // So we switch it back here.
-            root = root.replaceAll("\\", "/");
-          }
-          addNode(new LiteralNode(root));
-        }
-        finishComponent();
-        components = components.skip(1);
-        if (components.isEmpty) continue;
-      }
-
-      // For each component except the last one, add a separate sequence to
-      // [sequences] containing only that component.
-      for (var component in components.take(components.length - 1)) {
-        addNode(new LiteralNode(component));
-        finishComponent();
-      }
-
-      // For the final component, only end its sequence (by adding a new empty
-      // sequence) if it ends with a separator.
-      addNode(new LiteralNode(components.last));
-      if (node.text.endsWith('/')) finishComponent();
-    }
-
-    finishComponent();
-    return componentsToReturn;
-  }
-
-  String _toRegExp() => nodes.map((node) => node._toRegExp()).join();
-
-  bool operator==(Object other) => other is SequenceNode &&
-      const IterableEquality().equals(nodes, other.nodes);
-
-  int get hashCode => const IterableEquality().hash(nodes);
-
-  String toString() => nodes.join();
-}
-
-/// A node matching zero or more non-separator characters.
-class StarNode extends AstNode {
-  StarNode();
-
-  String _toRegExp() => '[^/]*';
-
-  bool operator==(Object other) => other is StarNode;
-
-  int get hashCode => 0;
-
-  String toString() => '*';
-}
-
-/// A node matching zero or more characters that may be separators.
-class DoubleStarNode extends AstNode {
-  /// The path context for the glob.
-  ///
-  /// This is used to determine what absolute paths look like.
-  final p.Context _context;
-
-  DoubleStarNode(this._context);
-
-  String _toRegExp() {
-    // Double star shouldn't match paths with a leading "../", since these paths
-    // wouldn't be listed with this glob. We only check for "../" at the
-    // beginning since the paths are normalized before being checked against the
-    // glob.
-    var buffer = new StringBuffer()..write(r'(?!^(?:\.\./|');
-
-    // A double star at the beginning of the glob also shouldn't match absolute
-    // paths, since those also wouldn't be listed. Which root patterns we look
-    // for depends on the style of path we're matching.
-    if (_context.style == p.Style.posix) {
-      buffer.write(r'/');
-    } else if (_context.style == p.Style.windows) {
-      buffer.write(r'//|[A-Za-z]:/');
-    } else {
-      assert(_context.style == p.Style.url);
-      buffer.write(r'[a-zA-Z][-+.a-zA-Z\d]*://|/');
-    }
-
-    // Use `[^]` rather than `.` so that it matches newlines as well.
-    buffer.write(r'))[^]*');
-
-    return buffer.toString();
-  }
-
-  bool operator==(Object other) => other is DoubleStarNode;
-
-  int get hashCode => 1;
-
-  String toString() => '**';
-}
-
-/// A node matching a single non-separator character.
-class AnyCharNode extends AstNode {
-  AnyCharNode();
-
-  String _toRegExp() => '[^/]';
-
-  bool operator==(Object other) => other is AnyCharNode;
-
-  int get hashCode => 2;
-
-  String toString() => '?';
-}
-
-/// A node matching a single character in a range of options.
-class RangeNode extends AstNode {
-  /// The ranges matched by this node.
-  ///
-  /// The ends of the ranges are unicode code points.
-  final Set<Range> ranges;
-
-  /// Whether this range was negated.
-  final bool negated;
-
-  RangeNode(Iterable<Range> ranges, {this.negated})
-      : ranges = ranges.toSet();
-
-  OptionsNode flattenOptions() {
-    if (negated || ranges.any((range) => !range.isSingleton)) {
-      return super.flattenOptions();
-    }
-
-    // If a range explicitly lists a set of characters, return each character as
-    // a separate expansion.
-    return new OptionsNode(ranges.map((range) {
-      return new SequenceNode([
-        new LiteralNode(new String.fromCharCodes([range.min]))
-      ]);
-    }));
-  }
-
-  String _toRegExp() {
-    var buffer = new StringBuffer();
-
-    var containsSeparator = ranges.any((range) => range.contains(_SEPARATOR));
-    if (!negated && containsSeparator) {
-      // Add `(?!/)` because ranges are never allowed to match separators.
-      buffer.write('(?!/)');
-    }
-
-    buffer.write('[');
-    if (negated) {
-      buffer.write('^');
-      // If the range doesn't itself exclude separators, exclude them ourselves,
-      // since ranges are never allowed to match them.
-      if (!containsSeparator) buffer.write('/');
-    }
-
-    for (var range in ranges) {
-      var start = new String.fromCharCodes([range.min]);
-      buffer.write(regExpQuote(start));
-      if (range.isSingleton) continue;
-      buffer.write('-');
-      buffer.write(regExpQuote(new String.fromCharCodes([range.max])));
-    }
-
-    buffer.write(']');
-    return buffer.toString();
-  }
-
-  bool operator==(Object other) {
-    if (other is! RangeNode) return false;
-    if ((other as RangeNode).negated != negated) return false;
-    return const SetEquality().equals(ranges, (other as RangeNode).ranges);
-  }
-
-  int get hashCode => (negated ? 1 : 3) * const SetEquality().hash(ranges);
-
-  String toString() {
-    var buffer = new StringBuffer()..write('[');
-    for (var range in ranges) {
-      buffer.writeCharCode(range.min);
-      if (range.isSingleton) continue;
-      buffer.write('-');
-      buffer.writeCharCode(range.max);
-    }
-    buffer.write(']');
-    return buffer.toString();
-  }
-}
-
-/// A node that matches one of several options.
-class OptionsNode extends AstNode {
-  /// The options to match.
-  final List<SequenceNode> options;
-
-  bool get canMatchAbsolute => options.any((node) => node.canMatchAbsolute);
-  bool get canMatchRelative => options.any((node) => node.canMatchRelative);
-
-  OptionsNode(Iterable<SequenceNode> options)
-      : options = options.toList();
-
-  OptionsNode flattenOptions() => new OptionsNode(
-      options.expand((option) => option.flattenOptions().options));
-
-  String _toRegExp() =>
-      '(?:${options.map((option) => option._toRegExp()).join("|")})';
-
-  bool operator==(Object other) => other is OptionsNode &&
-      const UnorderedIterableEquality().equals(options, other.options);
-
-  int get hashCode => const UnorderedIterableEquality().hash(options);
-
-  String toString() => '{${options.join(',')}}';
-}
-
-/// A node that matches a literal string.
-class LiteralNode extends AstNode {
-  /// The string to match.
-  final String text;
-
-  /// The path context for the glob.
-  ///
-  /// This is used to determine whether this could match an absolute path.
-  final p.Context _context;
-
-  bool get canMatchAbsolute {
-    var nativeText = _context.style == p.Style.windows ?
-        text.replaceAll('/', '\\') : text;
-    return _context.isAbsolute(nativeText);
-  }
-
-  bool get canMatchRelative => !canMatchAbsolute;
-
-  LiteralNode(this.text, [this._context]);
-
-  String _toRegExp() => regExpQuote(text);
-
-  bool operator==(Object other) => other is LiteralNode && other.text == text;
-
-  int get hashCode => text.hashCode;
-
-  String toString() => text;
-}
diff --git a/pkg/glob/lib/src/list_tree.dart b/pkg/glob/lib/src/list_tree.dart
deleted file mode 100644
index 3667d63..0000000
--- a/pkg/glob/lib/src/list_tree.dart
+++ /dev/null
@@ -1,420 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library glob.list_tree;
-
-import 'dart:io';
-import 'dart:async';
-
-import 'package:path/path.dart' as p;
-
-import 'ast.dart';
-import 'stream_pool.dart';
-import 'utils.dart';
-
-/// The errno for a file or directory not existing on Mac and Linux.
-const _ENOENT = 2;
-
-/// Another errno we see on Windows when trying to list a non-existent
-/// directory.
-const _ENOENT_WIN = 3;
-
-/// A structure built from a glob that efficiently lists filesystem entities
-/// that match that glob.
-///
-/// This structure is designed to list the minimal number of physical
-/// directories necessary to find everything that matches the glob. For example,
-/// for the glob `foo/{bar,baz}/*`, there's no need to list the working
-/// directory or even `foo/`; only `foo/bar` and `foo/baz` should be listed.
-///
-/// This works by creating a tree of [_ListTreeNode]s, each of which corresponds
-/// to a single of directory nesting in the source glob. Each node has child
-/// nodes associated with globs ([_ListTreeNode.children]), as well as its own
-/// glob ([_ListTreeNode._validator]) that indicates which entities within that
-/// node's directory should be returned.
-///
-/// For example, the glob `foo/{*.dart,b*/*.txt}` creates the following tree:
-///
-///     .
-///     '-- "foo" (validator: "*.dart")
-///         '-- "b*" (validator: "*.txt"
-///
-/// If a node doesn't have a validator, we know we don't have to list it
-/// explicitly.
-///
-/// Nodes can also be marked as "recursive", which means they need to be listed
-/// recursively (usually to support `**`). In this case, they will have no
-/// children; instead, their validator will just encompass the globs that would
-/// otherwise be in their children. For example, the glob
-/// `foo/{**.dart,bar/*.txt}` creates a recursive node for `foo` with the
-/// validator `**.dart,bar/*.txt`.
-///
-/// If the glob contains multiple filesystem roots (e.g. `{C:/,D:/}*.dart`),
-/// each root will have its own tree of nodes. Relative globs use `.` as their
-/// root instead.
-class ListTree {
-  /// A map from filesystem roots to the list tree for those roots.
-  ///
-  /// A relative glob will use `.` as its root.
-  final _trees = new Map<String, _ListTreeNode>();
-
-  /// Whether paths listed might overlap.
-  ///
-  /// If they do, we need to filter out overlapping paths.
-  bool _canOverlap;
-
-  ListTree(AstNode glob) {
-    // The first step in constructing a tree from the glob is to simplify the
-    // problem by eliminating options. [glob.flattenOptions] bubbles all options
-    // (and certain ranges) up to the top level of the glob so we can deal with
-    // them one at a time.
-    var options = glob.flattenOptions();
-
-    for (var option in options.options) {
-      // Since each option doesn't include its own options, we can safely split
-      // it into path components.
-      var components = option.split(p.context);
-      var firstNode = components.first.nodes.first;
-      var root = '.';
-
-      // Determine the root for this option, if it's absolute. If it's not, the
-      // root's just ".".
-      if (firstNode is LiteralNode) {
-        var text = firstNode.text;
-        if (Platform.isWindows) text.replaceAll("/", "\\");
-        if (p.isAbsolute(text)) {
-          // If the path is absolute, the root should be the only thing in the
-          // first component.
-          assert(components.first.nodes.length == 1);
-          root = firstNode.text;
-          components.removeAt(0);
-        }
-      }
-
-      _addGlob(root, components);
-    }
-
-    _canOverlap = _computeCanOverlap();
-  }
-
-  /// Add the glob represented by [components] to the tree under [root].
-  void _addGlob(String root, List<AstNode> components) {
-    // The first [parent] represents the root directory itself. It may be null
-    // here if this is the first option with this particular [root]. If so,
-    // we'll create it below.
-    //
-    // As we iterate through [components], [parent] will be set to
-    // progressively more nested nodes.
-    var parent = _trees[root];
-    for (var i = 0; i < components.length; i++) {
-      var component = components[i];
-      var recursive = component.nodes.any((node) => node is DoubleStarNode);
-      var complete = i == components.length - 1;
-
-      // If the parent node for this level of nesting already exists, the new
-      // option will be added to it as additional validator options and/or
-      // additional children.
-      //
-      // If the parent doesn't exist, we'll create it in one of the else
-      // clauses below.
-      if (parent != null) {
-        if (parent.isRecursive || recursive) {
-          // If [component] is recursive, mark [parent] as recursive. This
-          // will cause all of its children to be folded into its validator.
-          // If [parent] was already recursive, this is a no-op.
-          parent.makeRecursive();
-
-          // Add [component] and everything nested beneath it as an option to
-          // [parent]. Since [parent] is recursive, it will recursively list
-          // everything beneath it and filter them with one big glob.
-          parent.addOption(_join(components.sublist(i)));
-          return;
-        } else if (complete) {
-          // If [component] is the last component, add it to [parent]'s
-          // validator but not to its children.
-          parent.addOption(component);
-        } else {
-          // On the other hand if there are more components, add [component]
-          // to [parent]'s children and not its validator. Since we process
-          // each option's components separately, the same component is never
-          // both a validator and a child.
-          if (!parent.children.containsKey(component)) {
-            parent.children[component] = new _ListTreeNode();
-          }
-          parent = parent.children[component];
-        }
-      } else if (recursive) {
-        _trees[root] = new _ListTreeNode.recursive(
-            _join(components.sublist(i)));
-        return;
-      } else if (complete) {
-        _trees[root] = new _ListTreeNode()..addOption(component);
-      } else {
-        _trees[root] = new _ListTreeNode();
-        _trees[root].children[component] = new _ListTreeNode();
-        parent = _trees[root].children[component];
-      }
-    }
-  }
-
-  /// Computes the value for [_canOverlap].
-  bool _computeCanOverlap() {
-    // If this can list a relative path and an absolute path, the former may be
-    // contained within the latter.
-    if (_trees.length > 1 && _trees.containsKey('.')) return true;
-
-    // Otherwise, this can only overlap if the tree beneath any given root could
-    // overlap internally.
-    return _trees.values.any((node) => node.canOverlap);
-  }
-
-  /// List all entities that match this glob beneath [root].
-  Stream<FileSystemEntity> list({String root, bool followLinks: true}) {
-    if (root == null) root = '.';
-    var pool = new StreamPool();
-    for (var rootDir in _trees.keys) {
-      var dir = rootDir == '.' ? root : rootDir;
-      pool.add(_trees[rootDir].list(dir, followLinks: followLinks));
-    }
-    pool.closeWhenEmpty();
-
-    if (!_canOverlap) return pool.stream;
-
-    // TODO(nweiz): Rather than filtering here, avoid double-listing directories
-    // in the first place.
-    var seen = new Set();
-    return pool.stream.where((entity) {
-      if (seen.contains(entity.path)) return false;
-      seen.add(entity.path);
-      return true;
-    });
-  }
-
-  /// Synchronosuly list all entities that match this glob beneath [root].
-  List<FileSystemEntity> listSync({String root, bool followLinks: true}) {
-    if (root == null) root = '.';
-
-    var result = _trees.keys.expand((rootDir) {
-      var dir = rootDir == '.' ? root : rootDir;
-      return _trees[rootDir].listSync(dir, followLinks: followLinks);
-    });
-
-    if (!_canOverlap) return result.toList();
-
-    // TODO(nweiz): Rather than filtering here, avoid double-listing directories
-    // in the first place.
-    var seen = new Set();
-    return result.where((entity) {
-      if (seen.contains(entity.path)) return false;
-      seen.add(entity.path);
-      return true;
-    }).toList();
-  }
-}
-
-/// A single node in a [ListTree].
-class _ListTreeNode {
-  /// This node's child nodes, by their corresponding globs.
-  ///
-  /// Each child node will only be listed on directories that match its glob.
-  ///
-  /// This may be `null`, indicating that this node should be listed
-  /// recursively.
-  Map<SequenceNode, _ListTreeNode> children;
-
-  /// This node's validator.
-  ///
-  /// This determines which entities will ultimately be emitted when [list] is
-  /// called.
-  OptionsNode _validator;
-
-  /// Whether this node is recursive.
-  ///
-  /// A recursive node has no children and is listed recursively.
-  bool get isRecursive => children == null;
-
-  /// Whether this node doesn't itself need to be listed.
-  ///
-  /// If a node has no validator and all of its children are literal filenames,
-  /// there's no need to list its contents. We can just directly traverse into
-  /// its children.
-  bool get _isIntermediate {
-    if (_validator != null) return false;
-    return children.keys.every((sequence) =>
-        sequence.nodes.length == 1 && sequence.nodes.first is LiteralNode);
-  }
-
-  /// Returns whether listing this node might return overlapping results.
-  bool get canOverlap {
-    // A recusive node can never overlap with itself, because it will only ever
-    // involve a single call to [Directory.list] that's then filtered with
-    // [_validator].
-    if (isRecursive) return false;
-
-    // If there's more than one child node and at least one of the children is
-    // dynamic (that is, matches more than just a literal string), there may be
-    // overlap.
-    if (children.length > 1 && children.keys.any((sequence) =>
-          sequence.nodes.length > 1 || sequence.nodes.single is! LiteralNode)) {
-      return true;
-    }
-
-    return children.values.any((node) => node.canOverlap);
-  }
-
-  /// Creates a node with no children and no validator.
-  _ListTreeNode()
-      : children = new Map<SequenceNode, _ListTreeNode>(),
-        _validator = null;
-
-  /// Creates a recursive node the given [validator].
-  _ListTreeNode.recursive(SequenceNode validator)
-      : children = null,
-        _validator = new OptionsNode([validator]);
-
-  /// Transforms this into recursive node, folding all its children into its
-  /// validator.
-  void makeRecursive() {
-    if (isRecursive) return;
-    _validator = new OptionsNode(children.keys.map((sequence) {
-      var child = children[sequence];
-      child.makeRecursive();
-      return _join([sequence, child._validator]);
-    }));
-    children = null;
-  }
-
-  /// Adds [validator] to this node's existing validator.
-  void addOption(SequenceNode validator) {
-    if (_validator == null) {
-      _validator = new OptionsNode([validator]);
-    } else {
-      _validator.options.add(validator);
-    }
-  }
-
-  /// Lists all entities within [dir] matching this node or its children.
-  ///
-  /// This may return duplicate entities. These will be filtered out in
-  /// [ListTree.list].
-  Stream<FileSystemEntity> list(String dir, {bool followLinks: true}) {
-    if (isRecursive) {
-      return new Directory(dir).list(recursive: true, followLinks: followLinks)
-          .where((entity) => _matches(entity.path.substring(dir.length + 1)));
-    }
-
-    var resultPool = new StreamPool();
-
-    // Don't spawn extra [Directory.list] calls when we already know exactly
-    // which subdirectories we're interested in.
-    if (_isIntermediate) {
-      children.forEach((sequence, child) {
-        resultPool.add(child.list(p.join(dir, sequence.nodes.single.text),
-            followLinks: followLinks));
-      });
-      resultPool.closeWhenEmpty();
-      return resultPool.stream;
-    }
-
-    var resultController = new StreamController(sync: true);
-    resultPool.add(resultController.stream);
-    new Directory(dir).list(followLinks: followLinks).listen((entity) {
-      var basename = entity.path.substring(dir.length + 1);
-      if (_matches(basename)) resultController.add(entity);
-
-      children.forEach((sequence, child) {
-        if (entity is! Directory) return;
-        if (!sequence.matches(basename)) return;
-        var stream = child.list(p.join(dir, basename), followLinks: followLinks)
-            .handleError((_) {}, test: (error) {
-          // Ignore errors from directories not existing. We do this here so
-          // that we only ignore warnings below wild cards. For example, the
-          // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but
-          // succeed if "foo/bar/qux/baz" doesn't exist.
-          return error is FileSystemException &&
-              (error.osError.errorCode == _ENOENT ||
-              error.osError.errorCode == _ENOENT_WIN);
-        });
-        resultPool.add(stream);
-      });
-    },
-        onError: resultController.addError,
-        onDone: resultController.close);
-
-    resultPool.closeWhenEmpty();
-    return resultPool.stream;
-  }
-
-  /// Synchronously lists all entities within [dir] matching this node or its
-  /// children.
-  ///
-  /// This may return duplicate entities. These will be filtered out in
-  /// [ListTree.listSync].
-  Iterable<FileSystemEntity> listSync(String dir, {bool followLinks: true}) {
-    if (isRecursive) {
-      return new Directory(dir)
-          .listSync(recursive: true, followLinks: followLinks)
-          .where((entity) => _matches(entity.path.substring(dir.length + 1)));
-    }
-
-    // Don't spawn extra [Directory.listSync] calls when we already know exactly
-    // which subdirectories we're interested in.
-    if (_isIntermediate) {
-      return children.keys.expand((sequence) {
-        return children[sequence].listSync(
-            p.join(dir, sequence.nodes.single.text), followLinks: followLinks);
-      });
-    }
-
-    return new Directory(dir).listSync(followLinks: followLinks)
-        .expand((entity) {
-      var entities = [];
-      var basename = entity.path.substring(dir.length + 1);
-      if (_matches(basename)) entities.add(entity);
-      if (entity is! Directory) return entities;
-
-      entities.addAll(children.keys
-          .where((sequence) => sequence.matches(basename))
-          .expand((sequence) {
-        try {
-          return children[sequence].listSync(
-              p.join(dir, basename), followLinks: followLinks).toList();
-        } on FileSystemException catch (error) {
-          // Ignore errors from directories not existing. We do this here so
-          // that we only ignore warnings below wild cards. For example, the
-          // glob "foo/bar/*/baz" should fail if "foo/bar" doesn't exist but
-          // succeed if "foo/bar/qux/baz" doesn't exist.
-          if (error.osError.errorCode == _ENOENT ||
-              error.osError.errorCode == _ENOENT_WIN) {
-            return const [];
-          } else {
-            rethrow;
-          }
-        }
-      }));
-
-      return entities;
-    });
-  }
-
-  /// Returns whether the native [path] matches [_validator].
-  bool _matches(String path) {
-    if (_validator == null) return false;
-    return _validator.matches(toPosixPath(p.context, path));
-  }
-
-  String toString() => "($_validator) $children";
-}
-
-/// Joins each [components] into a new glob where each component is separated by
-/// a path separator.
-SequenceNode _join(Iterable<AstNode> components) {
-  var componentsList = components.toList();
-  var nodes = [componentsList.removeAt(0)];
-  for (var component in componentsList) {
-    nodes.add(new LiteralNode('/'));
-    nodes.add(component);
-  }
-  return new SequenceNode(nodes);
-}
diff --git a/pkg/glob/lib/src/parser.dart b/pkg/glob/lib/src/parser.dart
deleted file mode 100644
index 5dac146..0000000
--- a/pkg/glob/lib/src/parser.dart
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library glob.single_component;
-
-import 'package:path/path.dart' as p;
-import 'package:string_scanner/string_scanner.dart';
-
-import 'ast.dart';
-import 'utils.dart';
-
-const _HYPHEN = 0x2D;
-const _SLASH = 0x2F;
-
-/// A parser for globs.
-class Parser {
-  /// The scanner used to scan the source.
-  final StringScanner _scanner;
-
-  /// The path context for the glob.
-  final p.Context _context;
-
-  Parser(String component, this._context)
-      : _scanner = new StringScanner(component);
-
-  /// Parses an entire glob.
-  SequenceNode parse() => _parseSequence();
-
-  /// Parses a [SequenceNode].
-  ///
-  /// If [inOptions] is true, this is parsing within an [OptionsNode].
-  SequenceNode _parseSequence({bool inOptions: false}) {
-    var nodes = [];
-
-    if (_scanner.isDone) {
-      _scanner.error('expected a glob.', position: 0, length: 0);
-    }
-
-    while (!_scanner.isDone) {
-      if (inOptions && (_scanner.matches(',') || _scanner.matches('}'))) break;
-      nodes.add(_parseNode(inOptions: inOptions));
-    }
-
-    return new SequenceNode(nodes);
-  }
-
-  /// Parses an [AstNode].
-  ///
-  /// If [inOptions] is true, this is parsing within an [OptionsNode].
-  AstNode _parseNode({bool inOptions: false}) {
-    var star = _parseStar();
-    if (star != null) return star;
-
-    var anyChar = _parseAnyChar();
-    if (anyChar != null) return anyChar;
-
-    var range = _parseRange();
-    if (range != null) return range;
-
-    var options = _parseOptions();
-    if (options != null) return options;
-
-    return _parseLiteral(inOptions: inOptions);
-  }
-
-  /// Tries to parse a [StarNode] or a [DoubleStarNode].
-  ///
-  /// Returns `null` if there's not one to parse.
-  AstNode _parseStar() {
-    if (!_scanner.scan('*')) return null;
-    return _scanner.scan('*') ? new DoubleStarNode(_context) : new StarNode();
-  }
-
-  /// Tries to parse an [AnyCharNode].
-  ///
-  /// Returns `null` if there's not one to parse.
-  AstNode _parseAnyChar() {
-    if (!_scanner.scan('?')) return null;
-    return new AnyCharNode();
-  }
-
-  /// Tries to parse an [RangeNode].
-  ///
-  /// Returns `null` if there's not one to parse.
-  AstNode _parseRange() {
-    if (!_scanner.scan('[')) return null;
-    if (_scanner.matches(']')) _scanner.error('unexpected "]".');
-    var negated = _scanner.scan('!') || _scanner.scan('^');
-
-    readRangeChar() {
-      var char = _scanner.readChar();
-      if (negated || char != _SLASH) return char;
-      _scanner.error('"/" may not be used in a range.',
-          position: _scanner.position - 1);
-    }
-
-    var ranges = [];
-    while (!_scanner.scan(']')) {
-      var start = _scanner.position;
-      // Allow a backslash to escape a character.
-      _scanner.scan('\\');
-      var char = readRangeChar();
-
-      if (_scanner.scan('-')) {
-        if (_scanner.matches(']')) {
-          ranges.add(new Range.singleton(char));
-          ranges.add(new Range.singleton(_HYPHEN));
-          continue;
-        }
-
-        // Allow a backslash to escape a character.
-        _scanner.scan('\\');
-
-        var end = readRangeChar();
-
-        if (end < char) {
-          _scanner.error("Range out of order.",
-              position: start,
-              length: _scanner.position - start);
-        }
-        ranges.add(new Range(char, end));
-      } else {
-        ranges.add(new Range.singleton(char));
-      }
-    }
-
-    return new RangeNode(ranges, negated: negated);
-  }
-
-  /// Tries to parse an [OptionsNode].
-  ///
-  /// Returns `null` if there's not one to parse.
-  AstNode _parseOptions() {
-    if (!_scanner.scan('{')) return null;
-    if (_scanner.matches('}')) _scanner.error('unexpected "}".');
-
-    var options = [];
-    do {
-      options.add(_parseSequence(inOptions: true));
-    } while (_scanner.scan(','));
-
-    // Don't allow single-option blocks.
-    if (options.length == 1) _scanner.expect(',');
-    _scanner.expect('}');
-
-    return new OptionsNode(options);
-  }
-
-  /// Parses a [LiteralNode].
-  AstNode _parseLiteral({bool inOptions: false}) {
-    // If we're in an options block, we want to stop parsing as soon as we hit a
-    // comma. Otherwise, commas are fair game for literals.
-    var regExp = new RegExp(
-        inOptions ? r'[^*{[?\\}\],()]*' : r'[^*{[?\\}\]()]*');
-
-    _scanner.scan(regExp);
-    var buffer = new StringBuffer()..write(_scanner.lastMatch[0]);
-
-    while (_scanner.scan('\\')) {
-      buffer.writeCharCode(_scanner.readChar());
-      _scanner.scan(regExp);
-      buffer.write(_scanner.lastMatch[0]);
-    }
-
-    for (var char in const [']', '(', ')']) {
-      if (_scanner.matches(char)) _scanner.error('unexpected "$char"');
-    }
-    if (!inOptions && _scanner.matches('}')) _scanner.error('unexpected "}"');
-
-    return new LiteralNode(buffer.toString(), _context);
-  }
-}
diff --git a/pkg/glob/lib/src/stream_pool.dart b/pkg/glob/lib/src/stream_pool.dart
deleted file mode 100644
index 6417513..0000000
--- a/pkg/glob/lib/src/stream_pool.dart
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library glob.stream_pool;
-
-import 'dart:async';
-
-/// A pool of streams whose events are unified and emitted through a central
-/// stream.
-class StreamPool<T> {
-  /// The stream through which all events from streams in the pool are emitted.
-  Stream<T> get stream => _controller.stream;
-  final StreamController<T> _controller;
-
-  /// Subscriptions to the streams that make up the pool.
-  final _subscriptions = new Map<Stream<T>, StreamSubscription<T>>();
-
-  /// Whether this pool should be closed when it becomes empty.
-  bool _closeWhenEmpty = false;
-
-  /// Creates a new stream pool that only supports a single subscriber.
-  ///
-  /// Any events from broadcast streams in the pool will be buffered until a
-  /// listener is subscribed.
-  StreamPool()
-      // Create the controller as sync so that any sync input streams will be
-      // forwarded synchronously. Async input streams will have their asynchrony
-      // preserved, since _controller.add will be called asynchronously.
-      : _controller = new StreamController<T>(sync: true);
-
-  /// Creates a new stream pool where [stream] can be listened to more than
-  /// once.
-  ///
-  /// Any events from buffered streams in the pool will be emitted immediately,
-  /// regardless of whether [stream] has any subscribers.
-  StreamPool.broadcast()
-      // Create the controller as sync so that any sync input streams will be
-      // forwarded synchronously. Async input streams will have their asynchrony
-      // preserved, since _controller.add will be called asynchronously.
-      : _controller = new StreamController<T>.broadcast(sync: true);
-
-  /// Adds [stream] as a member of this pool.
-  ///
-  /// Any events from [stream] will be emitted through [this.stream]. If
-  /// [stream] is sync, they'll be emitted synchronously; if [stream] is async,
-  /// they'll be emitted asynchronously.
-  void add(Stream<T> stream) {
-    if (_subscriptions.containsKey(stream)) return;
-    _subscriptions[stream] = stream.listen(_controller.add,
-        onError: _controller.addError,
-        onDone: () => remove(stream));
-  }
-
-  /// Removes [stream] as a member of this pool.
-  void remove(Stream<T> stream) {
-    var subscription = _subscriptions.remove(stream);
-    if (subscription != null) subscription.cancel();
-    if (_closeWhenEmpty && _subscriptions.isEmpty) close();
-  }
-
-  /// Removes all streams from this pool and closes [stream].
-  void close() {
-    for (var subscription in _subscriptions.values) {
-      subscription.cancel();
-    }
-    _subscriptions.clear();
-    _controller.close();
-  }
-
-  /// The next time this pool becomes empty, close it.
-  void closeWhenEmpty() {
-    if (_subscriptions.isEmpty) close();
-    _closeWhenEmpty = true;
-  }
-}
diff --git a/pkg/glob/lib/src/utils.dart b/pkg/glob/lib/src/utils.dart
deleted file mode 100644
index f17f2ed..0000000
--- a/pkg/glob/lib/src/utils.dart
+++ /dev/null
@@ -1,78 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library glob.utils;
-
-import 'package:path/path.dart' as p;
-
-/// A range from [min] to [max], inclusive.
-class Range {
-  /// The minimum value included by the range.
-  final int min;
-
-  /// The maximum value included by the range.
-  final int max;
-
-  /// Whether this range covers only a single number.
-  bool get isSingleton => min == max;
-
-  Range(this.min, this.max);
-
-  /// Returns a range that covers only [value].
-  Range.singleton(int value)
-      : this(value, value);
-
-  /// Whether [this] contains [value].
-  bool contains(int value) => value >= min && value <= max;
-
-  bool operator==(Object other) => other is Range &&
-      other.min == min && other.max == max;
-
-  int get hashCode => 3 * min + 7 * max;
-}
-
-/// An implementation of [Match] constructed by [Glob]s.
-class GlobMatch implements Match {
-  final String input;
-  final Pattern pattern;
-  final int start = 0;
-
-  int get end => input.length;
-  int get groupCount => 0;
-
-  GlobMatch(this.input, this.pattern);
-
-  String operator [](int group) => this.group(group);
-
-  String group(int group) {
-    if (group != 0) throw new RangeError.range(group, 0, 0);
-    return input;
-  }
-
-  List<String> groups(List<int> groupIndices) =>
-      groupIndices.map((index) => group(index)).toList();
-}
-
-final _quote = new RegExp(r"[+*?{}|[\]\\().^$-]");
-
-/// Returns [contents] with characters that are meaningful in regular
-/// expressions backslash-escaped.
-String regExpQuote(String contents) =>
-    contents.replaceAllMapped(_quote, (char) => "\\${char[0]}");
-
-/// Returns [path] with all its separators replaced with forward slashes.
-///
-/// This is useful when converting from Windows paths to globs.
-String separatorToForwardSlash(String path) {
-  if (p.style != p.Style.windows) return path;
-  return path.replaceAll('\\', '/');
-}
-
-/// Returns [path] which follows [context] converted to the POSIX format that
-/// globs match against.
-String toPosixPath(p.Context context, String path) {
-  if (context.style == p.Style.windows) return path.replaceAll('\\', '/');
-  if (context.style == p.Style.url) return Uri.decodeFull(path);
-  return path;
-}
diff --git a/pkg/glob/pubspec.yaml b/pkg/glob/pubspec.yaml
deleted file mode 100644
index 997de2d..0000000
--- a/pkg/glob/pubspec.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-name: glob
-version: 1.0.3
-author: "Dart Team <misc@dartlang.org>"
-homepage: http://www.dartlang.org
-description: Bash-style filename globbing.
-dependencies:
-  path: ">=1.0.0 <2.0.0"
-  string_scanner: ">=0.1.0 <0.2.0"
-dev_dependencies:
-  unittest: ">=0.11.0 <0.12.0"
-  scheduled_test: ">=0.11.2 <0.12.0"
diff --git a/pkg/glob/test/glob_test.dart b/pkg/glob/test/glob_test.dart
deleted file mode 100644
index 34dbb65..0000000
--- a/pkg/glob/test/glob_test.dart
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:glob/glob.dart';
-import 'package:unittest/unittest.dart';
-
-void main() {
-  group("Glob.quote()", () {
-    test("quotes all active characters", () {
-      expect(Glob.quote("*{[?\\}],-"), equals(r"\*\{\[\?\\\}\]\,\-"));
-    });
-
-    test("doesn't quote inactive characters", () {
-      expect(Glob.quote("abc~`_+="), equals("abc~`_+="));
-    });
-  });
-
-  group("Glob.matches()", () {
-    test("returns whether the path matches the glob", () {
-      var glob = new Glob("foo*");
-      expect(glob.matches("foobar"), isTrue);
-      expect(glob.matches("baz"), isFalse);
-    });
-
-    test("only matches the entire path", () {
-      var glob = new Glob("foo");
-      expect(glob.matches("foo/bar"), isFalse);
-      expect(glob.matches("bar/foo"), isFalse);
-    });
-  });
-
-  group("Glob.matchAsPrefix()", () {
-    test("returns a match if the path matches the glob", () {
-      var glob = new Glob("foo*");
-      expect(glob.matchAsPrefix("foobar"), new isInstanceOf<Match>());
-      expect(glob.matchAsPrefix("baz"), isNull);
-    });
-
-    test("returns null for start > 0", () {
-      var glob = new Glob("*");
-      expect(glob.matchAsPrefix("foobar", 1), isNull);
-    });
-  });
-
-  group("Glob.allMatches()", () {
-    test("returns a single match if the path matches the glob", () {
-      var matches = new Glob("foo*").allMatches("foobar");
-      expect(matches, hasLength(1));
-      expect(matches.first, new isInstanceOf<Match>());
-    });
-
-    test("returns an empty list if the path doesn't match the glob", () {
-      expect(new Glob("foo*").allMatches("baz"), isEmpty);
-    });
-
-    test("returns no matches for start > 0", () {
-      var glob = new Glob("*");
-      expect(glob.allMatches("foobar", 1), isEmpty);
-    });
-  });
-
-  group("GlobMatch", () {
-    var glob = new Glob("foo*");
-    var match = glob.matchAsPrefix("foobar");
-
-    test("returns the string as input", () {
-      expect(match.input, equals("foobar"));
-    });
-
-    test("returns the glob as the pattern", () {
-      expect(match.pattern, equals(glob));
-    });
-
-    test("returns the span of the string for start and end", () {
-      expect(match.start, equals(0));
-      expect(match.end, equals("foobar".length));
-    });
-
-    test("has a single group that contains the whole string", () {
-      expect(match.groupCount, equals(0));
-      expect(match[0], equals("foobar"));
-      expect(match.group(0), equals("foobar"));
-      expect(match.groups([0]), equals(["foobar"]));
-    });
-
-    test("throws a range error for an invalid group", () {
-      expect(() => match[1], throwsRangeError);
-      expect(() => match[-1], throwsRangeError);
-      expect(() => match.group(1), throwsRangeError);
-      expect(() => match.groups([1]), throwsRangeError);
-    });
-  });
-}
diff --git a/pkg/glob/test/list_test.dart b/pkg/glob/test/list_test.dart
deleted file mode 100644
index 3327524..0000000
--- a/pkg/glob/test/list_test.dart
+++ /dev/null
@@ -1,313 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:glob/glob.dart';
-import 'package:glob/src/utils.dart';
-import 'package:path/path.dart' as p;
-import 'package:scheduled_test/descriptor.dart' as d;
-import 'package:scheduled_test/scheduled_test.dart';
-
-String sandbox;
-
-void main() {
-  setUp(() {
-    scheduleSandbox();
-
-    d.dir("foo", [
-      d.file("bar"),
-      d.dir("baz", [
-        d.file("bang"),
-        d.file("qux")
-      ])
-    ]).create();
-  });
-
-  group("list()", () {
-    test("fails if the context doesn't match the system context", () {
-      expect(new Glob("*", context: p.url).list, throwsStateError);
-    });
-
-    test("reports exceptions for non-existent directories", () {
-      schedule(() {
-        expect(new Glob("non/existent/**").list().toList(),
-            throwsA(new isInstanceOf<FileSystemException>()));
-      });
-    });
-  });
-
-  group("listSync()", () {
-    test("fails if the context doesn't match the system context", () {
-      expect(new Glob("*", context: p.url).listSync, throwsStateError);
-    });
-
-    test("reports exceptions for non-existent directories", () {
-      schedule(() {
-        expect(new Glob("non/existent/**").listSync,
-            throwsA(new isInstanceOf<FileSystemException>()));
-      });
-    });
-  });
-
-  syncAndAsync((list) {
-    group("literals", () {
-      test("lists a single literal", () {
-        expect(list("foo/baz/qux"),
-            completion(equals([p.join("foo", "baz", "qux")])));
-      });
-
-      test("lists a non-matching literal", () {
-        expect(list("foo/baz/nothing"), completion(isEmpty));
-      });
-    });
-
-    group("star", () {
-      test("lists within filenames but not across directories", () {
-        expect(list("foo/b*"), completion(unorderedEquals([
-          p.join("foo", "bar"),
-          p.join("foo", "baz")
-        ])));
-      });
-
-      test("lists the empy string", () {
-        expect(list("foo/bar*"), completion(equals([p.join("foo", "bar")])));
-      });
-    });
-
-    group("double star", () {
-      test("lists within filenames", () {
-        expect(list("foo/baz/**"), completion(unorderedEquals([
-          p.join("foo", "baz", "qux"),
-          p.join("foo", "baz", "bang")
-        ])));
-      });
-
-      test("lists the empty string", () {
-        expect(list("foo/bar**"), completion(equals([p.join("foo", "bar")])));
-      });
-
-      test("lists recursively", () {
-        expect(list("foo/**"), completion(unorderedEquals([
-          p.join("foo", "bar"),
-          p.join("foo", "baz"),
-          p.join("foo", "baz", "qux"),
-          p.join("foo", "baz", "bang")
-        ])));
-      });
-
-      test("combines with literals", () {
-        expect(list("foo/ba**"), completion(unorderedEquals([
-          p.join("foo", "bar"),
-          p.join("foo", "baz"),
-          p.join("foo", "baz", "qux"),
-          p.join("foo", "baz", "bang")
-        ])));
-      });
-
-      test("lists recursively in the middle of a glob", () {
-        d.dir("deep", [
-          d.dir("a", [
-            d.dir("b", [
-              d.dir("c", [
-                d.file("d"),
-                d.file("long-file")
-              ]),
-              d.dir("long-dir", [d.file("x")])
-            ])
-          ])
-        ]).create();
-
-        expect(list("deep/**/?/?"), completion(unorderedEquals([
-          p.join("deep", "a", "b", "c"),
-          p.join("deep", "a", "b", "c", "d")
-        ])));
-      });
-    });
-
-    group("any char", () {
-      test("matches a character", () {
-        expect(list("foo/ba?"), completion(unorderedEquals([
-          p.join("foo", "bar"),
-          p.join("foo", "baz")
-        ])));
-      });
-
-      test("doesn't match a separator", () {
-        expect(list("foo?bar"), completion(isEmpty));
-      });
-    });
-
-    group("range", () {
-      test("matches a range of characters", () {
-        expect(list("foo/ba[a-z]"), completion(unorderedEquals([
-          p.join("foo", "bar"),
-          p.join("foo", "baz")
-        ])));
-      });
-
-      test("matches a specific list of characters", () {
-        expect(list("foo/ba[rz]"), completion(unorderedEquals([
-          p.join("foo", "bar"),
-          p.join("foo", "baz")
-        ])));
-      });
-
-      test("doesn't match outside its range", () {
-        expect(list("foo/ba[a-x]"),
-            completion(unorderedEquals([p.join("foo", "bar")])));
-      });
-
-      test("doesn't match outside its specific list", () {
-        expect(list("foo/ba[rx]"),
-            completion(unorderedEquals([p.join("foo", "bar")])));
-      });
-    });
-
-    test("the same file shouldn't be non-recursively listed multiple times",
-        () {
-      d.dir("multi", [
-        d.dir("start-end", [d.file("file")])
-      ]).create();
-
-      expect(list("multi/{start-*/f*,*-end/*e}"),
-          completion(equals([p.join("multi", "start-end", "file")])));
-    });
-
-    test("the same file shouldn't be recursively listed multiple times", () {
-      d.dir("multi", [
-        d.dir("a", [
-          d.dir("b", [
-            d.file("file"),
-            d.dir("c", [
-              d.file("file")
-            ])
-          ]),
-          d.dir("x", [
-            d.dir("y", [
-              d.file("file")
-            ])
-          ])
-        ])
-      ]).create();
-
-      expect(list("multi/{*/*/*/file,a/**/file}"), completion(unorderedEquals([
-        p.join("multi", "a", "b", "file"),
-        p.join("multi", "a", "b", "c", "file"),
-        p.join("multi", "a", "x", "y", "file")
-      ])));
-    });
-
-    group("with symlinks", () {
-      setUp(() {
-        schedule(() {
-          return new Link(p.join(sandbox, "dir", "link"))
-              .create(p.join(sandbox, "foo", "baz"), recursive: true);
-        }, "symlink foo/baz to dir/link");
-      });
-
-      test("follows symlinks by default", () {
-        expect(list("dir/**"), completion(unorderedEquals([
-          p.join("dir", "link"),
-          p.join("dir", "link", "bang"),
-          p.join("dir", "link", "qux")
-        ])));
-      });
-
-      test("doesn't follow symlinks with followLinks: false", () {
-        expect(list("dir/**", followLinks: false),
-            completion(equals([p.join("dir", "link")])));
-      });
-
-      test("shouldn't crash on broken symlinks", () {
-        schedule(() {
-          return new Directory(p.join(sandbox, "foo")).delete(recursive: true);
-        });
-
-        expect(list("dir/**"), completion(equals([p.join("dir", "link")])));
-      });
-    });
-
-    test("always lists recursively with recursive: true", () {
-      expect(list("foo", recursive: true), completion(unorderedEquals([
-        "foo",
-        p.join("foo", "bar"),
-        p.join("foo", "baz"),
-        p.join("foo", "baz", "qux"),
-        p.join("foo", "baz", "bang")
-      ])));
-    });
-
-    test("lists an absolute glob", () {
-      expect(schedule(() {
-        var pattern = separatorToForwardSlash(
-            p.absolute(p.join(sandbox, 'foo/baz/**')));
-
-        return list(pattern);
-      }), completion(unorderedEquals([
-        p.join("foo", "baz", "bang"),
-        p.join("foo", "baz", "qux")
-      ])));
-    });
-
-    test("lists a subdirectory that sometimes exists", () {
-      d.dir("top", [
-        d.dir("dir1", [
-          d.dir("subdir", [d.file("file")])
-        ]),
-        d.dir("dir2", [])
-      ]).create();
-
-      expect(list("top/*/subdir/**"),
-          completion(equals([p.join("top", "dir1", "subdir", "file")])));
-    });
-  });
-}
-
-typedef Future<List<String>> ListFn(String glob,
-    {bool recursive, bool followLinks});
-
-/// Runs [callback] in two groups with two values of [listFn]: one that uses
-/// [Glob.list], one that uses [Glob.listSync].
-void syncAndAsync(callback(ListFn listFn)) {
-  group("async", () {
-    callback((glob, {recursive: false, followLinks: true}) {
-      return schedule(() {
-        return new Glob(glob, recursive: recursive)
-            .list(root: sandbox, followLinks: followLinks)
-            .map((entity) => p.relative(entity.path, from: sandbox))
-            .toList();
-      }, 'listing $glob');
-    });
-  });
-
-  group("sync", () {
-    callback((glob, {recursive: false, followLinks: true}) {
-      return schedule(() {
-        return new Glob(glob, recursive: recursive)
-            .listSync(root: sandbox, followLinks: followLinks)
-            .map((entity) => p.relative(entity.path, from: sandbox))
-            .toList();
-      }, 'listing $glob');
-    });
-  });
-}
-
-void scheduleSandbox() {
-  schedule(() {
-    return Directory.systemTemp.createTemp('glob_').then((dir) {
-      sandbox = dir.path;
-      d.defaultRoot = sandbox;
-    });
-  }, 'creating sandbox');
-
-  currentSchedule.onComplete.schedule(() {
-    d.defaultRoot = null;
-    if (sandbox == null) return null;
-    var oldSandbox = sandbox;
-    sandbox = null;
-    return new Directory(oldSandbox).delete(recursive: true);
-  });
-}
diff --git a/pkg/glob/test/match_test.dart b/pkg/glob/test/match_test.dart
deleted file mode 100644
index 448d60c..0000000
--- a/pkg/glob/test/match_test.dart
+++ /dev/null
@@ -1,294 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:glob/glob.dart';
-import 'package:glob/src/utils.dart';
-import 'package:path/path.dart' as p;
-import 'package:unittest/unittest.dart';
-
-const RAW_ASCII_WITHOUT_SLASH = "\t\n\r !\"#\$%&'()*+`-.0123456789:;<=>?@ABCDEF"
-    "GHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~";
-
-// URL-encode the path for a URL context.
-final asciiWithoutSlash = p.style == p.Style.url ?
-    Uri.encodeFull(RAW_ASCII_WITHOUT_SLASH) : RAW_ASCII_WITHOUT_SLASH;
-
-void main() {
-  test("literals match exactly", () {
-    expect("foo", contains(new Glob("foo")));
-    expect("foo/bar", contains(new Glob("foo/bar")));
-    expect("foo*", contains(new Glob(r"foo\*")));
-  });
-
-  test("backslashes match nothing on Windows", () {
-    expect(r"foo\bar",
-        isNot(contains(new Glob(r"foo\\bar", context: p.windows))));
-  });
-
-  group("star", () {
-    test("matches non-separator characters", () {
-      var glob = new Glob("*");
-      expect(asciiWithoutSlash, contains(glob));
-    });
-
-    test("matches the empty string", () {
-      expect("foo", contains(new Glob("foo*")));
-      expect("", contains(new Glob("*")));
-    });
-
-    test("doesn't match separators", () {
-      var glob = new Glob("*");
-      expect("foo/bar", isNot(contains(glob)));
-    });
-  });
-
-  group("double star", () {
-    test("matches non-separator characters", () {
-      var glob = new Glob("**");
-      expect(asciiWithoutSlash, contains(glob));
-    });
-
-    test("matches the empty string", () {
-      var glob = new Glob("foo**");
-      expect("foo", contains(glob));
-    });
-
-    test("matches any level of nesting", () {
-      var glob = new Glob("**");
-      expect("a", contains(glob));
-      expect("a/b/c/d/e/f", contains(glob));
-    });
-
-    test("doesn't match unresolved dot dots", () {
-      expect("../foo/bar", isNot(contains(new Glob("**"))));
-    });
-
-    test("matches entities containing dot dots", () {
-      expect("..foo/bar", contains(new Glob("**")));
-      expect("foo../bar", contains(new Glob("**")));
-      expect("foo/..bar", contains(new Glob("**")));
-      expect("foo/bar..", contains(new Glob("**")));
-    });
-  });
-
-  group("any char", () {
-    test("matches any non-separator character", () {
-      var glob = new Glob("foo?");
-      for (var char in RAW_ASCII_WITHOUT_SLASH.split('')) {
-        if (p.style == p.Style.url) char = Uri.encodeFull(char);
-        expect("foo$char", contains(glob));
-      }
-    });
-
-    test("doesn't match a separator", () {
-      expect("foo/bar", isNot(contains(new Glob("foo?bar"))));
-    });
-  });
-
-  group("range", () {
-    test("can match individual characters", () {
-      var glob = new Glob("foo[a<.*]");
-      expect("fooa", contains(glob));
-      expect("foo<", contains(glob));
-      expect("foo.", contains(glob));
-      expect("foo*", contains(glob));
-      expect("foob", isNot(contains(glob)));
-      expect("foo>", isNot(contains(glob)));
-    });
-
-    test("can match a range of characters", () {
-      var glob = new Glob("foo[a-z]");
-      expect("fooa", contains(glob));
-      expect("foon", contains(glob));
-      expect("fooz", contains(glob));
-      expect("foo`", isNot(contains(glob)));
-      expect("foo{", isNot(contains(glob)));
-    });
-
-    test("can match multiple ranges of characters", () {
-      var glob = new Glob("foo[a-zA-Z]");
-      expect("fooa", contains(glob));
-      expect("foon", contains(glob));
-      expect("fooz", contains(glob));
-      expect("fooA", contains(glob));
-      expect("fooN", contains(glob));
-      expect("fooZ", contains(glob));
-      expect("foo?", isNot(contains(glob)));
-      expect("foo{", isNot(contains(glob)));
-    });
-
-    test("can match individual characters and ranges of characters", () {
-      var glob = new Glob("foo[a-z_A-Z]");
-      expect("fooa", contains(glob));
-      expect("foon", contains(glob));
-      expect("fooz", contains(glob));
-      expect("fooA", contains(glob));
-      expect("fooN", contains(glob));
-      expect("fooZ", contains(glob));
-      expect("foo_", contains(glob));
-      expect("foo?", isNot(contains(glob)));
-      expect("foo{", isNot(contains(glob)));
-    });
-
-    test("can be negated", () {
-      var glob = new Glob("foo[^a<.*]");
-      expect("fooa", isNot(contains(glob)));
-      expect("foo<", isNot(contains(glob)));
-      expect("foo.", isNot(contains(glob)));
-      expect("foo*", isNot(contains(glob)));
-      expect("foob", contains(glob));
-      expect("foo>", contains(glob));
-    });
-
-    test("never matches separators", () {
-      // "\t-~" contains "/".
-      expect("foo/bar", isNot(contains(new Glob("foo[\t-~]bar"))));
-      expect("foo/bar", isNot(contains(new Glob("foo[^a]bar"))));
-    });
-
-    test("allows dangling -", () {
-      expect("-", contains(new Glob(r"[-]")));
-
-      var glob = new Glob(r"[a-]");
-      expect("-", contains(glob));
-      expect("a", contains(glob));
-
-      glob = new Glob(r"[-b]");
-      expect("-", contains(glob));
-      expect("b", contains(glob));
-    });
-
-    test("allows multiple -s", () {
-      expect("-", contains(new Glob(r"[--]")));
-      expect("-", contains(new Glob(r"[---]")));
-
-      var glob = new Glob(r"[--a]");
-      expect("-", contains(glob));
-      expect("a", contains(glob));
-    });
-
-    test("allows negated /", () {
-      expect("foo-bar", contains(new Glob("foo[^/]bar")));
-    });
-
-    test("doesn't choke on RegExp-active characters", () {
-      var glob = new Glob(r"foo[\]].*");
-      expect("foobar", isNot(contains(glob)));
-      expect("foo].*", contains(glob));
-    });
-  });
-
-  group("options", () {
-    test("match if any of the options match", () {
-      var glob = new Glob("foo/{bar,baz,bang}");
-      expect("foo/bar", contains(glob));
-      expect("foo/baz", contains(glob));
-      expect("foo/bang", contains(glob));
-      expect("foo/qux", isNot(contains(glob)));
-    });
-
-    test("can contain nested operators", () {
-      var glob = new Glob("foo/{ba?,*az,ban{g,f}}");
-      expect("foo/bar", contains(glob));
-      expect("foo/baz", contains(glob));
-      expect("foo/bang", contains(glob));
-      expect("foo/qux", isNot(contains(glob)));
-    });
-
-    test("can conditionally match separators", () {
-      var glob = new Glob("foo/{bar,baz/bang}");
-      expect("foo/bar", contains(glob));
-      expect("foo/baz/bang", contains(glob));
-      expect("foo/baz", isNot(contains(glob)));
-      expect("foo/bar/bang", isNot(contains(glob)));
-    });
-  });
-
-  group("normalization", () {
-    test("extra slashes are ignored", () {
-      expect("foo//bar", contains(new Glob("foo/bar")));
-      expect("foo/", contains(new Glob("*")));
-    });
-
-    test("dot directories are ignored", () {
-      expect("foo/./bar", contains(new Glob("foo/bar")));
-      expect("foo/.", contains(new Glob("foo")));
-    });
-
-    test("dot dot directories are resolved", () {
-      expect("foo/../bar", contains(new Glob("bar")));
-      expect("../foo/bar", contains(new Glob("../foo/bar")));
-      expect("foo/../../bar", contains(new Glob("../bar")));
-    });
-
-    test("Windows separators are converted in a Windows context", () {
-      expect(r"foo\bar", contains(new Glob("foo/bar", context: p.windows)));
-      expect(r"foo\bar/baz",
-          contains(new Glob("foo/bar/baz", context: p.windows)));
-    });
-  });
-
-  test("an absolute path can be matched by a relative glob", () {
-    var path = p.absolute('foo/bar');
-    expect(path, contains(new Glob("foo/bar")));
-  });
-
-  test("a relative path can be matched by an absolute glob", () {
-    var pattern = separatorToForwardSlash(p.absolute('foo/bar'));
-    expect('foo/bar', contains(new Glob(pattern)));
-  });
-
-  group("with recursive: true", () {
-    var glob = new Glob("foo/bar", recursive: true);
-
-    test("still matches basic files", () {
-      expect("foo/bar", contains(glob));
-    });
-
-    test("matches subfiles", () {
-      expect("foo/bar/baz", contains(glob));
-      expect("foo/bar/baz/bang", contains(glob));
-    });
-
-    test("doesn't match suffixes", () {
-      expect("foo/barbaz", isNot(contains(glob)));
-      expect("foo/barbaz/bang", isNot(contains(glob)));
-    });
-  });
-
-  test("absolute POSIX paths", () {
-    expect("/foo/bar", contains(new Glob("/foo/bar", context: p.posix)));
-    expect("/foo/bar", isNot(contains(new Glob("**", context: p.posix))));
-    expect("/foo/bar", contains(new Glob("/**", context: p.posix)));
-  });
-
-  test("absolute Windows paths", () {
-    expect(r"C:\foo\bar", contains(new Glob("C:/foo/bar", context: p.windows)));
-    expect(r"C:\foo\bar", isNot(contains(new Glob("**", context: p.windows))));
-    expect(r"C:\foo\bar", contains(new Glob("C:/**", context: p.windows)));
-
-    expect(r"\\foo\bar\baz",
-        contains(new Glob("//foo/bar/baz", context: p.windows)));
-    expect(r"\\foo\bar\baz",
-        isNot(contains(new Glob("**", context: p.windows))));
-    expect(r"\\foo\bar\baz", contains(new Glob("//**", context: p.windows)));
-    expect(r"\\foo\bar\baz",
-        contains(new Glob("//foo/**", context: p.windows)));
-  });
-
-  test("absolute URL paths", () {
-    expect(r"http://foo.com/bar",
-        contains(new Glob("http://foo.com/bar", context: p.url)));
-    expect(r"http://foo.com/bar",
-        isNot(contains(new Glob("**", context: p.url))));
-    expect(r"http://foo.com/bar",
-        contains(new Glob("http://**", context: p.url)));
-    expect(r"http://foo.com/bar",
-        contains(new Glob("http://foo.com/**", context: p.url)));
-
-    expect("/foo/bar", contains(new Glob("/foo/bar", context: p.url)));
-    expect("/foo/bar", isNot(contains(new Glob("**", context: p.url))));
-    expect("/foo/bar", contains(new Glob("/**", context: p.url)));
-  });
-}
diff --git a/pkg/glob/test/parse_test.dart b/pkg/glob/test/parse_test.dart
deleted file mode 100644
index 498d035..0000000
--- a/pkg/glob/test/parse_test.dart
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:glob/glob.dart';
-import 'package:path/path.dart' as p;
-import 'package:unittest/unittest.dart';
-
-void main() {
-  test("supports backslash-escaped characters", () {
-    expect(r"*[]{,}?()", contains(new Glob(r"\*\[\]\{\,\}\?\(\)")));
-    if (p.style != p.Style.windows) {
-      expect(r"foo\bar", contains(new Glob(r"foo\\bar")));
-    }
-  });
-
-  test("disallows an empty glob", () {
-    expect(() => new Glob(""), throwsFormatException);
-  });
-
-  group("range", () {
-    test("supports either ^ or ! for negated ranges", () {
-      var bang = new Glob("fo[!a-z]");
-      expect("foo", isNot(contains(bang)));
-      expect("fo2", contains(bang));
-
-      var caret = new Glob("fo[^a-z]");
-      expect("foo", isNot(contains(bang)));
-      expect("fo2", contains(bang));
-    });
-
-    test("supports backslash-escaped characters", () {
-      var glob = new Glob(r"fo[\*\--\]]");
-      expect("fo]", contains(glob));
-      expect("fo-", contains(glob));
-      expect("fo*", contains(glob));
-    });
-
-    test("disallows inverted ranges", () {
-      expect(() => new Glob(r"[z-a]"), throwsFormatException);
-    });
-
-    test("disallows empty ranges", () {
-      expect(() => new Glob(r"[]"), throwsFormatException);
-    });
-
-    test("disallows unclosed ranges", () {
-      expect(() => new Glob(r"[abc"), throwsFormatException);
-      expect(() => new Glob(r"[-"), throwsFormatException);
-    });
-
-    test("disallows dangling ]", () {
-      expect(() => new Glob(r"abc]"), throwsFormatException);
-    });
-
-    test("disallows explicit /", () {
-      expect(() => new Glob(r"[/]"), throwsFormatException);
-      expect(() => new Glob(r"[ -/]"), throwsFormatException);
-      expect(() => new Glob(r"[/-~]"), throwsFormatException);
-    });
-  });
-
-  group("options", () {
-    test("allows empty branches", () {
-      var glob = new Glob("foo{,bar}");
-      expect("foo", contains(glob));
-      expect("foobar", contains(glob));
-    });
-
-    test("disallows empty options", () {
-      expect(() => new Glob("{}"), throwsFormatException);
-    });
-
-    test("disallows single options", () {
-      expect(() => new Glob("{foo}"), throwsFormatException);
-    });
-
-    test("disallows unclosed options", () {
-      expect(() => new Glob("{foo,bar"), throwsFormatException);
-      expect(() => new Glob("{foo,"), throwsFormatException);
-    });
-
-    test("disallows dangling }", () {
-      expect(() => new Glob("foo}"), throwsFormatException);
-    });
-
-    test("disallows dangling ] in options", () {
-      expect(() => new Glob(r"{abc]}"), throwsFormatException);
-    });
-  });
-
-  test("disallows unescaped parens", () {
-    expect(() => new Glob("foo(bar"), throwsFormatException);
-    expect(() => new Glob("foo)bar"), throwsFormatException);
-  });
-}
diff --git a/pkg/intl/CHANGELOG.md b/pkg/intl/CHANGELOG.md
index 9dca66f..36bb584 100644
--- a/pkg/intl/CHANGELOG.md
+++ b/pkg/intl/CHANGELOG.md
@@ -1,3 +1,10 @@
+## 0.11.12
+  * Number formatting now accepts "int-like" inputs that don't have to
+    conform to the num interface. In particular, you can now pass an Int64
+    from the fixnum package and format it. In addition, this no longer
+    multiplies the result, so it won't lose precision on a few additional
+    cases in JS.
+
 ## 0.11.11
   * Add a -no-embedded-plurals flag to reject plurals and genders that
     have either leading or trailing text around them. This follows the
diff --git a/pkg/intl/lib/src/intl/number_format.dart b/pkg/intl/lib/src/intl/number_format.dart
index 377db7d..2e23d35 100644
--- a/pkg/intl/lib/src/intl/number_format.dart
+++ b/pkg/intl/lib/src/intl/number_format.dart
@@ -71,7 +71,19 @@
   int minimumFractionDigits = 0;
   int minimumExponentDigits = 0;
 
-  int _multiplier = 1;
+  /**
+   * For percent and permille, what are we multiplying by in order to
+   * get the printed value, e.g. 100 for percent.
+   */
+  int get _multiplier => _internalMultiplier;
+  set _multiplier(int x) {
+    _internalMultiplier = x;
+    _multiplierDigits = (log(_multiplier) / LN10).round();
+  }
+  int _internalMultiplier = 1;
+
+  /** How many digits are there in the [_multiplier]. */
+  int _multiplierDigits = 0;
 
   /**
    * Stores the pattern used to create this format. This isn't used, but
@@ -162,14 +174,12 @@
   /**
    * Format [number] according to our pattern and return the formatted string.
    */
-  String format(num number) {
-    // TODO(alanknight): Do we have to do anything for printing numbers bidi?
-    // Or are they always printed left to right?
-    if (number.isNaN) return symbols.NAN;
-    if (number.isInfinite) return "${_signPrefix(number)}${symbols.INFINITY}";
+  String format(number) {
+    if (_isNaN(number)) return symbols.NAN;
+    if (_isInfinite(number)) return "${_signPrefix(number)}${symbols.INFINITY}";
 
     _add(_signPrefix(number));
-    _formatNumber(number.abs() * _multiplier);
+    _formatNumber(number.abs());
     _add(_signSuffix(number));
 
     var result = _buffer.toString();
@@ -186,7 +196,7 @@
   /**
    * Format the main part of the number in the form dictated by the pattern.
    */
-  void _formatNumber(num number) {
+  void _formatNumber(number) {
     if (_useExponentialNotation) {
       _formatExponential(number);
     } else {
@@ -250,48 +260,60 @@
   final _maxInt = pow(2, 52);
 
   /**
+   * Helpers to check numbers that don't conform to the [num] interface,
+   * e.g. Int64
+   */
+  _isInfinite(number) => number is num ? number.isInfinite : false;
+  _isNaN(number) => number is num ? number.isNaN : false;
+  _round(number) => number is num ? number.round() : number;
+  _floor(number) => number is num ? number.floor() : number;
+
+  /**
    * Format the basic number portion, inluding the fractional digits.
    */
-  void _formatFixed(num number) {
-    // Very fussy math to get integer and fractional parts.
-    var power = pow(10, maximumFractionDigits);
-    var shiftedNumber = (number * power);
-    // We must not roundToDouble() an int or it will lose precision. We must not
-    // round() a large double or it will take its loss of precision and
-    // preserve it in an int, which we will then print to the right
-    // of the decimal place. Therefore, only roundToDouble if we are already
-    // a double.
-    if (shiftedNumber is double) {
-      shiftedNumber = shiftedNumber.roundToDouble();
-    }
-    var intValue, fracValue;
-    if (shiftedNumber.isInfinite) {
-      intValue = number.toInt();
-      fracValue = 0;
+  void _formatFixed(number) {
+    var integerPart;
+    int fractionPart;
+    int extraIntegerDigits;
+
+    final power = pow(10, maximumFractionDigits);
+    final digitMultiplier = power * _multiplier;
+
+    if (_isInfinite(number)) {
+      integerPart = number.toInt();
+      extraIntegerDigits = 0;
+      fractionPart = 0;
     } else {
-      intValue = shiftedNumber.round() ~/ power;
-      fracValue = (shiftedNumber - intValue * power).floor();
+      // We have three possible pieces. First, the basic integer part. If this
+      // is a percent or permille, the additional 2 or 3 digits. Finally the
+      // fractional part.
+      // We avoid multiplying the number because it might overflow if we have
+      // a fixed-size integer type, so we extract each of the three as an
+      // integer pieces.
+      integerPart = _floor(number);
+      var fraction = number - integerPart;
+      // Multiply out to the number of decimal places and the percent, then
+      // round. For fixed-size integer types this should always be zero, so
+      // multiplying is OK.
+      var remainingDigits = _round(fraction * digitMultiplier).toInt();
+      // However, in rounding we may overflow into the main digits.
+      if (remainingDigits >= digitMultiplier) {
+        integerPart++;
+        remainingDigits -= digitMultiplier;
+      }
+      // Separate out the extra integer parts from the fraction part.
+      extraIntegerDigits = remainingDigits ~/ power;
+      fractionPart = remainingDigits % power;
     }
-    var fractionPresent = minimumFractionDigits > 0 || fracValue > 0;
+    var fractionPresent = minimumFractionDigits > 0 || fractionPart > 0;
 
-    // If the int part is larger than 2^52 and we're on Javascript (so it's
-    // really a float) it will lose precision, so pad out the rest of it
-    // with zeros. Check for Javascript by seeing if an integer is double.
-    var paddingDigits = '';
-    if (1 is double && intValue > _maxInt) {
-      var howManyDigitsTooBig = (log(intValue) / LN10).ceil() - 16;
-      var divisor = pow(10, howManyDigitsTooBig).round();
-      paddingDigits = symbols.ZERO_DIGIT * howManyDigitsTooBig.toInt();
-
-      intValue = (intValue / divisor).truncate();
-    }
-    var integerDigits = "${intValue}${paddingDigits}".codeUnits;
+    var integerDigits = _integerDigits(integerPart, extraIntegerDigits);
     var digitLength = integerDigits.length;
 
-    if (_hasPrintableIntegerPart(intValue)) {
+    if (_hasPrintableIntegerPart(integerPart)) {
       _pad(minimumIntegerDigits - digitLength);
       for (var i = 0; i < digitLength; i++) {
-        _addDigit(integerDigits[i]);
+        _addDigit(integerDigits.codeUnitAt(i));
         _group(digitLength, i);
       }
     } else if (!fractionPresent) {
@@ -300,7 +322,44 @@
     }
 
     _decimalSeparator(fractionPresent);
-    _formatFractionPart((fracValue + power).toString());
+    _formatFractionPart((fractionPart + power).toString());
+  }
+
+  /**
+   * Compute the raw integer digits which will then be printed with
+   * grouping and translated to localized digits.
+   */
+  String _integerDigits(integerPart, extraIntegerDigits) {
+    // If the int part is larger than 2^52 and we're on Javascript (so it's
+    // really a float) it will lose precision, so pad out the rest of it
+    // with zeros. Check for Javascript by seeing if an integer is double.
+    var paddingDigits = '';
+    if (1 is double && integerPart is num && integerPart > _maxInt) {
+      var howManyDigitsTooBig = (log(integerPart) / LN10).ceil() - 16;
+      var divisor = pow(10, howManyDigitsTooBig).round();
+      paddingDigits = symbols.ZERO_DIGIT * howManyDigitsTooBig.toInt();
+      integerPart = (integerPart / divisor).truncate();
+    }
+
+    var extra = extraIntegerDigits == 0 ? '' : extraIntegerDigits.toString();
+    var intDigits = _mainIntegerDigits(integerPart);
+    var paddedExtra =
+        intDigits.isEmpty ? extra : extra.padLeft(_multiplierDigits, '0');
+    return "${intDigits}${paddedExtra}${paddingDigits}";
+  }
+
+  /**
+   * The digit string of the integer part. This is the empty string if the
+   * integer part is zero and otherwise is the toString() of the integer
+   * part, stripping off any minus sign.
+   */
+  String _mainIntegerDigits(integer) {
+    if (integer == 0) return '';
+    var digits = integer.toString();
+    // If we have a fixed-length int representation, it can have a negative
+    // number whose negation is also negative, e.g. 2^-63 in 64-bit.
+    // Remove the minus sign.
+    return digits.startsWith('-') ? digits.substring(1) : digits;
   }
 
   /**
@@ -330,8 +389,8 @@
    * because we have digits left of the decimal point, or because there are
    * a minimum number of printable digits greater than 1.
    */
-  bool _hasPrintableIntegerPart(int intValue) =>
-      intValue > 0 || minimumIntegerDigits > 0;
+  bool _hasPrintableIntegerPart(x) =>
+      x > 0 || minimumIntegerDigits > 0;
 
   /** A group of methods that provide support for writing digits and other
    * required characters into [_buffer] easily.
@@ -384,13 +443,13 @@
    * Returns the prefix for [x] based on whether it's positive or negative.
    * In en_US this would be '' and '-' respectively.
    */
-  String _signPrefix(num x) => x.isNegative ? _negativePrefix : _positivePrefix;
+  String _signPrefix(x) => x.isNegative ? _negativePrefix : _positivePrefix;
 
   /**
    * Returns the suffix for [x] based on wether it's positive or negative.
    * In en_US there are no suffixes for positive or negative.
    */
-  String _signSuffix(num x) => x.isNegative ? _negativeSuffix : _positiveSuffix;
+  String _signSuffix(x) => x.isNegative ? _negativeSuffix : _positiveSuffix;
 
   void _setPattern(String newPattern) {
     if (newPattern == null) return;
diff --git a/pkg/intl/pubspec.yaml b/pkg/intl/pubspec.yaml
index c2bcbef..9d039c4 100644
--- a/pkg/intl/pubspec.yaml
+++ b/pkg/intl/pubspec.yaml
@@ -1,5 +1,5 @@
 name: intl
-version: 0.11.11
+version: 0.11.12
 author: Dart Team <misc@dartlang.org>
 description: Contains code to deal with internationalized/localized messages, date and number formatting and parsing, bi-directional text, and other internationalization issues.
 homepage: https://www.dartlang.org
@@ -12,3 +12,4 @@
   petitparser: '>=1.1.3 <2.0.0'
 dev_dependencies:
   unittest: '>=0.10.0 <0.12.0'
+  fixnum: '>=0.9.0 <0.10.0'
diff --git a/pkg/intl/test/fixnum_test.dart b/pkg/intl/test/fixnum_test.dart
new file mode 100644
index 0000000..953fe00
--- /dev/null
+++ b/pkg/intl/test/fixnum_test.dart
@@ -0,0 +1,47 @@
+// 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 intl_test;
+
+import 'package:intl/intl.dart';
+import 'package:unittest/unittest.dart';
+import 'package:fixnum/fixnum.dart';
+
+var int64Values = {
+  new Int64(12345) :
+    ["USD12,345.00", "1,234,500%"],
+  new Int64(0x7FFFFFFFFFFFF) :
+    ["USD2,251,799,813,685,247.00", "225,179,981,368,524,700%"],
+  Int64.parseHex('7FFFFFFFFFFFFFF') :
+    ["USD576,460,752,303,423,487.00", "57,646,075,230,342,348,700%"],
+  Int64.parseHex('8000000000000000') :
+    ["-USD9,223,372,036,854,775,808.00", "-922,337,203,685,477,580,800%"]
+};
+
+var int32Values = {
+  new Int32(12345) : ["USD12,345.00", "1,234,500%"],
+  new Int32(0x7FFFF) : ["USD524,287.00", "52,428,700%"],
+  Int32.parseHex('7FFFFFF') : ["USD134,217,727.00", "13,421,772,700%"],
+  Int32.parseHex('80000000') : ["-USD2,147,483,648.00", "-214,748,364,800%"]
+};
+
+main() {
+  test('int64', () {
+    int64Values.forEach((number, expected) {
+      var currency = new NumberFormat.currencyPattern().format(number);
+      expect(currency, expected.first);
+      var percent = new NumberFormat.percentPattern().format(number);
+      expect(percent, expected[1]);
+    });
+  });
+
+  test('int32', () {
+    int32Values.forEach((number, expected) {
+      var currency = new NumberFormat.currencyPattern().format(number);
+      expect(currency, expected.first);
+      var percent = new NumberFormat.percentPattern().format(number);
+      expect(percent, expected[1]);
+    });
+  });
+}
diff --git a/pkg/intl/test/number_closure_test.dart b/pkg/intl/test/number_closure_test.dart
index 523ca8c..d715d7e 100644
--- a/pkg/intl/test/number_closure_test.dart
+++ b/pkg/intl/test/number_closure_test.dart
@@ -40,7 +40,7 @@
 
   fmt = new NumberFormat.decimalPattern();
   str = fmt.format(1.3456E20);
-  expect(veryBigNumberCompare('134,559,999,999,999,000,000', str), isTrue);
+  expect(veryBigNumberCompare('134,560,000,000,000,000,000', str), isTrue);
 
   fmt = new NumberFormat.percentPattern();
   str = fmt.format(1.3456E20);
diff --git a/pkg/matcher/CHANGELOG.md b/pkg/matcher/CHANGELOG.md
index 4689c31..aaf5a4d 100644
--- a/pkg/matcher/CHANGELOG.md
+++ b/pkg/matcher/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.11.3+1
+
+* Fix the `prints` matcher test on dart2js.
+
+## 0.11.3
+
+* Add a `prints` matcher that matches output a callback emits via `print`.
+
 ## 0.11.2
 
 * Add an `isNotEmpty` matcher.
diff --git a/pkg/matcher/lib/matcher.dart b/pkg/matcher/lib/matcher.dart
index 6fd18cc..c7790c9 100644
--- a/pkg/matcher/lib/matcher.dart
+++ b/pkg/matcher/lib/matcher.dart
@@ -15,6 +15,7 @@
 export 'src/map_matchers.dart';
 export 'src/numeric_matchers.dart';
 export 'src/operator_matchers.dart';
+export 'src/prints_matcher.dart';
 export 'src/string_matchers.dart';
 export 'src/throws_matcher.dart';
 export 'src/throws_matchers.dart';
diff --git a/pkg/matcher/lib/src/prints_matcher.dart b/pkg/matcher/lib/src/prints_matcher.dart
new file mode 100644
index 0000000..8faa895
--- /dev/null
+++ b/pkg/matcher/lib/src/prints_matcher.dart
@@ -0,0 +1,72 @@
+// 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 matcher.prints_matcher;
+
+import 'dart:async';
+
+import 'description.dart';
+import 'expect.dart';
+import 'interfaces.dart';
+import 'future_matchers.dart';
+import 'util.dart';
+
+/// Matches a [Function] that prints text that matches [matcher].
+///
+/// [matcher] may be a String or a [Matcher].
+///
+/// If the function this runs against returns a [Future], all text printed by
+/// the function (using [Zone] scoping) until that Future completes is matched.
+///
+/// This only tracks text printed using the [print] function.
+Matcher prints(matcher) => new _Prints(wrapMatcher(matcher));
+
+class _Prints extends Matcher {
+  final Matcher _matcher;
+
+  _Prints(this._matcher);
+
+  bool matches(item, Map matchState) {
+    if (item is! Function) return false;
+
+    var buffer = new StringBuffer();
+    var result = runZoned(item, zoneSpecification:
+        new ZoneSpecification(print: (_, __, ____, line) {
+      buffer.writeln(line);
+    }));
+
+    if (result is! Future) {
+      var actual = buffer.toString();
+      matchState['prints.actual'] = actual;
+      return _matcher.matches(actual, matchState);
+    }
+
+    return completes.matches(result.then(wrapAsync((_) {
+      expect(buffer.toString(), _matcher);
+    }, 'prints')), matchState);
+  }
+
+  Description describe(Description description) =>
+      description.add('prints ').addDescriptionOf(_matcher);
+
+  Description describeMismatch(item, Description description, Map matchState,
+      bool verbose) {
+    var actual = matchState.remove('prints.actual');
+    if (actual == null) return description;
+    if (actual.isEmpty) return description.add("printed nothing.");
+
+    description.add('printed ').addDescriptionOf(actual);
+
+    // Create a new description for the matcher because at least
+    // [_StringEqualsMatcher] replaces the previous contents of the description.
+    var innerMismatch = _matcher.describeMismatch(
+        actual, new StringDescription(), matchState, verbose).toString();
+
+    if (innerMismatch.isNotEmpty) {
+      description.add('\n   Which: ').add(innerMismatch.toString());
+    }
+
+    return description;
+  }
+}
diff --git a/pkg/matcher/pubspec.yaml b/pkg/matcher/pubspec.yaml
index 230ddc39..fb3f68b 100644
--- a/pkg/matcher/pubspec.yaml
+++ b/pkg/matcher/pubspec.yaml
@@ -1,5 +1,5 @@
 name: matcher
-version: 0.11.2
+version: 0.11.3+1
 author: Dart Team <misc@dartlang.org>
 description: Support for specifying test expectations
 homepage: https://pub.dartlang.org/packages/matcher
diff --git a/pkg/matcher/test/prints_matcher_test.dart b/pkg/matcher/test/prints_matcher_test.dart
new file mode 100644
index 0000000..9c7dd4c
--- /dev/null
+++ b/pkg/matcher/test/prints_matcher_test.dart
@@ -0,0 +1,107 @@
+// 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 matcher.prints_matchers_test;
+
+import 'dart:async';
+
+import 'package:matcher/matcher.dart';
+import 'package:unittest/unittest.dart';
+
+import 'test_utils.dart';
+
+/// The VM and dart2js have different toStrings for closures.
+final closureToString = (() {}).toString();
+
+void main() {
+  initUtils();
+
+  group('synchronous', () {
+    test("passes with an expected print", () {
+      shouldPass(() => print("Hello, world!"), prints("Hello, world!\n"));
+    });
+
+    test("combines multiple prints", () {
+      shouldPass(() {
+        print("Hello");
+        print("World!");
+      }, prints("Hello\nWorld!\n"));
+    });
+
+    test("works with a Matcher", () {
+      shouldPass(() => print("Hello, world!"), prints(contains("Hello")));
+    });
+
+    test("describes a failure nicely", () {
+      shouldFail(() => print("Hello, world!"), prints("Goodbye, world!\n"),
+          "Expected: prints 'Goodbye, world!\\n' ''"
+          "  Actual: <$closureToString> "
+          "   Which: printed 'Hello, world!\\n' ''"
+          "   Which: is different. "
+          "Expected: Goodbye, w ... "
+          "  Actual: Hello, wor ... "
+          "          ^ Differ at offset 0");
+    });
+
+    test("describes a failure with a non-descriptive Matcher nicely", () {
+      shouldFail(() => print("Hello, world!"), prints(contains("Goodbye")),
+          "Expected: prints contains 'Goodbye'"
+          "  Actual: <$closureToString> "
+          "   Which: printed 'Hello, world!\\n' ''");
+    });
+
+    test("describes a failure with no text nicely", () {
+      shouldFail(() {}, prints(contains("Goodbye")),
+          "Expected: prints contains 'Goodbye'"
+          "  Actual: <$closureToString> "
+          "   Which: printed nothing.");
+    });
+  });
+
+  group('asynchronous', () {
+    test("passes with an expected print", () {
+      shouldPass(() => new Future(() => print("Hello, world!")),
+          prints("Hello, world!\n"));
+    });
+
+    test("combines multiple prints", () {
+      shouldPass(() => new Future(() {
+        print("Hello");
+        print("World!");
+      }), prints("Hello\nWorld!\n"));
+    });
+
+    test("works with a Matcher", () {
+      shouldPass(() => new Future(() => print("Hello, world!")),
+          prints(contains("Hello")));
+    });
+
+    test("describes a failure nicely", () {
+      shouldFail(() => new Future(() => print("Hello, world!")),
+          prints("Goodbye, world!\n"),
+          "Expected: 'Goodbye, world!\\n' ''"
+          "  Actual: 'Hello, world!\\n' ''"
+          "   Which: is different. "
+          "Expected: Goodbye, w ... "
+          "  Actual: Hello, wor ... "
+          "          ^ Differ at offset 0",
+          isAsync: true);
+    });
+
+    test("describes a failure with a non-descriptive Matcher nicely", () {
+      shouldFail(() => new Future(() => print("Hello, world!")),
+          prints(contains("Goodbye")),
+          "Expected: contains 'Goodbye'"
+          "  Actual: 'Hello, world!\\n' ''",
+          isAsync: true);
+    });
+
+    test("describes a failure with no text nicely", () {
+      shouldFail(() => new Future.value(), prints(contains("Goodbye")),
+          "Expected: contains 'Goodbye'"
+          "  Actual: ''",
+          isAsync: true);
+    });
+  });
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 256f654..750ebe0 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -21,6 +21,9 @@
 polymer/test/build/script_compactor_test: Pass, Slow
 polymer/test/import_test: Skip # 17873
 
+[ $runtime == vm && $checked ]
+analyzer2dart/test/end2end_test: RuntimeError 21872
+
 [ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 third_party/angular_tests/browser_test/*: Skip # github perf_api.dart issue 5
 third_party/angular_tests/browser_test/core_dom/shadow_root_options: Fail # Issue 19329
@@ -354,7 +357,6 @@
 code_transformers/test/resolver_test: Skip # Uses dart:io
 code_transformers/test/unique_message_test: Skip # Uses dart:io
 code_transformers/test/remove_sourcemap_comment_test: Skip # Uses dart:io.
-glob/test/*: Fail, OK # Uses dart:io.
 http/test/io/*: Fail, OK # Uses dart:io.
 http_parser/test/web_socket_test: Fail, OK # Uses dart:io
 http_multi_server/test/http_multi_server_test: Skip # Uses dart:io
diff --git a/pkg/polymer/CHANGELOG.md b/pkg/polymer/CHANGELOG.md
index f99b3d6..936b00f 100644
--- a/pkg/polymer/CHANGELOG.md
+++ b/pkg/polymer/CHANGELOG.md
@@ -1,5 +1,9 @@
+#### 0.15.3+1
+  * Fix logic for detecting when the compiler is linting within an
+    `auto-binding-dart` template element. This removes some false positive
+    warnings.
+    
 #### 0.15.3
-
   * Narrow the constraint on observe to ensure that new features are reflected
     in polymer's version.
 
diff --git a/pkg/polymer/lib/src/build/linter.dart b/pkg/polymer/lib/src/build/linter.dart
index 39cea9b..303b020 100644
--- a/pkg/polymer/lib/src/build/linter.dart
+++ b/pkg/polymer/lib/src/build/linter.dart
@@ -195,12 +195,13 @@
       case 'script': _validateScriptElement(node); break;
       case 'template':
         var isTag = node.attributes['is'];
+        var oldInAutoBindingElement = _inAutoBindingElement;
         if (isTag != null && AUTO_BINDING_ELEMENTS.contains(isTag)) {
           _inAutoBindingElement = true;
         }
         _validateNormalElement(node);
         super.visitElement(node);
-        _inAutoBindingElement = false;
+        _inAutoBindingElement = oldInAutoBindingElement;
         break;
       default:
         _validateNormalElement(node);
diff --git a/pkg/polymer/pubspec.yaml b/pkg/polymer/pubspec.yaml
index 10c1ea5..1548ba0 100644
--- a/pkg/polymer/pubspec.yaml
+++ b/pkg/polymer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: polymer
-version: 0.15.3
+version: 0.15.3+1
 author: Polymer.dart Authors <web-ui-dev@dartlang.org>
 description: >
   Polymer.dart is a new type of library for the web, built on top of Web
diff --git a/pkg/polymer/test/build/linter_test.dart b/pkg/polymer/test/build/linter_test.dart
index c08e5df..89e2263 100644
--- a/pkg/polymer/test/build/linter_test.dart
+++ b/pkg/polymer/test/build/linter_test.dart
@@ -477,13 +477,17 @@
         'a|lib/test.html': '''<html><body>
             <template is="auto-binding-dart">
               <div on-foo="{{something}}"></div>
+              <template>
+                <div>foo</div>
+              </template>
+              <div on-foo="{{something}}"></div>
             </template>
             '''.replaceAll('            ', ''),
       }, []);
 
     _testLinter('on-foo is only supported in polymer elements', {
         'a|lib/test.html': '''<html><body>
-            <div on-foo="something"></div>
+            <div on-foo="{{something}}"></div>
             '''.replaceAll('            ', ''),
       }, [
         'warning: ${EVENT_HANDLERS_ONLY_WITHIN_POLYMER.snippet} '
diff --git a/pkg/scheduled_test/CHANGELOG.md b/pkg/scheduled_test/CHANGELOG.md
index 937c030..863abf5 100644
--- a/pkg/scheduled_test/CHANGELOG.md
+++ b/pkg/scheduled_test/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.11.6
+
+* *Actually* bump the version constraint for `unittest`.
+
+## 0.11.5
+
+* Bump the version constraint for `unittest`.
+
 ## 0.11.4
 
 * Bump the version constraint for `unittest`.
diff --git a/pkg/scheduled_test/pubspec.yaml b/pkg/scheduled_test/pubspec.yaml
index db280ea..59112de 100644
--- a/pkg/scheduled_test/pubspec.yaml
+++ b/pkg/scheduled_test/pubspec.yaml
@@ -1,5 +1,5 @@
 name: scheduled_test
-version: 0.11.4
+version: 0.11.6
 author: Dart Team <misc@dartlang.org>
 description: >
   A package for writing readable tests of asynchronous behavior.
@@ -21,6 +21,6 @@
   # Because scheduled_test exports unittest, it needs to keep its version
   # constraint tight to ensure that a constraint on scheduled_test properly
   # constraints all features it provides.
-  unittest: '>=0.11.3 <0.11.4'
+  unittest: '>=0.11.4 <0.11.5'
 dev_dependencies:
   metatest: '>=0.1.0 <0.2.0'
diff --git a/pkg/shelf_web_socket/CHANGELOG.md b/pkg/shelf_web_socket/CHANGELOG.md
new file mode 100644
index 0000000..d12b690
--- /dev/null
+++ b/pkg/shelf_web_socket/CHANGELOG.md
@@ -0,0 +1,4 @@
+## 0.0.1+1
+
+* Properly parse the `Connection` header. This fixes an issue where Firefox was
+  unable to connect.
diff --git a/pkg/shelf_web_socket/lib/src/web_socket_handler.dart b/pkg/shelf_web_socket/lib/src/web_socket_handler.dart
index ac5786a..7ab8e7e 100644
--- a/pkg/shelf_web_socket/lib/src/web_socket_handler.dart
+++ b/pkg/shelf_web_socket/lib/src/web_socket_handler.dart
@@ -28,7 +28,9 @@
 
     var connection = request.headers['Connection'];
     if (connection == null) return _notFound();
-    if (connection.toLowerCase() != 'upgrade') return _notFound();
+    var tokens = connection.toLowerCase().split(',')
+        .map((token) => token.trim());
+    if (!tokens.contains('upgrade')) return _notFound();
 
     var upgrade = request.headers['Upgrade'];
     if (upgrade == null) return _notFound();
diff --git a/pkg/shelf_web_socket/pubspec.yaml b/pkg/shelf_web_socket/pubspec.yaml
index 7cecc42..a19a331 100644
--- a/pkg/shelf_web_socket/pubspec.yaml
+++ b/pkg/shelf_web_socket/pubspec.yaml
@@ -1,5 +1,5 @@
 name: shelf_web_socket
-version: 0.0.1
+version: 0.0.1+1
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/shelf_web_socket/test/web_socket_test.dart b/pkg/shelf_web_socket/test/web_socket_test.dart
index f9ae2dc..aa9ea41 100644
--- a/pkg/shelf_web_socket/test/web_socket_test.dart
+++ b/pkg/shelf_web_socket/test/web_socket_test.dart
@@ -105,6 +105,20 @@
     });
   });
 
+  // Regression test for issue 21894.
+  test("allows a Connection header with multiple values", () {
+    return shelf_io.serve(webSocketHandler((webSocket) {
+      webSocket.close();
+    }), "localhost", 0).then((server) {
+      var url = 'http://localhost:${server.port}/';
+
+      var headers = _handshakeHeaders;
+      headers['Connection'] = 'Other-Token, Upgrade';
+      expect(http.get(url, headers: headers).whenComplete(server.close),
+          hasStatus(101));
+    });
+  });
+
   group("HTTP errors", () {
     var server;
     var url;
diff --git a/pkg/string_scanner/CHANGELOG.md b/pkg/string_scanner/CHANGELOG.md
index d273748..9c03874 100644
--- a/pkg/string_scanner/CHANGELOG.md
+++ b/pkg/string_scanner/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.1.3
+
+* Add an optional `endState` argument to `SpanScanner.spanFrom`.
+
 ## 0.1.2
 
 * Add `StringScanner.substring`, which returns a substring of the source string.
diff --git a/pkg/string_scanner/lib/src/span_scanner.dart b/pkg/string_scanner/lib/src/span_scanner.dart
index a70d5fd..2a78b5b 100644
--- a/pkg/string_scanner/lib/src/span_scanner.dart
+++ b/pkg/string_scanner/lib/src/span_scanner.dart
@@ -58,8 +58,10 @@
 
   /// Creates a [FileSpan] representing the source range between [startState]
   /// and the current position.
-  FileSpan spanFrom(LineScannerState startState) =>
-      _sourceFile.span(startState.position, position);
+  FileSpan spanFrom(LineScannerState startState, [LineScannerState endState]) {
+    var endPosition = endState == null ? position : endState.position;
+    return _sourceFile.span(startState.position, endPosition);
+  }
 
   bool matches(Pattern pattern) {
     if (!super.matches(pattern)) {
diff --git a/pkg/string_scanner/pubspec.yaml b/pkg/string_scanner/pubspec.yaml
index d14a43e..da93ead 100644
--- a/pkg/string_scanner/pubspec.yaml
+++ b/pkg/string_scanner/pubspec.yaml
@@ -1,5 +1,5 @@
 name: string_scanner
-version: 0.1.2
+version: 0.1.3
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: >
diff --git a/pkg/unittest/CHANGELOG.md b/pkg/unittest/CHANGELOG.md
index 7dfada9..4b5cfdd 100644
--- a/pkg/unittest/CHANGELOG.md
+++ b/pkg/unittest/CHANGELOG.md
@@ -1,3 +1,7 @@
+##0.11.4
+
+* Bump the version constraint for `matcher`.
+
 ##0.11.3
 
 * Narrow the constraint on matcher to ensure that new features are reflected in
diff --git a/pkg/unittest/pubspec.yaml b/pkg/unittest/pubspec.yaml
index 0db9cbd..032cbca 100644
--- a/pkg/unittest/pubspec.yaml
+++ b/pkg/unittest/pubspec.yaml
@@ -1,5 +1,5 @@
 name: unittest
-version: 0.11.3
+version: 0.11.4
 author: Dart Team <misc@dartlang.org>
 description: A library for writing dart unit tests.
 homepage: https://pub.dartlang.org/packages/unittest
@@ -11,6 +11,6 @@
   # Because unittest exports matcher, it needs to keep its version constraint
   # tight to ensure that a constraint on unittest properly constraints all
   # features it provides.
-  matcher: '>=0.11.2 <0.11.3'
+  matcher: '>=0.11.3 <0.11.4'
 dev_dependencies:
   metatest: '>=0.1.0 <0.2.0'
diff --git a/pkg/yaml/CHANGELOG.md b/pkg/yaml/CHANGELOG.md
index f454255..b864250 100644
--- a/pkg/yaml/CHANGELOG.md
+++ b/pkg/yaml/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 2.1.2
+
+* Fix a crashing bug when parsing block scalars.
+
+## 2.1.1
+
+* Properly scope `SourceSpan`s for scalar values surrounded by whitespace.
+
 ## 2.1.0
 
 * Rewrite the parser for a 10x speed improvement.
diff --git a/pkg/yaml/lib/src/scanner.dart b/pkg/yaml/lib/src/scanner.dart
index 0068553..e1b578e 100644
--- a/pkg/yaml/lib/src/scanner.dart
+++ b/pkg/yaml/lib/src/scanner.dart
@@ -1156,6 +1156,7 @@
     var leadingBreak = '';
     var leadingBlank = false;
     var trailingBlank = false;
+    var end = _scanner.state;
     while (_scanner.column == indent && !_scanner.isDone) {
       // Check for a document indicator. libyaml doesn't do this, but the spec
       // mandates it. See example 9.5:
@@ -1188,6 +1189,7 @@
         _scanner.readChar();
       }
       buffer.write(_scanner.substring(startPosition));
+      end = _scanner.state;
 
       // libyaml always reads a line here, but this breaks on block scalars at
       // the end of the document that end without newlines. See example 8.1:
@@ -1204,7 +1206,7 @@
     if (chomping != _Chomping.STRIP) buffer.write(leadingBreak);
     if (chomping == _Chomping.KEEP) buffer.write(trailingBreaks);
 
-    return new ScalarToken(_scanner.spanFrom(start), buffer.toString(),
+    return new ScalarToken(_scanner.spanFrom(start, end), buffer.toString(),
         literal ? ScalarStyle.LITERAL : ScalarStyle.FOLDED);
   }
 
@@ -1430,6 +1432,7 @@
   /// Scans a plain scalar.
   Token _scanPlainScalar() {
     var start = _scanner.state;
+    var end = _scanner.state;
     var buffer = new StringBuffer();
     var leadingBreak = '';
     var trailingBreaks = '';
@@ -1466,6 +1469,7 @@
         _scanner.readChar();
       }
       buffer.write(_scanner.substring(startPosition));
+      end = _scanner.state;
 
       // Is it the end?
       if (!_isBlank && !_isBreak) break;
@@ -1501,7 +1505,7 @@
     // Allow a simple key after a plain scalar with leading blanks.
     if (leadingBreak.isNotEmpty) _simpleKeyAllowed = true;
 
-    return new ScalarToken(_scanner.spanFrom(start), buffer.toString(),
+    return new ScalarToken(_scanner.spanFrom(start, end), buffer.toString(),
         ScalarStyle.PLAIN);
   }
 
diff --git a/pkg/yaml/pubspec.yaml b/pkg/yaml/pubspec.yaml
index d0d51c5..88650fc 100644
--- a/pkg/yaml/pubspec.yaml
+++ b/pkg/yaml/pubspec.yaml
@@ -1,12 +1,12 @@
 name: yaml
-version: 2.1.0
+version: 2.1.2
 author: "Dart Team <misc@dartlang.org>"
 homepage: http://www.dartlang.org
 description: A parser for YAML.
 dependencies:
   collection: ">=1.1.0 <2.0.0"
   path: ">=1.2.0 <2.0.0"
-  string_scanner: ">=0.1.2 <0.2.0"
+  string_scanner: ">=0.1.3 <0.2.0"
   source_span: ">=1.0.0 <2.0.0"
 dev_dependencies:
   unittest: ">=0.9.0 <0.12.0"
diff --git a/runtime/bin/dbg_message.cc b/runtime/bin/dbg_message.cc
index e507544..91558bf 100644
--- a/runtime/bin/dbg_message.cc
+++ b/runtime/bin/dbg_message.cc
@@ -1096,18 +1096,18 @@
   while (true) {
     // Handle all available vm service messages, up to a resume
     // request.
-    while (Dart_HasServiceMessages()) {
+    bool resume = false;
+    while (!resume && Dart_HasServiceMessages()) {
       // Release the message queue lock before handling service
       // messages.  This allows notifications to come in while we are
       // processing long requests and avoids deadlock with the PortMap
       // lock in the vm.
       msg_queue_lock_.Exit();
-      bool resume = Dart_HandleServiceMessages();
+      resume = Dart_HandleServiceMessages();
       msg_queue_lock_.Enter();
-      if (resume) {
-        // Resume requested through the vm service.
-        break;
-      }
+    }
+    if (resume) {
+      break;
     }
 
     // Handle all available debug messages, up to a resume request.
diff --git a/runtime/bin/vmservice/observatory/deployed/web/index.html b/runtime/bin/vmservice/observatory/deployed/web/index.html
index 0893722..ef8e873 100644
--- a/runtime/bin/vmservice/observatory/deployed/web/index.html
+++ b/runtime/bin/vmservice/observatory/deployed/web/index.html
@@ -4100,6 +4100,12 @@
     #classtable tr:hover > td {
       background-color: #F4C7C3;
     }
+    .nav-option {
+      color: white;
+      float: right;
+      margin: 3px;
+      padding: 8px;
+    }
   </style>
   <nav-bar>
     <top-nav-menu></top-nav-menu>
@@ -4108,6 +4114,9 @@
     <nav-refresh callback="{{ resetAccumulator }}" label="Reset Accumulator"></nav-refresh>
     <nav-refresh callback="{{ refreshGC }}" label="GC"></nav-refresh>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <div class="nav-option">
+      <input type="checkbox" checked="{{ autoRefresh }}">Auto-refresh on GC
+    </div>
     <nav-control></nav-control>
   </nav-bar>
   <div class="content">
@@ -4240,6 +4249,7 @@
 
 
 
+
 <polymer-element name="sliding-checkbox">
   <template>
     <style>
diff --git a/runtime/bin/vmservice/observatory/deployed/web/index.html_bootstrap.dart.js b/runtime/bin/vmservice/observatory/deployed/web/index.html_bootstrap.dart.js
index b0e84c5..6017b53 100644
--- a/runtime/bin/vmservice/observatory/deployed/web/index.html_bootstrap.dart.js
+++ b/runtime/bin/vmservice/observatory/deployed/web/index.html_bootstrap.dart.js
@@ -1708,13 +1708,13 @@
 z=this.b
 for(y=0;y<z.length;++y){x=z[y]
 b.$2(x,this.Uf(x))}},
-gvc:function(a){return H.J(new H.AV(this),[H.u3(this,0)])},
+gvc:function(a){return H.J(new H.ph(this),[H.u3(this,0)])},
 gUQ:function(a){return H.fR(this.b,new H.hY(this),H.u3(this,0),H.u3(this,1))},
 $isyN:true},
 hY:{
 "^":"r:14;Q",
 $1:[function(a){return this.Q.Uf(a)},"$1",null,2,0,null,81,"call"]},
-AV:{
+ph:{
 "^":"mW;Q",
 gu:function(a){return J.Nx(this.Q.b)}},
 LI:{
@@ -2136,7 +2136,7 @@
 gFR:function(a){return a.kX},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.kX=this.ct(a,C.U,a.kX,b)},
+sFR:function(a,b){a.kX=this.ct(a,C.AV,a.kX,b)},
 gph:function(a){return a.RZ},
 sph:function(a,b){a.RZ=this.ct(a,C.hf,a.RZ,b)},
 gih:function(a){return a.ij},
@@ -2234,7 +2234,7 @@
 z.giG(b).ml(this.gm6())
 y=b.gG2()
 H.J(new P.rk(y),[H.u3(y,0)]).yI(this.glQ())
-J.HL(z.gRk(b)).yI(this.gPF())
+J.HL(z.gRk(b)).yI(this.gPF(this))
 z=b.gXs()
 H.J(new P.rk(z),[H.u3(z,0)]).yI(this.geO())}this.c=b},
 gvK:function(){return this.x},
@@ -2254,17 +2254,17 @@
 H.J(new W.Ov(0,y.Q,y.a,W.Yt(z.gTk()),y.b),[H.u3(y,0)]).P6()
 z.VA()},
 pZ:function(a){J.OP(this.x,new G.xE(a,new G.cE()))},
-rG:[function(a){var z=J.RE(a)
-switch(z.gfG(a)){case"IsolateCreated":break
-case"IsolateShutdown":this.pZ(z.god(a))
+rG:[function(a,b){var z=J.RE(b)
+switch(z.gfG(b)){case"IsolateCreated":break
+case"IsolateShutdown":this.pZ(z.god(b))
 break
-case"BreakpointResolved":z.god(a).Xb()
+case"BreakpointResolved":z.god(b).Xb()
 break
-case"BreakpointReached":case"IsolateInterrupted":case"ExceptionThrown":this.pZ(z.god(a))
-J.dH(this.x,a)
+case"BreakpointReached":case"IsolateInterrupted":case"ExceptionThrown":this.pZ(z.god(b))
+J.dH(this.x,b)
 break
 case"GC":break
-default:N.QM("").YX("Unrecognized event: "+H.d(a))
+default:N.QM("").YX("Unrecognized event: "+H.d(b))
 break}},"$1","gPF",2,0,86,87],
 Iu:[function(a){this.r=a
 this.aX("error/",null)},"$1","glQ",2,0,88,24],
@@ -2651,14 +2651,14 @@
 return J.WB(z,this.d?"\u25bc":"\u25b2")},"$1","gCO",2,0,16,101]}}],["","",,E,{
 "^":"",
 E24:[function(){var z,y,x
-z=P.B([C.S,new E.L(),C.N,new E.Q(),C.X,new E.O(),C.P,new E.Y(),C.V,new E.em(),C.Z,new E.Lb(),C.W,new E.QA(),C.ET,new E.Cv(),C.T,new E.ed(),C.M,new E.wa(),C.hR,new E.Or(),C.S4,new E.YL(),C.R,new E.wf(),C.hN,new E.Oa(),C.U,new E.emv(),C.bV,new E.Lbd(),C.C0,new E.QAa(),C.eZ,new E.CvS(),C.bk,new E.edy(),C.lH,new E.waE(),C.am,new E.Ore(),C.oE,new E.YLa(),C.kG,new E.wfa(),C.OI,new E.Oaa(),C.Wt,new E.e0(),C.I9,new E.e1(),C.To,new E.e2(),C.mM,new E.e3(),C.aw,new E.e4(),C.XA,new E.e5(),C.i4,new E.e6(),C.mJ,new E.e7(),C.qt,new E.e8(),C.p1,new E.e9(),C.yJ,new E.e10(),C.la,new E.e11(),C.yL,new E.e12(),C.nr,new E.e13(),C.bJ,new E.e14(),C.ox,new E.e15(),C.Je,new E.e16(),C.kI,new E.e17(),C.vY,new E.e18(),C.Rs,new E.e19(),C.hJ,new E.e20(),C.yC,new E.e21(),C.Lw,new E.e22(),C.eR,new E.e23(),C.LS,new E.e24(),C.iE,new E.e25(),C.f4,new E.e26(),C.VK,new E.e27(),C.aH,new E.e28(),C.aK,new E.e29(),C.GP,new E.e30(),C.mw,new E.e31(),C.vs,new E.e32(),C.Gr,new E.e33(),C.TU,new E.e34(),C.Fe,new E.e35(),C.tP,new E.e36(),C.yh,new E.e37(),C.Zb,new E.e38(),C.u7,new E.e39(),C.p8,new E.e40(),C.qR,new E.e41(),C.ld,new E.e42(),C.ne,new E.e43(),C.B0,new E.e44(),C.r1,new E.e45(),C.mr,new E.e46(),C.Ek,new E.e47(),C.Pn,new E.e48(),C.YT,new E.e49(),C.h7,new E.e50(),C.R3,new E.e51(),C.cJ,new E.e52(),C.WQ,new E.e53(),C.fV,new E.e54(),C.jU,new E.e55(),C.OO,new E.e56(),C.Mc,new E.e57(),C.FP,new E.e58(),C.kF,new E.e59(),C.UD,new E.e60(),C.Aq,new E.e61(),C.DS,new E.e62(),C.C9,new E.e63(),C.VF,new E.e64(),C.uU,new E.e65(),C.YJ,new E.e66(),C.EF,new E.e67(),C.oI,new E.e68(),C.ST,new E.e69(),C.QH,new E.e70(),C.qX,new E.e71(),C.rE,new E.e72(),C.nf,new E.e73(),C.EI,new E.e74(),C.JB,new E.e75(),C.RY,new E.e76(),C.d4,new E.e77(),C.cF,new E.e78(),C.ft,new E.e79(),C.dr,new E.e80(),C.SI,new E.e81(),C.zS,new E.e82(),C.YA,new E.e83(),C.Ge,new E.e84(),C.A7,new E.e85(),C.He,new E.e86(),C.im,new E.e87(),C.Ss,new E.e88(),C.k6,new E.e89(),C.oj,new E.e90(),C.PJ,new E.e91(),C.Yb,new E.e92(),C.q2,new E.e93(),C.d2,new E.e94(),C.kN,new E.e95(),C.uO,new E.e96(),C.fn,new E.e97(),C.yB,new E.e98(),C.eJ,new E.e99(),C.iG,new E.e100(),C.Py,new E.e101(),C.pC,new E.e102(),C.uu,new E.e103(),C.qs,new E.e104(),C.XH,new E.e105(),C.XJ,new E.e106(),C.tJ,new E.e107(),C.F8,new E.e108(),C.fy,new E.e109(),C.C1,new E.e110(),C.Nr,new E.e111(),C.nL,new E.e112(),C.a0,new E.e113(),C.Yg,new E.e114(),C.bR,new E.e115(),C.ai,new E.e116(),C.ob,new E.e117(),C.dR,new E.e118(),C.MY,new E.e119(),C.Wg,new E.e120(),C.tD,new E.e121(),C.QS,new E.e122(),C.C7,new E.e123(),C.nZ,new E.e124(),C.Of,new E.e125(),C.Vl,new E.e126(),C.pY,new E.e127(),C.XL,new E.e128(),C.LA,new E.e129(),C.Iw,new E.e130(),C.tz,new E.e131(),C.AT,new E.e132(),C.Lk,new E.e133(),C.GS,new E.e134(),C.rB,new E.e135(),C.bz,new E.e136(),C.Jx,new E.e137(),C.b5,new E.e138(),C.z6,new E.e139(),C.SY,new E.e140(),C.Lc,new E.e141(),C.hf,new E.e142(),C.uk,new E.e143(),C.Zi,new E.e144(),C.TN,new E.e145(),C.GI,new E.e146(),C.Wn,new E.e147(),C.ur,new E.e148(),C.VN,new E.e149(),C.EV,new E.e150(),C.VI,new E.e151(),C.eh,new E.e152(),C.SA,new E.e153(),C.uG,new E.e154(),C.kV,new E.e155(),C.vp,new E.e156(),C.cc,new E.e157(),C.DY,new E.e158(),C.Lx,new E.e159(),C.M3,new E.e160(),C.wT,new E.e161(),C.JK,new E.e162(),C.SR,new E.e163(),C.t6,new E.e164(),C.rP,new E.e165(),C.qi,new E.e166(),C.pX,new E.e167(),C.kB,new E.e168(),C.LH,new E.e169(),C.a2,new E.e170(),C.VD,new E.e171(),C.NN,new E.e172(),C.UX,new E.e173(),C.YS,new E.e174(),C.pu,new E.e175(),C.uw,new E.e176(),C.BJ,new E.e177(),C.c6,new E.e178(),C.td,new E.e179(),C.Gn,new E.e180(),C.zO,new E.e181(),C.vg,new E.e182(),C.Yp,new E.e183(),C.YV,new E.e184(),C.If,new E.e185(),C.Ys,new E.e186(),C.zm,new E.e187(),C.EP,new E.e188(),C.nX,new E.e189(),C.BV,new E.e190(),C.xP,new E.e191(),C.XM,new E.e192(),C.Ic,new E.e193(),C.yG,new E.e194(),C.uI,new E.e195(),C.O9,new E.e196(),C.ba,new E.e197(),C.tW,new E.e198(),C.CG,new E.e199(),C.Jf,new E.e200(),C.Wj,new E.e201(),C.vb,new E.e202(),C.UL,new E.e203(),C.AY,new E.e204(),C.QK,new E.e205(),C.AO,new E.e206(),C.Xd,new E.e207(),C.I7,new E.e208(),C.kY,new E.e209(),C.Wm,new E.e210(),C.vK,new E.e211(),C.Tc,new E.e212(),C.GR,new E.e213(),C.KX,new E.e214(),C.ja,new E.e215(),C.mn,new E.e216(),C.Dj,new E.e217(),C.ir,new E.e218(),C.dx,new E.e219(),C.ni,new E.e220(),C.X2,new E.e221(),C.F3,new E.e222(),C.UY,new E.e223(),C.Aa,new E.e224(),C.nY,new E.e225(),C.tg,new E.e226(),C.HD,new E.e227(),C.iU,new E.e228(),C.eN,new E.e229(),C.ue,new E.e230(),C.nh,new E.e231(),C.L2,new E.e232(),C.vm,new E.e233(),C.Gs,new E.e234(),C.bE,new E.e235(),C.YD,new E.e236(),C.PX,new E.e237(),C.N8,new E.e238(),C.FQ,new E.e239(),C.EA,new E.e240(),C.oW,new E.e241(),C.KC,new E.e242(),C.tf,new E.e243(),C.TI,new E.e244(),C.da,new E.e245(),C.Jd,new E.e246(),C.Y4,new E.e247(),C.Si,new E.e248(),C.pH,new E.e249(),C.Ve,new E.e250(),C.jM,new E.e251(),C.rd,new E.e252(),C.rX,new E.e253(),C.W5,new E.e254(),C.uX,new E.e255(),C.nt,new E.e256(),C.IT,new E.e257(),C.li,new E.e258(),C.PM,new E.e259(),C.ks,new E.e260(),C.Om,new E.e261(),C.iC,new E.e262(),C.Nv,new E.e263(),C.Wo,new E.e264(),C.FZ,new E.e265(),C.TW,new E.e266(),C.xS,new E.e267(),C.pD,new E.e268(),C.QF,new E.e269(),C.mi,new E.e270(),C.zz,new E.e271(),C.eO,new E.e272(),C.hO,new E.e273(),C.ei,new E.e274(),C.HK,new E.e275(),C.je,new E.e276(),C.Ef,new E.e277(),C.QL,new E.e278(),C.RH,new E.e279(),C.SP,new E.e280(),C.Q1,new E.e281(),C.ID,new E.e282(),C.dA,new E.e283(),C.bc,new E.e284(),C.nE,new E.e285(),C.ep,new E.e286(),C.hB,new E.e287(),C.J2,new E.e288(),C.hx,new E.e289(),C.zU,new E.e290(),C.OU,new E.e291(),C.bn,new E.e292(),C.mh,new E.e293(),C.Fh,new E.e294(),C.yv,new E.e295(),C.LP,new E.e296(),C.jh,new E.e297(),C.zd,new E.e298(),C.Db,new E.e299(),C.aF,new E.e300(),C.l4,new E.e301(),C.fj,new E.e302(),C.xw,new E.e303(),C.zn,new E.e304(),C.RJ,new E.e305(),C.Sk,new E.e306(),C.KS,new E.e307(),C.MA,new E.e308(),C.YE,new E.e309(),C.Uy,new E.e310()],null,null)
-y=P.B([C.S,new E.e311(),C.N,new E.e312(),C.P,new E.e313(),C.Z,new E.e314(),C.S4,new E.e315(),C.U,new E.e316(),C.bk,new E.e317(),C.lH,new E.e318(),C.am,new E.e319(),C.oE,new E.e320(),C.kG,new E.e321(),C.Wt,new E.e322(),C.mM,new E.e323(),C.aw,new E.e324(),C.XA,new E.e325(),C.i4,new E.e326(),C.mJ,new E.e327(),C.yL,new E.e328(),C.nr,new E.e329(),C.bJ,new E.e330(),C.kI,new E.e331(),C.vY,new E.e332(),C.yC,new E.e333(),C.VK,new E.e334(),C.aH,new E.e335(),C.GP,new E.e336(),C.vs,new E.e337(),C.Gr,new E.e338(),C.Fe,new E.e339(),C.tP,new E.e340(),C.yh,new E.e341(),C.Zb,new E.e342(),C.p8,new E.e343(),C.ld,new E.e344(),C.ne,new E.e345(),C.B0,new E.e346(),C.mr,new E.e347(),C.YT,new E.e348(),C.cJ,new E.e349(),C.WQ,new E.e350(),C.jU,new E.e351(),C.OO,new E.e352(),C.Mc,new E.e353(),C.QH,new E.e354(),C.rE,new E.e355(),C.nf,new E.e356(),C.ft,new E.e357(),C.Ge,new E.e358(),C.A7,new E.e359(),C.He,new E.e360(),C.oj,new E.e361(),C.d2,new E.e362(),C.uO,new E.e363(),C.fn,new E.e364(),C.yB,new E.e365(),C.Py,new E.e366(),C.uu,new E.e367(),C.qs,new E.e368(),C.rB,new E.e369(),C.z6,new E.e370(),C.hf,new E.e371(),C.uk,new E.e372(),C.Zi,new E.e373(),C.TN,new E.e374(),C.ur,new E.e375(),C.EV,new E.e376(),C.VI,new E.e377(),C.eh,new E.e378(),C.SA,new E.e379(),C.uG,new E.e380(),C.kV,new E.e381(),C.vp,new E.e382(),C.SR,new E.e383(),C.t6,new E.e384(),C.kB,new E.e385(),C.UX,new E.e386(),C.YS,new E.e387(),C.c6,new E.e388(),C.td,new E.e389(),C.zO,new E.e390(),C.Yp,new E.e391(),C.YV,new E.e392(),C.If,new E.e393(),C.Ys,new E.e394(),C.EP,new E.e395(),C.nX,new E.e396(),C.BV,new E.e397(),C.XM,new E.e398(),C.Ic,new E.e399(),C.O9,new E.e400(),C.tW,new E.e401(),C.Wj,new E.e402(),C.vb,new E.e403(),C.QK,new E.e404(),C.Xd,new E.e405(),C.kY,new E.e406(),C.vK,new E.e407(),C.Tc,new E.e408(),C.GR,new E.e409(),C.KX,new E.e410(),C.ja,new E.e411(),C.Dj,new E.e412(),C.X2,new E.e413(),C.UY,new E.e414(),C.Aa,new E.e415(),C.nY,new E.e416(),C.tg,new E.e417(),C.HD,new E.e418(),C.iU,new E.e419(),C.eN,new E.e420(),C.Gs,new E.e421(),C.bE,new E.e422(),C.YD,new E.e423(),C.PX,new E.e424(),C.FQ,new E.e425(),C.tf,new E.e426(),C.TI,new E.e427(),C.Jd,new E.e428(),C.pH,new E.e429(),C.Ve,new E.e430(),C.jM,new E.e431(),C.rd,new E.e432(),C.rX,new E.e433(),C.uX,new E.e434(),C.nt,new E.e435(),C.IT,new E.e436(),C.PM,new E.e437(),C.ks,new E.e438(),C.Om,new E.e439(),C.iC,new E.e440(),C.Nv,new E.e441(),C.FZ,new E.e442(),C.TW,new E.e443(),C.pD,new E.e444(),C.mi,new E.e445(),C.zz,new E.e446(),C.dA,new E.e447(),C.nE,new E.e448(),C.hx,new E.e449(),C.zU,new E.e450(),C.OU,new E.e451(),C.zd,new E.e452(),C.RJ,new E.e453(),C.YE,new E.e454()],null,null)
+z=P.B([C.S,new E.L(),C.N,new E.Q(),C.X,new E.O(),C.P,new E.Y(),C.V,new E.em(),C.Z,new E.Lb(),C.W,new E.QA(),C.ET,new E.Cv(),C.U,new E.ed(),C.T,new E.wa(),C.M,new E.Or(),C.hR,new E.YL(),C.S4,new E.wf(),C.R,new E.Oa(),C.hN,new E.emv(),C.AV,new E.Lbd(),C.bV,new E.QAa(),C.C0,new E.CvS(),C.eZ,new E.edy(),C.bk,new E.waE(),C.lH,new E.Ore(),C.am,new E.YLa(),C.oE,new E.wfa(),C.kG,new E.Oaa(),C.OI,new E.e0(),C.Wt,new E.e1(),C.I9,new E.e2(),C.To,new E.e3(),C.mM,new E.e4(),C.aw,new E.e5(),C.XA,new E.e6(),C.i4,new E.e7(),C.mJ,new E.e8(),C.qt,new E.e9(),C.p1,new E.e10(),C.yJ,new E.e11(),C.la,new E.e12(),C.yL,new E.e13(),C.nr,new E.e14(),C.bJ,new E.e15(),C.ox,new E.e16(),C.Je,new E.e17(),C.kI,new E.e18(),C.vY,new E.e19(),C.Rs,new E.e20(),C.hJ,new E.e21(),C.yC,new E.e22(),C.Lw,new E.e23(),C.eR,new E.e24(),C.LS,new E.e25(),C.iE,new E.e26(),C.f4,new E.e27(),C.VK,new E.e28(),C.aH,new E.e29(),C.aK,new E.e30(),C.GP,new E.e31(),C.mw,new E.e32(),C.vs,new E.e33(),C.Gr,new E.e34(),C.TU,new E.e35(),C.Fe,new E.e36(),C.tP,new E.e37(),C.yh,new E.e38(),C.Zb,new E.e39(),C.u7,new E.e40(),C.p8,new E.e41(),C.qR,new E.e42(),C.ld,new E.e43(),C.ne,new E.e44(),C.B0,new E.e45(),C.r1,new E.e46(),C.mr,new E.e47(),C.Ek,new E.e48(),C.Pn,new E.e49(),C.YT,new E.e50(),C.h7,new E.e51(),C.R3,new E.e52(),C.cJ,new E.e53(),C.WQ,new E.e54(),C.fV,new E.e55(),C.jU,new E.e56(),C.OO,new E.e57(),C.Mc,new E.e58(),C.FP,new E.e59(),C.kF,new E.e60(),C.UD,new E.e61(),C.Aq,new E.e62(),C.DS,new E.e63(),C.C9,new E.e64(),C.VF,new E.e65(),C.uU,new E.e66(),C.YJ,new E.e67(),C.EF,new E.e68(),C.oI,new E.e69(),C.ST,new E.e70(),C.QH,new E.e71(),C.qX,new E.e72(),C.rE,new E.e73(),C.nf,new E.e74(),C.EI,new E.e75(),C.JB,new E.e76(),C.RY,new E.e77(),C.d4,new E.e78(),C.cF,new E.e79(),C.ft,new E.e80(),C.dr,new E.e81(),C.SI,new E.e82(),C.zS,new E.e83(),C.YA,new E.e84(),C.Ge,new E.e85(),C.A7,new E.e86(),C.He,new E.e87(),C.im,new E.e88(),C.Ss,new E.e89(),C.k6,new E.e90(),C.oj,new E.e91(),C.PJ,new E.e92(),C.Yb,new E.e93(),C.q2,new E.e94(),C.d2,new E.e95(),C.kN,new E.e96(),C.uO,new E.e97(),C.fn,new E.e98(),C.yB,new E.e99(),C.eJ,new E.e100(),C.iG,new E.e101(),C.Py,new E.e102(),C.pC,new E.e103(),C.uu,new E.e104(),C.qs,new E.e105(),C.XH,new E.e106(),C.XJ,new E.e107(),C.tJ,new E.e108(),C.F8,new E.e109(),C.fy,new E.e110(),C.C1,new E.e111(),C.Nr,new E.e112(),C.nL,new E.e113(),C.a0,new E.e114(),C.Yg,new E.e115(),C.bR,new E.e116(),C.ai,new E.e117(),C.ob,new E.e118(),C.dR,new E.e119(),C.MY,new E.e120(),C.Wg,new E.e121(),C.tD,new E.e122(),C.QS,new E.e123(),C.C7,new E.e124(),C.nZ,new E.e125(),C.Of,new E.e126(),C.Vl,new E.e127(),C.pY,new E.e128(),C.XL,new E.e129(),C.LA,new E.e130(),C.Iw,new E.e131(),C.tz,new E.e132(),C.AT,new E.e133(),C.Lk,new E.e134(),C.GS,new E.e135(),C.rB,new E.e136(),C.bz,new E.e137(),C.Jx,new E.e138(),C.b5,new E.e139(),C.z6,new E.e140(),C.SY,new E.e141(),C.Lc,new E.e142(),C.hf,new E.e143(),C.uk,new E.e144(),C.Zi,new E.e145(),C.TN,new E.e146(),C.GI,new E.e147(),C.Wn,new E.e148(),C.ur,new E.e149(),C.VN,new E.e150(),C.EV,new E.e151(),C.VI,new E.e152(),C.eh,new E.e153(),C.SA,new E.e154(),C.uG,new E.e155(),C.kV,new E.e156(),C.vp,new E.e157(),C.cc,new E.e158(),C.DY,new E.e159(),C.Lx,new E.e160(),C.M3,new E.e161(),C.wT,new E.e162(),C.JK,new E.e163(),C.SR,new E.e164(),C.t6,new E.e165(),C.rP,new E.e166(),C.qi,new E.e167(),C.pX,new E.e168(),C.kB,new E.e169(),C.LH,new E.e170(),C.a2,new E.e171(),C.VD,new E.e172(),C.NN,new E.e173(),C.UX,new E.e174(),C.YS,new E.e175(),C.pu,new E.e176(),C.uw,new E.e177(),C.BJ,new E.e178(),C.c6,new E.e179(),C.td,new E.e180(),C.Gn,new E.e181(),C.zO,new E.e182(),C.vg,new E.e183(),C.Yp,new E.e184(),C.YV,new E.e185(),C.If,new E.e186(),C.Ys,new E.e187(),C.zm,new E.e188(),C.EP,new E.e189(),C.nX,new E.e190(),C.BV,new E.e191(),C.xP,new E.e192(),C.XM,new E.e193(),C.Ic,new E.e194(),C.yG,new E.e195(),C.uI,new E.e196(),C.O9,new E.e197(),C.ba,new E.e198(),C.tW,new E.e199(),C.CG,new E.e200(),C.Jf,new E.e201(),C.Wj,new E.e202(),C.vb,new E.e203(),C.UL,new E.e204(),C.AY,new E.e205(),C.QK,new E.e206(),C.AO,new E.e207(),C.Xd,new E.e208(),C.I7,new E.e209(),C.kY,new E.e210(),C.Wm,new E.e211(),C.vK,new E.e212(),C.Tc,new E.e213(),C.GR,new E.e214(),C.KX,new E.e215(),C.ja,new E.e216(),C.mn,new E.e217(),C.Dj,new E.e218(),C.ir,new E.e219(),C.dx,new E.e220(),C.ni,new E.e221(),C.X2,new E.e222(),C.F3,new E.e223(),C.UY,new E.e224(),C.Aa,new E.e225(),C.nY,new E.e226(),C.tg,new E.e227(),C.HD,new E.e228(),C.iU,new E.e229(),C.eN,new E.e230(),C.ue,new E.e231(),C.nh,new E.e232(),C.L2,new E.e233(),C.vm,new E.e234(),C.Gs,new E.e235(),C.bE,new E.e236(),C.YD,new E.e237(),C.PX,new E.e238(),C.N8,new E.e239(),C.FQ,new E.e240(),C.EA,new E.e241(),C.oW,new E.e242(),C.KC,new E.e243(),C.tf,new E.e244(),C.TI,new E.e245(),C.da,new E.e246(),C.Jd,new E.e247(),C.Y4,new E.e248(),C.Si,new E.e249(),C.pH,new E.e250(),C.Ve,new E.e251(),C.jM,new E.e252(),C.rd,new E.e253(),C.rX,new E.e254(),C.W5,new E.e255(),C.uX,new E.e256(),C.nt,new E.e257(),C.IT,new E.e258(),C.li,new E.e259(),C.PM,new E.e260(),C.ks,new E.e261(),C.Om,new E.e262(),C.iC,new E.e263(),C.Nv,new E.e264(),C.Wo,new E.e265(),C.FZ,new E.e266(),C.TW,new E.e267(),C.xS,new E.e268(),C.pD,new E.e269(),C.QF,new E.e270(),C.mi,new E.e271(),C.zz,new E.e272(),C.eO,new E.e273(),C.hO,new E.e274(),C.ei,new E.e275(),C.HK,new E.e276(),C.je,new E.e277(),C.Ef,new E.e278(),C.QL,new E.e279(),C.RH,new E.e280(),C.SP,new E.e281(),C.Q1,new E.e282(),C.ID,new E.e283(),C.dA,new E.e284(),C.bc,new E.e285(),C.nE,new E.e286(),C.ep,new E.e287(),C.hB,new E.e288(),C.J2,new E.e289(),C.hx,new E.e290(),C.zU,new E.e291(),C.OU,new E.e292(),C.bn,new E.e293(),C.mh,new E.e294(),C.Fh,new E.e295(),C.yv,new E.e296(),C.LP,new E.e297(),C.jh,new E.e298(),C.zd,new E.e299(),C.Db,new E.e300(),C.aF,new E.e301(),C.l4,new E.e302(),C.fj,new E.e303(),C.xw,new E.e304(),C.zn,new E.e305(),C.RJ,new E.e306(),C.Sk,new E.e307(),C.KS,new E.e308(),C.MA,new E.e309(),C.YE,new E.e310(),C.Uy,new E.e311()],null,null)
+y=P.B([C.S,new E.e312(),C.N,new E.e313(),C.P,new E.e314(),C.Z,new E.e315(),C.U,new E.e316(),C.S4,new E.e317(),C.AV,new E.e318(),C.bk,new E.e319(),C.lH,new E.e320(),C.am,new E.e321(),C.oE,new E.e322(),C.kG,new E.e323(),C.Wt,new E.e324(),C.mM,new E.e325(),C.aw,new E.e326(),C.XA,new E.e327(),C.i4,new E.e328(),C.mJ,new E.e329(),C.yL,new E.e330(),C.nr,new E.e331(),C.bJ,new E.e332(),C.kI,new E.e333(),C.vY,new E.e334(),C.yC,new E.e335(),C.VK,new E.e336(),C.aH,new E.e337(),C.GP,new E.e338(),C.vs,new E.e339(),C.Gr,new E.e340(),C.Fe,new E.e341(),C.tP,new E.e342(),C.yh,new E.e343(),C.Zb,new E.e344(),C.p8,new E.e345(),C.ld,new E.e346(),C.ne,new E.e347(),C.B0,new E.e348(),C.mr,new E.e349(),C.YT,new E.e350(),C.cJ,new E.e351(),C.WQ,new E.e352(),C.jU,new E.e353(),C.OO,new E.e354(),C.Mc,new E.e355(),C.QH,new E.e356(),C.rE,new E.e357(),C.nf,new E.e358(),C.ft,new E.e359(),C.Ge,new E.e360(),C.A7,new E.e361(),C.He,new E.e362(),C.oj,new E.e363(),C.d2,new E.e364(),C.uO,new E.e365(),C.fn,new E.e366(),C.yB,new E.e367(),C.Py,new E.e368(),C.uu,new E.e369(),C.qs,new E.e370(),C.rB,new E.e371(),C.z6,new E.e372(),C.hf,new E.e373(),C.uk,new E.e374(),C.Zi,new E.e375(),C.TN,new E.e376(),C.ur,new E.e377(),C.EV,new E.e378(),C.VI,new E.e379(),C.eh,new E.e380(),C.SA,new E.e381(),C.uG,new E.e382(),C.kV,new E.e383(),C.vp,new E.e384(),C.SR,new E.e385(),C.t6,new E.e386(),C.kB,new E.e387(),C.UX,new E.e388(),C.YS,new E.e389(),C.c6,new E.e390(),C.td,new E.e391(),C.zO,new E.e392(),C.Yp,new E.e393(),C.YV,new E.e394(),C.If,new E.e395(),C.Ys,new E.e396(),C.EP,new E.e397(),C.nX,new E.e398(),C.BV,new E.e399(),C.XM,new E.e400(),C.Ic,new E.e401(),C.O9,new E.e402(),C.tW,new E.e403(),C.Wj,new E.e404(),C.vb,new E.e405(),C.QK,new E.e406(),C.Xd,new E.e407(),C.kY,new E.e408(),C.vK,new E.e409(),C.Tc,new E.e410(),C.GR,new E.e411(),C.KX,new E.e412(),C.ja,new E.e413(),C.Dj,new E.e414(),C.X2,new E.e415(),C.UY,new E.e416(),C.Aa,new E.e417(),C.nY,new E.e418(),C.tg,new E.e419(),C.HD,new E.e420(),C.iU,new E.e421(),C.eN,new E.e422(),C.Gs,new E.e423(),C.bE,new E.e424(),C.YD,new E.e425(),C.PX,new E.e426(),C.FQ,new E.e427(),C.tf,new E.e428(),C.TI,new E.e429(),C.Jd,new E.e430(),C.pH,new E.e431(),C.Ve,new E.e432(),C.jM,new E.e433(),C.rd,new E.e434(),C.rX,new E.e435(),C.uX,new E.e436(),C.nt,new E.e437(),C.IT,new E.e438(),C.PM,new E.e439(),C.ks,new E.e440(),C.Om,new E.e441(),C.iC,new E.e442(),C.Nv,new E.e443(),C.FZ,new E.e444(),C.TW,new E.e445(),C.pD,new E.e446(),C.mi,new E.e447(),C.zz,new E.e448(),C.dA,new E.e449(),C.nE,new E.e450(),C.hx,new E.e451(),C.zU,new E.e452(),C.OU,new E.e453(),C.zd,new E.e454(),C.RJ,new E.e455(),C.YE,new E.e456()],null,null)
 x=P.B([C.K4,C.qJ,C.yS,C.Mt,C.OG,C.il,C.nw,C.Mt,C.ou,C.Mt,C.oT,C.il,C.jR,C.Mt,C.XW,C.il,C.kH,C.Mt,C.Lg,C.qJ,C.Wd,C.Mt,C.V7,C.Mt,C.V8,C.Mt,C.hM,C.Mt,C.JX,C.Mt,C.Bi,C.il,C.KO,C.Mt,C.wk,C.Mt,C.jA,C.qJ,C.Jo,C.il,C.Az,C.Mt,C.Vx,C.Mt,C.Qb,C.Mt,C.lE,C.al,C.te,C.Mt,C.iD,C.Mt,C.Ju,C.Mt,C.uC,C.Mt,C.Wz,C.il,C.Ke,C.Mt,C.pF,C.il,C.Wh,C.Mt,C.It,C.Mt,C.qZ,C.il,C.Zj,C.Mt,C.he,C.Mt,C.dD,C.al,C.hP,C.Mt,C.tc,C.Mt,C.rR,C.il,C.oG,C.Mt,C.mK,C.il,C.IZ,C.Mt,C.FG,C.il,C.pJ,C.Mt,C.tU,C.Mt,C.DD,C.Mt,C.Yy,C.il,C.Xv,C.Mt,C.ce,C.Mt,C.UJ,C.il,C.ca,C.Mt,C.Io,C.Mt,C.j4,C.Mt,C.EG,C.Mt,C.CT,C.Mt,C.mq,C.Mt,C.Tq,C.Mt,C.lp,C.il,C.PT,C.Mt,C.fU,C.Mt,C.pi,C.Mt,C.Fn,C.Mt,C.Ey,C.Mt,C.km,C.Mt,C.vw,C.Mt,C.LT,C.Mt,C.NW,C.Mz,C.ms,C.Mt,C.FA,C.Mt,C.Qt,C.Mt,C.a8,C.Mt,C.JW,C.Mt,C.Mf,C.Mt,C.rC,C.Mt,C.kq,C.Mt,C.Dl,C.Mt,C.Mz,C.qJ,C.Nw,C.Mt,C.ON,C.Mt,C.Sb,C.al,C.Th,C.Mt,C.wH,C.Mt,C.pK,C.Mt,C.R9,C.Mt,C.OZ,C.il,C.il,C.Mt,C.QJ,C.Mt,C.u4,C.Mt,C.X8,C.Mt,C.kt,C.Mt,C.Y3,C.qJ,C.bC,C.Mt,C.ws,C.Mt,C.cK,C.il,C.jK,C.Mt,C.qJ,C.jw,C.Mt,C.Mz,C.al,C.il],null,null)
-y=O.rH(!1,P.B([C.K4,P.B([C.S4,C.aj,C.U,C.Qp,C.mJ,C.Dx,C.hf,C.BT],null,null),C.yS,P.B([C.UX,C.Pt],null,null),C.OG,P.A(null,null),C.nw,P.B([C.rB,C.xY,C.bz,C.Bk],null,null),C.ou,P.B([C.XA,C.dq,C.yB,C.vZ,C.tg,C.DC],null,null),C.oT,P.B([C.i4,C.Qs,C.Wm,C.QW],null,null),C.jR,P.B([C.i4,C.aJ],null,null),C.XW,P.A(null,null),C.kH,P.B([C.nr,C.BO],null,null),C.Lg,P.B([C.S4,C.aj,C.U,C.Qp,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz],null,null),C.Wd,P.B([C.rB,C.RU],null,null),C.V7,P.B([C.S4,C.aj,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz,C.rE,C.B7,C.FQ,C.Ow],null,null),C.V8,P.B([C.rB,C.RU,C.mi,C.VB],null,null),C.hM,P.B([C.rB,C.RU,C.TI,C.NU],null,null),C.JX,P.B([C.N,C.ZX,C.rB,C.RU,C.bz,C.Bk,C.rX,C.Wp],null,null),C.Bi,P.A(null,null),C.KO,P.B([C.yh,C.tO],null,null),C.wk,P.B([C.U,C.k1,C.eh,C.IP,C.Aa,C.k5,C.mi,C.nH],null,null),C.jA,P.B([C.S4,C.aj,C.U,C.Qp,C.YT,C.LC,C.hf,C.BT,C.UY,C.n6],null,null),C.Jo,P.A(null,null),C.Az,P.B([C.WQ,C.on],null,null),C.Vx,P.B([C.OO,C.Cf],null,null),C.Qb,P.B([C.Mc,C.f0],null,null),C.lE,P.B([C.QK,C.P9],null,null),C.te,P.B([C.nf,C.wR],null,null),C.iD,P.B([C.QH,C.C4,C.qX,C.dO,C.PM,C.Jr],null,null),C.Ju,P.B([C.kG,C.Pr,C.rB,C.xY,C.Zi,C.vC,C.TN,C.K1,C.vb,C.Mq,C.UL,C.bG],null,null),C.uC,P.B([C.uO,C.KK,C.kY,C.rT],null,null),C.Wz,P.A(null,null),C.Ke,P.B([C.fn,C.Kk],null,null),C.pF,P.A(null,null),C.Wh,P.B([C.yL,C.j5],null,null),C.It,P.B([C.vp,C.o0],null,null),C.qZ,P.A(null,null),C.Zj,P.B([C.oj,C.GT],null,null),C.he,P.B([C.vp,C.o0],null,null),C.dD,P.B([C.pH,C.xV],null,null),C.hP,P.B([C.Wj,C.Ah],null,null),C.tc,P.B([C.vp,C.o0],null,null),C.rR,P.A(null,null),C.oG,P.B([C.jU,C.bw],null,null),C.mK,P.A(null,null),C.IZ,P.B([C.vp,C.o0],null,null),C.FG,P.A(null,null),C.pJ,P.B([C.Ve,C.X4],null,null),C.tU,P.B([C.qs,C.MN],null,null),C.DD,P.B([C.vp,C.o0],null,null),C.Yy,P.A(null,null),C.Xv,P.B([C.YE,C.Wl],null,null),C.ce,P.B([C.aH,C.Ei,C.He,C.fz,C.vb,C.Mq,C.UL,C.bG,C.Dj,C.kA,C.Gs,C.Wq,C.bE,C.Dh,C.YD,C.bl,C.TW,C.B3,C.xS,C.hd,C.zz,C.mb],null,null),C.UJ,P.A(null,null),C.ca,P.B([C.bJ,C.UI,C.ox,C.Rh],null,null),C.Io,P.B([C.rB,C.RU],null,null),C.j4,P.B([C.rB,C.RU],null,null),C.EG,P.B([C.rB,C.RU],null,null),C.CT,P.B([C.rB,C.RU],null,null),C.mq,P.B([C.rB,C.RU],null,null),C.Tq,P.B([C.SR,C.S9,C.t6,C.Hk,C.rP,C.Nt],null,null),C.lp,P.A(null,null),C.PT,P.B([C.EV,C.V0],null,null),C.fU,P.B([C.kB,C.nq,C.LH,C.oB,C.EP,C.db],null,null),C.pi,P.B([C.rB,C.xY,C.kB,C.nq,C.LH,C.oB],null,null),C.Fn,P.B([C.rB,C.xY,C.bz,C.Bk,C.EP,C.GO,C.tf,C.q6],null,null),C.Ey,P.B([C.XA,C.dq,C.uk,C.rY],null,null),C.km,P.B([C.rB,C.RU,C.bz,C.Bk,C.uk,C.rY],null,null),C.vw,P.B([C.uk,C.rY,C.EV,C.V0],null,null),C.LT,P.B([C.Ys,C.Cg],null,null),C.NW,P.A(null,null),C.ms,P.B([C.P,C.TE,C.uk,C.rY,C.kV,C.RZ],null,null),C.FA,P.B([C.P,C.TE,C.kV,C.RZ],null,null),C.Qt,P.B([C.ld,C.Gw],null,null),C.a8,P.B([C.p8,C.uc,C.ld,C.Gw],null,null),C.JW,P.B([C.S,C.oh,C.U,C.Qp,C.hf,C.BT],null,null),C.Mf,P.B([C.uk,C.rY],null,null),C.rC,P.B([C.uO,C.JT,C.td,C.Zk,C.XM,C.Tt,C.tg,C.DC],null,null),C.kq,P.B([C.td,C.Zk],null,null),C.Dl,P.B([C.VK,C.lW],null,null),C.Mz,P.B([C.O9,C.q9,C.ba,C.yV],null,null),C.Nw,P.B([C.S4,C.aj,C.VI,C.w6],null,null),C.ON,P.B([C.kI,C.Bf,C.vY,C.ZS,C.Rs,C.EW,C.vs,C.MP,C.Gr,C.VJ,C.TU,C.Cp,C.A7,C.cD,C.SA,C.KI,C.uG,C.Df,C.PX,C.jz,C.N8,C.qE,C.nt,C.VS,C.IT,C.NL,C.li,C.Tz],null,null),C.Sb,P.B([C.tW,C.Qc,C.CG,C.Ml],null,null),C.Th,P.B([C.PX,C.jz],null,null),C.wH,P.B([C.yh,C.lJ],null,null),C.pK,P.B([C.ne,C.bp],null,null),C.R9,P.B([C.kY,C.TO,C.Wm,C.QW],null,null),C.OZ,P.A(null,null),C.il,P.B([C.uu,C.NJ,C.kY,C.TO,C.Wm,C.QW],null,null),C.QJ,P.B([C.B0,C.iH,C.vp,C.Rz],null,null),C.u4,P.B([C.B0,C.iH,C.SR,C.hS],null,null),C.X8,P.B([C.Z,C.b7,C.td,C.Zk,C.Gn,C.az],null,null),C.kt,P.B([C.nE,C.FM],null,null),C.Y3,P.B([C.bk,C.NS,C.lH,C.M6,C.zU,C.OS],null,null),C.bC,P.B([C.am,C.JD,C.oE,C.py,C.uX,C.VM],null,null),C.ws,P.B([C.pD,C.Gz],null,null),C.cK,P.A(null,null),C.jK,P.B([C.yh,C.tO,C.RJ,C.BP],null,null)],null,null),z,P.B([C.S,"active",C.N,"activeFrame",C.X,"address",C.P,"anchor",C.V,"app",C.Z,"args",C.W,"asStringLiteral",C.ET,"assertsEnabled",C.T,"averageCollectionPeriodInMillis",C.M,"bpt",C.hR,"breakpoint",C.S4,"busy",C.R,"buttonClick",C.hN,"bytes",C.U,"callback",C.bV,"capacity",C.C0,"change",C.eZ,"changeSort",C.bk,"checked",C.lH,"checkedText",C.am,"chromeTargets",C.oE,"chromiumAddress",C.kG,"classTable",C.OI,"classes",C.Wt,"clazz",C.I9,"closeItem",C.To,"closing",C.mM,"closureCtxt",C.aw,"closureFunc",C.XA,"cls",C.i4,"code",C.mJ,"color",C.qt,"coloring",C.p1,"columns",C.yJ,"connectStandalone",C.la,"connectToVm",C.yL,"connection",C.nr,"context",C.bJ,"counters",C.ox,"countersChanged",C.Je,"current",C.kI,"currentLine",C.vY,"currentPos",C.Rs,"currentPosChanged",C.hJ,"dartMetrics",C.yC,"declaredType",C.Lw,"deleteVm",C.eR,"deoptimizations",C.LS,"description",C.iE,"descriptor",C.f4,"descriptors",C.VK,"devtools",C.aH,"displayCutoff",C.aK,"doAction",C.GP,"element",C.mw,"elements",C.vs,"endLine",C.Gr,"endPos",C.TU,"endPosChanged",C.Fe,"endTokenPos",C.tP,"entry",C.yh,"error",C.Zb,"eval",C.u7,"evalNow",C.p8,"event",C.qR,"eventType",C.ld,"events",C.ne,"exception",C.B0,"expand",C.r1,"expandChanged",C.mr,"expanded",C.Ek,"expander",C.Pn,"expanderStyle",C.YT,"expr",C.h7,"external",C.R3,"fd",C.cJ,"fetchInboundReferences",C.WQ,"field",C.fV,"fields",C.jU,"file",C.OO,"flag",C.Mc,"flagList",C.FP,"formatSize",C.kF,"formatTime",C.UD,"formattedAddress",C.Aq,"formattedAverage",C.DS,"formattedCollections",C.C9,"formattedDeoptId",C.VF,"formattedExclusive",C.uU,"formattedExclusiveTicks",C.YJ,"formattedInclusive",C.EF,"formattedInclusiveTicks",C.oI,"formattedLine",C.ST,"formattedTotalCollectionTime",C.QH,"fragmentation",C.qX,"fragmentationChanged",C.rE,"frame",C.nf,"function",C.EI,"functions",C.JB,"getColumnLabel",C.RY,"getTabs",C.d4,"goto",C.cF,"gotoLink",C.ft,"guardClass",C.dr,"guardNullable",C.SI,"hasDescriptors",C.zS,"hasDisassembly",C.YA,"hasNoAllocations",C.Ge,"hashLinkWorkaround",C.A7,"height",C.He,"hideTagsChecked",C.im,"history",C.Ss,"hits",C.k6,"hoverText",C.oj,"httpServer",C.PJ,"human",C.Yb,"id",C.q2,"idle",C.d2,"imp",C.kN,"imports",C.uO,"inboundReferences",C.fn,"instance",C.yB,"instances",C.eJ,"instruction",C.iG,"instructions",C.Py,"interface",C.pC,"interfaces",C.uu,"internal",C.qs,"io",C.XH,"isAbstract",C.XJ,"isAbstractType",C.tJ,"isBool",C.F8,"isChromeTarget",C.fy,"isClosure",C.C1,"isComment",C.Nr,"isConst",C.nL,"isCurrentTarget",C.a0,"isDart",C.Yg,"isDartCode",C.bR,"isDouble",C.ai,"isEmpty",C.ob,"isError",C.dR,"isFinal",C.MY,"isInlinable",C.Wg,"isInt",C.tD,"isList",C.QS,"isMap",C.C7,"isMirrorReference",C.nZ,"isNotEmpty",C.Of,"isNull",C.Vl,"isOptimizable",C.pY,"isOptimized",C.XL,"isPatch",C.LA,"isPipe",C.Iw,"isPlainInstance",C.tz,"isSentinel",C.AT,"isStatic",C.Lk,"isString",C.GS,"isWeakProperty",C.rB,"isolate",C.bz,"isolateChanged",C.Jx,"isolates",C.b5,"jumpTarget",C.z6,"key",C.SY,"keys",C.Lc,"kind",C.hf,"label",C.uk,"last",C.Zi,"lastAccumulatorReset",C.TN,"lastServiceGC",C.GI,"lastUpdate",C.Wn,"length",C.ur,"lib",C.VN,"libraries",C.EV,"library",C.VI,"line",C.eh,"lineMode",C.SA,"lines",C.uG,"linesReady",C.kV,"link",C.vp,"list",C.cc,"listening",C.DY,"loading",C.Lx,"localAddress",C.M3,"localPort",C.wT,"mainPort",C.JK,"makeLineId",C.SR,"map",C.t6,"mapAsString",C.rP,"mapChanged",C.qi,"max",C.pX,"message",C.kB,"metric",C.LH,"metricChanged",C.a2,"min",C.VD,"mouseOut",C.NN,"mouseOver",C.UX,"msg",C.YS,"name",C.pu,"nameIsEmpty",C.uw,"nativeFields",C.BJ,"newSpace",C.c6,"notifications",C.td,"object",C.Gn,"objectChanged",C.zO,"objectPool",C.vg,"oldSpace",C.Yp,"owner",C.YV,"owningClass",C.If,"owningLibrary",C.Ys,"pad",C.zm,"padding",C.EP,"page",C.nX,"parent",C.BV,"parentContext",C.xP,"parseInt",C.XM,"path",C.Ic,"pause",C.yG,"pauseEvent",C.uI,"pid",C.O9,"pollPeriod",C.ba,"pollPeriodChanged",C.tW,"pos",C.CG,"posChanged",C.Jf,"possibleBpt",C.Wj,"process",C.vb,"profile",C.UL,"profileChanged",C.AY,"protocol",C.QK,"qualified",C.AO,"qualifiedName",C.Xd,"reachable",C.I7,"readClosed",C.kY,"ref",C.Wm,"refChanged",C.vK,"reference",C.Tc,"referent",C.GR,"refresh",C.KX,"refreshCoverage",C.ja,"refreshGC",C.mn,"refreshRateChange",C.Dj,"refreshTime",C.ir,"relativeLink",C.dx,"remoteAddress",C.ni,"remotePort",C.X2,"resetAccumulator",C.F3,"response",C.UY,"result",C.Aa,"results",C.nY,"resume",C.tg,"retainedBytes",C.HD,"retainedSize",C.iU,"retainingPath",C.eN,"rootLib",C.ue,"row",C.nh,"rows",C.L2,"running",C.vm,"sampleBufferSizeChange",C.Gs,"sampleCount",C.bE,"sampleDepth",C.YD,"sampleRate",C.PX,"script",C.N8,"scriptChanged",C.FQ,"scriptHeight",C.EA,"scripts",C.oW,"selectExpr",C.KC,"selectMetric",C.tf,"selectedMetric",C.TI,"showConsole",C.da,"size",C.Jd,"slot",C.Y4,"slotIsArrayIndex",C.Si,"slotIsField",C.pH,"small",C.Ve,"socket",C.jM,"socketOwner",C.rd,"source",C.rX,"stack",C.W5,"standalone",C.uX,"standaloneVmAddress",C.nt,"startLine",C.IT,"startPos",C.li,"startPosChanged",C.PM,"status",C.ks,"stepInto",C.Om,"stepOut",C.iC,"stepOver",C.Nv,"subclass",C.Wo,"subclasses",C.FZ,"superclass",C.TW,"tagSelector",C.xS,"tagSelectorChanged",C.pD,"target",C.QF,"targets",C.mi,"text",C.zz,"timeSpan",C.eO,"timeStamp",C.hO,"tipExclusive",C.ei,"tipKind",C.HK,"tipParent",C.je,"tipTicks",C.Ef,"tipTime",C.QL,"toString",C.RH,"toStringAsFixed",C.SP,"toggleBreakpoint",C.Q1,"toggleExpand",C.ID,"toggleExpanded",C.dA,"tokenPos",C.bc,"topFrame",C.nE,"tracer",C.ep,"tree",C.hB,"type",C.J2,"typeChecksEnabled",C.hx,"typeClass",C.zU,"uncheckedText",C.OU,"unoptimizedCode",C.bn,"updateLineMode",C.mh,"uptime",C.Fh,"url",C.yv,"usageCounter",C.LP,"used",C.jh,"v",C.zd,"value",C.Db,"valueAsString",C.aF,"valueAsStringIsTruncated",C.l4,"values",C.fj,"variable",C.xw,"variables",C.zn,"version",C.RJ,"vm",C.Sk,"vmMetrics",C.KS,"vmName",C.MA,"vmType",C.YE,"webSocket",C.Uy,"writeClosed"],null,null),x,y,null)
+y=O.rH(!1,P.B([C.K4,P.B([C.S4,C.aj,C.AV,C.Qp,C.mJ,C.Dx,C.hf,C.BT],null,null),C.yS,P.B([C.UX,C.Pt],null,null),C.OG,P.A(null,null),C.nw,P.B([C.rB,C.xY,C.bz,C.Bk],null,null),C.ou,P.B([C.XA,C.dq,C.yB,C.vZ,C.tg,C.DC],null,null),C.oT,P.B([C.i4,C.Qs,C.Wm,C.QW],null,null),C.jR,P.B([C.i4,C.aJ],null,null),C.XW,P.A(null,null),C.kH,P.B([C.nr,C.BO],null,null),C.Lg,P.B([C.S4,C.aj,C.AV,C.Qp,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz],null,null),C.Wd,P.B([C.rB,C.RU],null,null),C.V7,P.B([C.S4,C.aj,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz,C.rE,C.B7,C.FQ,C.Ow],null,null),C.V8,P.B([C.rB,C.RU,C.mi,C.VB],null,null),C.hM,P.B([C.rB,C.RU,C.TI,C.NU],null,null),C.JX,P.B([C.N,C.ZX,C.rB,C.RU,C.bz,C.Bk,C.rX,C.Wp],null,null),C.Bi,P.A(null,null),C.KO,P.B([C.yh,C.tO],null,null),C.wk,P.B([C.AV,C.k1,C.eh,C.IP,C.Aa,C.k5,C.mi,C.nH],null,null),C.jA,P.B([C.S4,C.aj,C.AV,C.Qp,C.YT,C.LC,C.hf,C.BT,C.UY,C.n6],null,null),C.Jo,P.A(null,null),C.Az,P.B([C.WQ,C.on],null,null),C.Vx,P.B([C.OO,C.Cf],null,null),C.Qb,P.B([C.Mc,C.f0],null,null),C.lE,P.B([C.QK,C.P9],null,null),C.te,P.B([C.nf,C.wR],null,null),C.iD,P.B([C.QH,C.C4,C.qX,C.dO,C.PM,C.Jr],null,null),C.Ju,P.B([C.U,C.br,C.kG,C.Pr,C.rB,C.xY,C.Zi,C.vC,C.TN,C.K1,C.vb,C.Mq,C.UL,C.bG],null,null),C.uC,P.B([C.uO,C.KK,C.kY,C.rT],null,null),C.Wz,P.A(null,null),C.Ke,P.B([C.fn,C.Kk],null,null),C.pF,P.A(null,null),C.Wh,P.B([C.yL,C.j5],null,null),C.It,P.B([C.vp,C.o0],null,null),C.qZ,P.A(null,null),C.Zj,P.B([C.oj,C.GT],null,null),C.he,P.B([C.vp,C.o0],null,null),C.dD,P.B([C.pH,C.xV],null,null),C.hP,P.B([C.Wj,C.Ah],null,null),C.tc,P.B([C.vp,C.o0],null,null),C.rR,P.A(null,null),C.oG,P.B([C.jU,C.bw],null,null),C.mK,P.A(null,null),C.IZ,P.B([C.vp,C.o0],null,null),C.FG,P.A(null,null),C.pJ,P.B([C.Ve,C.X4],null,null),C.tU,P.B([C.qs,C.MN],null,null),C.DD,P.B([C.vp,C.o0],null,null),C.Yy,P.A(null,null),C.Xv,P.B([C.YE,C.Wl],null,null),C.ce,P.B([C.aH,C.Ei,C.He,C.fz,C.vb,C.Mq,C.UL,C.bG,C.Dj,C.kA,C.Gs,C.Wq,C.bE,C.Dh,C.YD,C.bl,C.TW,C.B3,C.xS,C.hd,C.zz,C.mb],null,null),C.UJ,P.A(null,null),C.ca,P.B([C.bJ,C.UI,C.ox,C.Rh],null,null),C.Io,P.B([C.rB,C.RU],null,null),C.j4,P.B([C.rB,C.RU],null,null),C.EG,P.B([C.rB,C.RU],null,null),C.CT,P.B([C.rB,C.RU],null,null),C.mq,P.B([C.rB,C.RU],null,null),C.Tq,P.B([C.SR,C.S9,C.t6,C.Hk,C.rP,C.Nt],null,null),C.lp,P.A(null,null),C.PT,P.B([C.EV,C.V0],null,null),C.fU,P.B([C.kB,C.nq,C.LH,C.oB,C.EP,C.db],null,null),C.pi,P.B([C.rB,C.xY,C.kB,C.nq,C.LH,C.oB],null,null),C.Fn,P.B([C.rB,C.xY,C.bz,C.Bk,C.EP,C.GO,C.tf,C.q6],null,null),C.Ey,P.B([C.XA,C.dq,C.uk,C.rY],null,null),C.km,P.B([C.rB,C.RU,C.bz,C.Bk,C.uk,C.rY],null,null),C.vw,P.B([C.uk,C.rY,C.EV,C.V0],null,null),C.LT,P.B([C.Ys,C.Cg],null,null),C.NW,P.A(null,null),C.ms,P.B([C.P,C.TE,C.uk,C.rY,C.kV,C.RZ],null,null),C.FA,P.B([C.P,C.TE,C.kV,C.RZ],null,null),C.Qt,P.B([C.ld,C.Gw],null,null),C.a8,P.B([C.p8,C.uc,C.ld,C.Gw],null,null),C.JW,P.B([C.S,C.oh,C.AV,C.Qp,C.hf,C.BT],null,null),C.Mf,P.B([C.uk,C.rY],null,null),C.rC,P.B([C.uO,C.JT,C.td,C.Zk,C.XM,C.Tt,C.tg,C.DC],null,null),C.kq,P.B([C.td,C.Zk],null,null),C.Dl,P.B([C.VK,C.lW],null,null),C.Mz,P.B([C.O9,C.q9,C.ba,C.yV],null,null),C.Nw,P.B([C.S4,C.aj,C.VI,C.w6],null,null),C.ON,P.B([C.kI,C.Bf,C.vY,C.ZS,C.Rs,C.EW,C.vs,C.MP,C.Gr,C.VJ,C.TU,C.Cp,C.A7,C.cD,C.SA,C.KI,C.uG,C.Df,C.PX,C.jz,C.N8,C.qE,C.nt,C.VS,C.IT,C.NL,C.li,C.Tz],null,null),C.Sb,P.B([C.tW,C.Qc,C.CG,C.Ml],null,null),C.Th,P.B([C.PX,C.jz],null,null),C.wH,P.B([C.yh,C.lJ],null,null),C.pK,P.B([C.ne,C.bp],null,null),C.R9,P.B([C.kY,C.TO,C.Wm,C.QW],null,null),C.OZ,P.A(null,null),C.il,P.B([C.uu,C.NJ,C.kY,C.TO,C.Wm,C.QW],null,null),C.QJ,P.B([C.B0,C.iH,C.vp,C.Rz],null,null),C.u4,P.B([C.B0,C.iH,C.SR,C.hS],null,null),C.X8,P.B([C.Z,C.b7,C.td,C.Zk,C.Gn,C.az],null,null),C.kt,P.B([C.nE,C.FM],null,null),C.Y3,P.B([C.bk,C.NS,C.lH,C.M6,C.zU,C.OS],null,null),C.bC,P.B([C.am,C.JD,C.oE,C.py,C.uX,C.VM],null,null),C.ws,P.B([C.pD,C.Gz],null,null),C.cK,P.A(null,null),C.jK,P.B([C.yh,C.tO,C.RJ,C.BP],null,null)],null,null),z,P.B([C.S,"active",C.N,"activeFrame",C.X,"address",C.P,"anchor",C.V,"app",C.Z,"args",C.W,"asStringLiteral",C.ET,"assertsEnabled",C.U,"autoRefresh",C.T,"averageCollectionPeriodInMillis",C.M,"bpt",C.hR,"breakpoint",C.S4,"busy",C.R,"buttonClick",C.hN,"bytes",C.AV,"callback",C.bV,"capacity",C.C0,"change",C.eZ,"changeSort",C.bk,"checked",C.lH,"checkedText",C.am,"chromeTargets",C.oE,"chromiumAddress",C.kG,"classTable",C.OI,"classes",C.Wt,"clazz",C.I9,"closeItem",C.To,"closing",C.mM,"closureCtxt",C.aw,"closureFunc",C.XA,"cls",C.i4,"code",C.mJ,"color",C.qt,"coloring",C.p1,"columns",C.yJ,"connectStandalone",C.la,"connectToVm",C.yL,"connection",C.nr,"context",C.bJ,"counters",C.ox,"countersChanged",C.Je,"current",C.kI,"currentLine",C.vY,"currentPos",C.Rs,"currentPosChanged",C.hJ,"dartMetrics",C.yC,"declaredType",C.Lw,"deleteVm",C.eR,"deoptimizations",C.LS,"description",C.iE,"descriptor",C.f4,"descriptors",C.VK,"devtools",C.aH,"displayCutoff",C.aK,"doAction",C.GP,"element",C.mw,"elements",C.vs,"endLine",C.Gr,"endPos",C.TU,"endPosChanged",C.Fe,"endTokenPos",C.tP,"entry",C.yh,"error",C.Zb,"eval",C.u7,"evalNow",C.p8,"event",C.qR,"eventType",C.ld,"events",C.ne,"exception",C.B0,"expand",C.r1,"expandChanged",C.mr,"expanded",C.Ek,"expander",C.Pn,"expanderStyle",C.YT,"expr",C.h7,"external",C.R3,"fd",C.cJ,"fetchInboundReferences",C.WQ,"field",C.fV,"fields",C.jU,"file",C.OO,"flag",C.Mc,"flagList",C.FP,"formatSize",C.kF,"formatTime",C.UD,"formattedAddress",C.Aq,"formattedAverage",C.DS,"formattedCollections",C.C9,"formattedDeoptId",C.VF,"formattedExclusive",C.uU,"formattedExclusiveTicks",C.YJ,"formattedInclusive",C.EF,"formattedInclusiveTicks",C.oI,"formattedLine",C.ST,"formattedTotalCollectionTime",C.QH,"fragmentation",C.qX,"fragmentationChanged",C.rE,"frame",C.nf,"function",C.EI,"functions",C.JB,"getColumnLabel",C.RY,"getTabs",C.d4,"goto",C.cF,"gotoLink",C.ft,"guardClass",C.dr,"guardNullable",C.SI,"hasDescriptors",C.zS,"hasDisassembly",C.YA,"hasNoAllocations",C.Ge,"hashLinkWorkaround",C.A7,"height",C.He,"hideTagsChecked",C.im,"history",C.Ss,"hits",C.k6,"hoverText",C.oj,"httpServer",C.PJ,"human",C.Yb,"id",C.q2,"idle",C.d2,"imp",C.kN,"imports",C.uO,"inboundReferences",C.fn,"instance",C.yB,"instances",C.eJ,"instruction",C.iG,"instructions",C.Py,"interface",C.pC,"interfaces",C.uu,"internal",C.qs,"io",C.XH,"isAbstract",C.XJ,"isAbstractType",C.tJ,"isBool",C.F8,"isChromeTarget",C.fy,"isClosure",C.C1,"isComment",C.Nr,"isConst",C.nL,"isCurrentTarget",C.a0,"isDart",C.Yg,"isDartCode",C.bR,"isDouble",C.ai,"isEmpty",C.ob,"isError",C.dR,"isFinal",C.MY,"isInlinable",C.Wg,"isInt",C.tD,"isList",C.QS,"isMap",C.C7,"isMirrorReference",C.nZ,"isNotEmpty",C.Of,"isNull",C.Vl,"isOptimizable",C.pY,"isOptimized",C.XL,"isPatch",C.LA,"isPipe",C.Iw,"isPlainInstance",C.tz,"isSentinel",C.AT,"isStatic",C.Lk,"isString",C.GS,"isWeakProperty",C.rB,"isolate",C.bz,"isolateChanged",C.Jx,"isolates",C.b5,"jumpTarget",C.z6,"key",C.SY,"keys",C.Lc,"kind",C.hf,"label",C.uk,"last",C.Zi,"lastAccumulatorReset",C.TN,"lastServiceGC",C.GI,"lastUpdate",C.Wn,"length",C.ur,"lib",C.VN,"libraries",C.EV,"library",C.VI,"line",C.eh,"lineMode",C.SA,"lines",C.uG,"linesReady",C.kV,"link",C.vp,"list",C.cc,"listening",C.DY,"loading",C.Lx,"localAddress",C.M3,"localPort",C.wT,"mainPort",C.JK,"makeLineId",C.SR,"map",C.t6,"mapAsString",C.rP,"mapChanged",C.qi,"max",C.pX,"message",C.kB,"metric",C.LH,"metricChanged",C.a2,"min",C.VD,"mouseOut",C.NN,"mouseOver",C.UX,"msg",C.YS,"name",C.pu,"nameIsEmpty",C.uw,"nativeFields",C.BJ,"newSpace",C.c6,"notifications",C.td,"object",C.Gn,"objectChanged",C.zO,"objectPool",C.vg,"oldSpace",C.Yp,"owner",C.YV,"owningClass",C.If,"owningLibrary",C.Ys,"pad",C.zm,"padding",C.EP,"page",C.nX,"parent",C.BV,"parentContext",C.xP,"parseInt",C.XM,"path",C.Ic,"pause",C.yG,"pauseEvent",C.uI,"pid",C.O9,"pollPeriod",C.ba,"pollPeriodChanged",C.tW,"pos",C.CG,"posChanged",C.Jf,"possibleBpt",C.Wj,"process",C.vb,"profile",C.UL,"profileChanged",C.AY,"protocol",C.QK,"qualified",C.AO,"qualifiedName",C.Xd,"reachable",C.I7,"readClosed",C.kY,"ref",C.Wm,"refChanged",C.vK,"reference",C.Tc,"referent",C.GR,"refresh",C.KX,"refreshCoverage",C.ja,"refreshGC",C.mn,"refreshRateChange",C.Dj,"refreshTime",C.ir,"relativeLink",C.dx,"remoteAddress",C.ni,"remotePort",C.X2,"resetAccumulator",C.F3,"response",C.UY,"result",C.Aa,"results",C.nY,"resume",C.tg,"retainedBytes",C.HD,"retainedSize",C.iU,"retainingPath",C.eN,"rootLib",C.ue,"row",C.nh,"rows",C.L2,"running",C.vm,"sampleBufferSizeChange",C.Gs,"sampleCount",C.bE,"sampleDepth",C.YD,"sampleRate",C.PX,"script",C.N8,"scriptChanged",C.FQ,"scriptHeight",C.EA,"scripts",C.oW,"selectExpr",C.KC,"selectMetric",C.tf,"selectedMetric",C.TI,"showConsole",C.da,"size",C.Jd,"slot",C.Y4,"slotIsArrayIndex",C.Si,"slotIsField",C.pH,"small",C.Ve,"socket",C.jM,"socketOwner",C.rd,"source",C.rX,"stack",C.W5,"standalone",C.uX,"standaloneVmAddress",C.nt,"startLine",C.IT,"startPos",C.li,"startPosChanged",C.PM,"status",C.ks,"stepInto",C.Om,"stepOut",C.iC,"stepOver",C.Nv,"subclass",C.Wo,"subclasses",C.FZ,"superclass",C.TW,"tagSelector",C.xS,"tagSelectorChanged",C.pD,"target",C.QF,"targets",C.mi,"text",C.zz,"timeSpan",C.eO,"timeStamp",C.hO,"tipExclusive",C.ei,"tipKind",C.HK,"tipParent",C.je,"tipTicks",C.Ef,"tipTime",C.QL,"toString",C.RH,"toStringAsFixed",C.SP,"toggleBreakpoint",C.Q1,"toggleExpand",C.ID,"toggleExpanded",C.dA,"tokenPos",C.bc,"topFrame",C.nE,"tracer",C.ep,"tree",C.hB,"type",C.J2,"typeChecksEnabled",C.hx,"typeClass",C.zU,"uncheckedText",C.OU,"unoptimizedCode",C.bn,"updateLineMode",C.mh,"uptime",C.Fh,"url",C.yv,"usageCounter",C.LP,"used",C.jh,"v",C.zd,"value",C.Db,"valueAsString",C.aF,"valueAsStringIsTruncated",C.l4,"values",C.fj,"variable",C.xw,"variables",C.zn,"version",C.RJ,"vm",C.Sk,"vmMetrics",C.KS,"vmName",C.MA,"vmType",C.YE,"webSocket",C.Uy,"writeClosed"],null,null),x,y,null)
 $.j8=new O.fH(y)
 $.Yv=new O.mO(y)
 $.qe=new O.ut(y)
-$.MU=[new E.e455(),new E.e456(),new E.e457(),new E.e458(),new E.e459(),new E.e460(),new E.e461(),new E.e462(),new E.e463(),new E.e464(),new E.e465(),new E.e466(),new E.e467(),new E.e468(),new E.e469(),new E.e470(),new E.e471(),new E.e472(),new E.e473(),new E.e474(),new E.e475(),new E.e476(),new E.e477(),new E.e478(),new E.e479(),new E.e480(),new E.e481(),new E.e482(),new E.e483(),new E.e484(),new E.e485(),new E.e486(),new E.e487(),new E.e488(),new E.e489(),new E.e490(),new E.e491(),new E.e492(),new E.e493(),new E.e494(),new E.e495(),new E.e496(),new E.e497(),new E.e498(),new E.e499(),new E.e500(),new E.e501(),new E.e502(),new E.e503(),new E.e504(),new E.e505(),new E.e506(),new E.e507(),new E.e508(),new E.e509(),new E.e510(),new E.e511(),new E.e512(),new E.e513(),new E.e514(),new E.e515(),new E.e516(),new E.e517(),new E.e518(),new E.e519(),new E.e520(),new E.e521(),new E.e522(),new E.e523(),new E.e524(),new E.e525(),new E.e526(),new E.e527(),new E.e528(),new E.e529(),new E.e530(),new E.e531(),new E.e532(),new E.e533(),new E.e534(),new E.e535(),new E.e536(),new E.e537(),new E.e538(),new E.e539(),new E.e540(),new E.e541(),new E.e542(),new E.e543(),new E.e544(),new E.e545(),new E.e546(),new E.e547(),new E.e548(),new E.e549(),new E.e550()]
+$.MU=[new E.e457(),new E.e458(),new E.e459(),new E.e460(),new E.e461(),new E.e462(),new E.e463(),new E.e464(),new E.e465(),new E.e466(),new E.e467(),new E.e468(),new E.e469(),new E.e470(),new E.e471(),new E.e472(),new E.e473(),new E.e474(),new E.e475(),new E.e476(),new E.e477(),new E.e478(),new E.e479(),new E.e480(),new E.e481(),new E.e482(),new E.e483(),new E.e484(),new E.e485(),new E.e486(),new E.e487(),new E.e488(),new E.e489(),new E.e490(),new E.e491(),new E.e492(),new E.e493(),new E.e494(),new E.e495(),new E.e496(),new E.e497(),new E.e498(),new E.e499(),new E.e500(),new E.e501(),new E.e502(),new E.e503(),new E.e504(),new E.e505(),new E.e506(),new E.e507(),new E.e508(),new E.e509(),new E.e510(),new E.e511(),new E.e512(),new E.e513(),new E.e514(),new E.e515(),new E.e516(),new E.e517(),new E.e518(),new E.e519(),new E.e520(),new E.e521(),new E.e522(),new E.e523(),new E.e524(),new E.e525(),new E.e526(),new E.e527(),new E.e528(),new E.e529(),new E.e530(),new E.e531(),new E.e532(),new E.e533(),new E.e534(),new E.e535(),new E.e536(),new E.e537(),new E.e538(),new E.e539(),new E.e540(),new E.e541(),new E.e542(),new E.e543(),new E.e544(),new E.e545(),new E.e546(),new E.e547(),new E.e548(),new E.e549(),new E.e550(),new E.e551(),new E.e552()]
 $.UG=!0
 F.E2()},"$0","VQk",0,0,1],
 L:{
@@ -2687,1704 +2687,1710 @@
 $1:[function(a){return a.gA3()},"$1",null,2,0,null,65,"call"]},
 ed:{
 "^":"r:14;",
-$1:[function(a){return a.goX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dX(a)},"$1",null,2,0,null,65,"call"]},
 wa:{
 "^":"r:14;",
-$1:[function(a){return a.gqr()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.goX()},"$1",null,2,0,null,65,"call"]},
 Or:{
 "^":"r:14;",
-$1:[function(a){return a.gYZ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gqr()},"$1",null,2,0,null,65,"call"]},
 YL:{
 "^":"r:14;",
-$1:[function(a){return J.zL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gYZ()},"$1",null,2,0,null,65,"call"]},
 wf:{
 "^":"r:14;",
-$1:[function(a){return J.aAQ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zL(a)},"$1",null,2,0,null,65,"call"]},
 Oa:{
 "^":"r:14;",
-$1:[function(a){return a.gET()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.aAQ(a)},"$1",null,2,0,null,65,"call"]},
 emv:{
 "^":"r:14;",
-$1:[function(a){return J.WT(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gET()},"$1",null,2,0,null,65,"call"]},
 Lbd:{
 "^":"r:14;",
-$1:[function(a){return a.gCs()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WT(a)},"$1",null,2,0,null,65,"call"]},
 QAa:{
 "^":"r:14;",
-$1:[function(a){return J.XB(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gCs()},"$1",null,2,0,null,65,"call"]},
 CvS:{
 "^":"r:14;",
-$1:[function(a){return J.n9(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.XB(a)},"$1",null,2,0,null,65,"call"]},
 edy:{
 "^":"r:14;",
-$1:[function(a){return J.rp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.n9(a)},"$1",null,2,0,null,65,"call"]},
 waE:{
 "^":"r:14;",
-$1:[function(a){return J.BS2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.rp(a)},"$1",null,2,0,null,65,"call"]},
 Ore:{
 "^":"r:14;",
-$1:[function(a){return J.LL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.BS2(a)},"$1",null,2,0,null,65,"call"]},
 YLa:{
 "^":"r:14;",
-$1:[function(a){return J.h3(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.LL(a)},"$1",null,2,0,null,65,"call"]},
 wfa:{
 "^":"r:14;",
-$1:[function(a){return J.AJ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.h3(a)},"$1",null,2,0,null,65,"call"]},
 Oaa:{
 "^":"r:14;",
-$1:[function(a){return J.pP(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.AJ(a)},"$1",null,2,0,null,65,"call"]},
 e0:{
 "^":"r:14;",
-$1:[function(a){return a.gUP()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pP(a)},"$1",null,2,0,null,65,"call"]},
 e1:{
 "^":"r:14;",
-$1:[function(a){return J.RC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUP()},"$1",null,2,0,null,65,"call"]},
 e2:{
 "^":"r:14;",
-$1:[function(a){return a.gSf()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.RC(a)},"$1",null,2,0,null,65,"call"]},
 e3:{
 "^":"r:14;",
-$1:[function(a){return a.gu5()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSf()},"$1",null,2,0,null,65,"call"]},
 e4:{
 "^":"r:14;",
-$1:[function(a){return a.gwz()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gu5()},"$1",null,2,0,null,65,"call"]},
 e5:{
 "^":"r:14;",
-$1:[function(a){return J.L6(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gwz()},"$1",null,2,0,null,65,"call"]},
 e6:{
 "^":"r:14;",
-$1:[function(a){return J.tX(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.L6(a)},"$1",null,2,0,null,65,"call"]},
 e7:{
 "^":"r:14;",
-$1:[function(a){return J.zF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.tX(a)},"$1",null,2,0,null,65,"call"]},
 e8:{
 "^":"r:14;",
-$1:[function(a){return J.lK(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zF(a)},"$1",null,2,0,null,65,"call"]},
 e9:{
 "^":"r:14;",
-$1:[function(a){return J.Al(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.lK(a)},"$1",null,2,0,null,65,"call"]},
 e10:{
 "^":"r:14;",
-$1:[function(a){return J.Mh(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Al(a)},"$1",null,2,0,null,65,"call"]},
 e11:{
 "^":"r:14;",
-$1:[function(a){return J.nC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Mh(a)},"$1",null,2,0,null,65,"call"]},
 e12:{
 "^":"r:14;",
-$1:[function(a){return J.xe(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.nC(a)},"$1",null,2,0,null,65,"call"]},
 e13:{
 "^":"r:14;",
-$1:[function(a){return J.Ux(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.xe(a)},"$1",null,2,0,null,65,"call"]},
 e14:{
 "^":"r:14;",
-$1:[function(a){return J.OT(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ux(a)},"$1",null,2,0,null,65,"call"]},
 e15:{
 "^":"r:14;",
-$1:[function(a){return J.Okq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.OT(a)},"$1",null,2,0,null,65,"call"]},
 e16:{
 "^":"r:14;",
-$1:[function(a){return a.gk()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Okq(a)},"$1",null,2,0,null,65,"call"]},
 e17:{
 "^":"r:14;",
-$1:[function(a){return J.h6(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gk()},"$1",null,2,0,null,65,"call"]},
 e18:{
 "^":"r:14;",
-$1:[function(a){return J.kc(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.h6(a)},"$1",null,2,0,null,65,"call"]},
 e19:{
 "^":"r:14;",
-$1:[function(a){return J.P3(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.kc(a)},"$1",null,2,0,null,65,"call"]},
 e20:{
 "^":"r:14;",
-$1:[function(a){return a.gpG()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.P3(a)},"$1",null,2,0,null,65,"call"]},
 e21:{
 "^":"r:14;",
-$1:[function(a){return a.gOF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gpG()},"$1",null,2,0,null,65,"call"]},
 e22:{
 "^":"r:14;",
-$1:[function(a){return J.TG(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gOF()},"$1",null,2,0,null,65,"call"]},
 e23:{
 "^":"r:14;",
-$1:[function(a){return a.gOs()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.TG(a)},"$1",null,2,0,null,65,"call"]},
 e24:{
 "^":"r:14;",
-$1:[function(a){return a.gN0()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gOs()},"$1",null,2,0,null,65,"call"]},
 e25:{
 "^":"r:14;",
-$1:[function(a){return a.gSL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gN0()},"$1",null,2,0,null,65,"call"]},
 e26:{
 "^":"r:14;",
-$1:[function(a){return a.guH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSL()},"$1",null,2,0,null,65,"call"]},
 e27:{
 "^":"r:14;",
-$1:[function(a){return J.mP(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.guH()},"$1",null,2,0,null,65,"call"]},
 e28:{
 "^":"r:14;",
-$1:[function(a){return J.fe(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.mP(a)},"$1",null,2,0,null,65,"call"]},
 e29:{
 "^":"r:14;",
-$1:[function(a){return J.dn(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fe(a)},"$1",null,2,0,null,65,"call"]},
 e30:{
 "^":"r:14;",
-$1:[function(a){return J.y3(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dn(a)},"$1",null,2,0,null,65,"call"]},
 e31:{
 "^":"r:14;",
-$1:[function(a){return J.YH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.y3(a)},"$1",null,2,0,null,65,"call"]},
 e32:{
 "^":"r:14;",
-$1:[function(a){return J.k0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.YH(a)},"$1",null,2,0,null,65,"call"]},
 e33:{
 "^":"r:14;",
-$1:[function(a){return J.yr(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.k0(a)},"$1",null,2,0,null,65,"call"]},
 e34:{
 "^":"r:14;",
-$1:[function(a){return J.lk(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.yr(a)},"$1",null,2,0,null,65,"call"]},
 e35:{
 "^":"r:14;",
-$1:[function(a){return a.gLK()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.lk(a)},"$1",null,2,0,null,65,"call"]},
 e36:{
 "^":"r:14;",
-$1:[function(a){return a.gw2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gLK()},"$1",null,2,0,null,65,"call"]},
 e37:{
 "^":"r:14;",
-$1:[function(a){return J.w8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gw2()},"$1",null,2,0,null,65,"call"]},
 e38:{
 "^":"r:14;",
-$1:[function(a){return J.ht(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.w8(a)},"$1",null,2,0,null,65,"call"]},
 e39:{
 "^":"r:14;",
-$1:[function(a){return J.Pp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ht(a)},"$1",null,2,0,null,65,"call"]},
 e40:{
 "^":"r:14;",
-$1:[function(a){return J.qf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Pp(a)},"$1",null,2,0,null,65,"call"]},
 e41:{
 "^":"r:14;",
-$1:[function(a){return J.Ts(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.qf(a)},"$1",null,2,0,null,65,"call"]},
 e42:{
 "^":"r:14;",
-$1:[function(a){return J.um(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ts(a)},"$1",null,2,0,null,65,"call"]},
 e43:{
 "^":"r:14;",
-$1:[function(a){return J.io(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.um(a)},"$1",null,2,0,null,65,"call"]},
 e44:{
 "^":"r:14;",
-$1:[function(a){return J.UE(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.io(a)},"$1",null,2,0,null,65,"call"]},
 e45:{
 "^":"r:14;",
-$1:[function(a){return J.Ak(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.UE(a)},"$1",null,2,0,null,65,"call"]},
 e46:{
 "^":"r:14;",
-$1:[function(a){return J.IL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ak(a)},"$1",null,2,0,null,65,"call"]},
 e47:{
 "^":"r:14;",
-$1:[function(a){return J.nb(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.IL(a)},"$1",null,2,0,null,65,"call"]},
 e48:{
 "^":"r:14;",
-$1:[function(a){return a.gty()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.nb(a)},"$1",null,2,0,null,65,"call"]},
 e49:{
 "^":"r:14;",
-$1:[function(a){return J.Ua(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gty()},"$1",null,2,0,null,65,"call"]},
 e50:{
 "^":"r:14;",
-$1:[function(a){return a.gMX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ua(a)},"$1",null,2,0,null,65,"call"]},
 e51:{
 "^":"r:14;",
-$1:[function(a){return a.gkE()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gMX()},"$1",null,2,0,null,65,"call"]},
 e52:{
 "^":"r:14;",
-$1:[function(a){return J.E1(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkE()},"$1",null,2,0,null,65,"call"]},
 e53:{
 "^":"r:14;",
-$1:[function(a){return J.Nb(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.E1(a)},"$1",null,2,0,null,65,"call"]},
 e54:{
 "^":"r:14;",
-$1:[function(a){return a.gtJ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Nb(a)},"$1",null,2,0,null,65,"call"]},
 e55:{
 "^":"r:14;",
-$1:[function(a){return J.vE(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gtJ()},"$1",null,2,0,null,65,"call"]},
 e56:{
 "^":"r:14;",
-$1:[function(a){return J.dw(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.vE(a)},"$1",null,2,0,null,65,"call"]},
 e57:{
 "^":"r:14;",
-$1:[function(a){return J.QZ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dw(a)},"$1",null,2,0,null,65,"call"]},
 e58:{
 "^":"r:14;",
-$1:[function(a){return J.WX7(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QZ(a)},"$1",null,2,0,null,65,"call"]},
 e59:{
 "^":"r:14;",
-$1:[function(a){return J.QvL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WX7(a)},"$1",null,2,0,null,65,"call"]},
 e60:{
 "^":"r:14;",
-$1:[function(a){return a.gZd()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QvL(a)},"$1",null,2,0,null,65,"call"]},
 e61:{
 "^":"r:14;",
-$1:[function(a){return J.TM(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZd()},"$1",null,2,0,null,65,"call"]},
 e62:{
 "^":"r:14;",
-$1:[function(a){return J.xo(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.TM(a)},"$1",null,2,0,null,65,"call"]},
 e63:{
 "^":"r:14;",
-$1:[function(a){return a.gkA()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.xo(a)},"$1",null,2,0,null,65,"call"]},
 e64:{
 "^":"r:14;",
-$1:[function(a){return a.gAX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkA()},"$1",null,2,0,null,65,"call"]},
 e65:{
 "^":"r:14;",
-$1:[function(a){return a.ga3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gAX()},"$1",null,2,0,null,65,"call"]},
 e66:{
 "^":"r:14;",
-$1:[function(a){return a.gcQ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.ga3()},"$1",null,2,0,null,65,"call"]},
 e67:{
 "^":"r:14;",
-$1:[function(a){return a.gS7()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gcQ()},"$1",null,2,0,null,65,"call"]},
 e68:{
 "^":"r:14;",
-$1:[function(a){return a.gP3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gS7()},"$1",null,2,0,null,65,"call"]},
 e69:{
 "^":"r:14;",
-$1:[function(a){return J.wm(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gP3()},"$1",null,2,0,null,65,"call"]},
 e70:{
 "^":"r:14;",
-$1:[function(a){return J.bu(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wm(a)},"$1",null,2,0,null,65,"call"]},
 e71:{
 "^":"r:14;",
-$1:[function(a){return J.iq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.bu(a)},"$1",null,2,0,null,65,"call"]},
 e72:{
 "^":"r:14;",
-$1:[function(a){return J.zN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.iq(a)},"$1",null,2,0,null,65,"call"]},
 e73:{
 "^":"r:14;",
-$1:[function(a){return J.m4(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zN(a)},"$1",null,2,0,null,65,"call"]},
 e74:{
 "^":"r:14;",
-$1:[function(a){return a.gjV()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.m4(a)},"$1",null,2,0,null,65,"call"]},
 e75:{
 "^":"r:14;",
-$1:[function(a){return a.gCO()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gjV()},"$1",null,2,0,null,65,"call"]},
 e76:{
 "^":"r:14;",
-$1:[function(a){return J.yf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gCO()},"$1",null,2,0,null,65,"call"]},
 e77:{
 "^":"r:14;",
-$1:[function(a){return J.i2U(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.yf(a)},"$1",null,2,0,null,65,"call"]},
 e78:{
 "^":"r:14;",
-$1:[function(a){return J.Ay(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.i2U(a)},"$1",null,2,0,null,65,"call"]},
 e79:{
 "^":"r:14;",
-$1:[function(a){return a.gZD()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ay(a)},"$1",null,2,0,null,65,"call"]},
 e80:{
 "^":"r:14;",
-$1:[function(a){return a.gRl()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZD()},"$1",null,2,0,null,65,"call"]},
 e81:{
 "^":"r:14;",
-$1:[function(a){return a.gvN()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gRl()},"$1",null,2,0,null,65,"call"]},
 e82:{
 "^":"r:14;",
-$1:[function(a){return a.gUa()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvN()},"$1",null,2,0,null,65,"call"]},
 e83:{
 "^":"r:14;",
-$1:[function(a){return a.gMp()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUa()},"$1",null,2,0,null,65,"call"]},
 e84:{
 "^":"r:14;",
-$1:[function(a){return J.Er(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gMp()},"$1",null,2,0,null,65,"call"]},
 e85:{
 "^":"r:14;",
-$1:[function(a){return J.Jv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Er(a)},"$1",null,2,0,null,65,"call"]},
 e86:{
 "^":"r:14;",
-$1:[function(a){return J.z8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Jv(a)},"$1",null,2,0,null,65,"call"]},
 e87:{
 "^":"r:14;",
-$1:[function(a){return J.Xf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.z8(a)},"$1",null,2,0,null,65,"call"]},
 e88:{
 "^":"r:14;",
-$1:[function(a){return a.gc1()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Xf(a)},"$1",null,2,0,null,65,"call"]},
 e89:{
 "^":"r:14;",
-$1:[function(a){return J.aW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gc1()},"$1",null,2,0,null,65,"call"]},
 e90:{
 "^":"r:14;",
-$1:[function(a){return J.hW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.aW(a)},"$1",null,2,0,null,65,"call"]},
 e91:{
 "^":"r:14;",
-$1:[function(a){return a.gu0()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.hW(a)},"$1",null,2,0,null,65,"call"]},
 e92:{
 "^":"r:14;",
-$1:[function(a){return J.eS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gu0()},"$1",null,2,0,null,65,"call"]},
 e93:{
 "^":"r:14;",
-$1:[function(a){return a.gaj()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.eS(a)},"$1",null,2,0,null,65,"call"]},
 e94:{
 "^":"r:14;",
-$1:[function(a){return a.giq()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gaj()},"$1",null,2,0,null,65,"call"]},
 e95:{
 "^":"r:14;",
-$1:[function(a){return a.gPb()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.giq()},"$1",null,2,0,null,65,"call"]},
 e96:{
 "^":"r:14;",
-$1:[function(a){return J.tl(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gPb()},"$1",null,2,0,null,65,"call"]},
 e97:{
 "^":"r:14;",
-$1:[function(a){return J.Ir(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.tl(a)},"$1",null,2,0,null,65,"call"]},
 e98:{
 "^":"r:14;",
-$1:[function(a){return J.US(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ir(a)},"$1",null,2,0,null,65,"call"]},
 e99:{
 "^":"r:14;",
-$1:[function(a){return a.gNI()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.US(a)},"$1",null,2,0,null,65,"call"]},
 e100:{
 "^":"r:14;",
-$1:[function(a){return a.gGA()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gNI()},"$1",null,2,0,null,65,"call"]},
 e101:{
 "^":"r:14;",
-$1:[function(a){return a.gKt()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gGA()},"$1",null,2,0,null,65,"call"]},
 e102:{
 "^":"r:14;",
-$1:[function(a){return a.gp2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gKt()},"$1",null,2,0,null,65,"call"]},
 e103:{
 "^":"r:14;",
-$1:[function(a){return J.oH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gp2()},"$1",null,2,0,null,65,"call"]},
 e104:{
 "^":"r:14;",
-$1:[function(a){return J.Ew(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.oH(a)},"$1",null,2,0,null,65,"call"]},
 e105:{
 "^":"r:14;",
-$1:[function(a){return a.gvo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ew(a)},"$1",null,2,0,null,65,"call"]},
 e106:{
 "^":"r:14;",
-$1:[function(a){return a.glO()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvo()},"$1",null,2,0,null,65,"call"]},
 e107:{
 "^":"r:14;",
-$1:[function(a){return a.gjS()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.glO()},"$1",null,2,0,null,65,"call"]},
 e108:{
 "^":"r:14;",
-$1:[function(a){return J.v9(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gjS()},"$1",null,2,0,null,65,"call"]},
 e109:{
 "^":"r:14;",
-$1:[function(a){return a.gBF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.v9(a)},"$1",null,2,0,null,65,"call"]},
 e110:{
 "^":"r:14;",
-$1:[function(a){return a.gUB()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gBF()},"$1",null,2,0,null,65,"call"]},
 e111:{
 "^":"r:14;",
-$1:[function(a){return a.gRh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUB()},"$1",null,2,0,null,65,"call"]},
 e112:{
 "^":"r:14;",
-$1:[function(a){return J.id(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gRh()},"$1",null,2,0,null,65,"call"]},
 e113:{
 "^":"r:14;",
-$1:[function(a){return a.gni()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.id(a)},"$1",null,2,0,null,65,"call"]},
 e114:{
 "^":"r:14;",
-$1:[function(a){return a.gkU()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gni()},"$1",null,2,0,null,65,"call"]},
 e115:{
 "^":"r:14;",
-$1:[function(a){return a.gzx()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkU()},"$1",null,2,0,null,65,"call"]},
 e116:{
 "^":"r:14;",
-$1:[function(a){return J.FN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gzx()},"$1",null,2,0,null,65,"call"]},
 e117:{
 "^":"r:14;",
-$1:[function(a){return a.gt3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.FN(a)},"$1",null,2,0,null,65,"call"]},
 e118:{
 "^":"r:14;",
-$1:[function(a){return J.or(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gt3()},"$1",null,2,0,null,65,"call"]},
 e119:{
 "^":"r:14;",
-$1:[function(a){return a.gxL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.or(a)},"$1",null,2,0,null,65,"call"]},
 e120:{
 "^":"r:14;",
-$1:[function(a){return a.gSO()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gxL()},"$1",null,2,0,null,65,"call"]},
 e121:{
 "^":"r:14;",
-$1:[function(a){return J.Zo(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSO()},"$1",null,2,0,null,65,"call"]},
 e122:{
 "^":"r:14;",
-$1:[function(a){return J.GGs(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zo(a)},"$1",null,2,0,null,65,"call"]},
 e123:{
 "^":"r:14;",
-$1:[function(a){return a.gOC()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.GGs(a)},"$1",null,2,0,null,65,"call"]},
 e124:{
 "^":"r:14;",
-$1:[function(a){return J.pO(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gOC()},"$1",null,2,0,null,65,"call"]},
 e125:{
 "^":"r:14;",
-$1:[function(a){return a.gHh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pO(a)},"$1",null,2,0,null,65,"call"]},
 e126:{
 "^":"r:14;",
-$1:[function(a){return a.gW1()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gHh()},"$1",null,2,0,null,65,"call"]},
 e127:{
 "^":"r:14;",
-$1:[function(a){return a.goF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gW1()},"$1",null,2,0,null,65,"call"]},
 e128:{
 "^":"r:14;",
-$1:[function(a){return a.geh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.goF()},"$1",null,2,0,null,65,"call"]},
 e129:{
 "^":"r:14;",
-$1:[function(a){return a.gHY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.geh()},"$1",null,2,0,null,65,"call"]},
 e130:{
 "^":"r:14;",
-$1:[function(a){return a.gXM()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gHY()},"$1",null,2,0,null,65,"call"]},
 e131:{
 "^":"r:14;",
-$1:[function(a){return a.gfo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gXM()},"$1",null,2,0,null,65,"call"]},
 e132:{
 "^":"r:14;",
-$1:[function(a){return a.gFo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gfo()},"$1",null,2,0,null,65,"call"]},
 e133:{
 "^":"r:14;",
-$1:[function(a){return a.gu7()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gFo()},"$1",null,2,0,null,65,"call"]},
 e134:{
 "^":"r:14;",
-$1:[function(a){return a.gl2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gu7()},"$1",null,2,0,null,65,"call"]},
 e135:{
 "^":"r:14;",
-$1:[function(a){return J.wg(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gl2()},"$1",null,2,0,null,65,"call"]},
 e136:{
 "^":"r:14;",
-$1:[function(a){return J.q0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wg(a)},"$1",null,2,0,null,65,"call"]},
 e137:{
 "^":"r:14;",
-$1:[function(a){return a.gi2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.q0(a)},"$1",null,2,0,null,65,"call"]},
 e138:{
 "^":"r:14;",
-$1:[function(a){return a.gSS()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gi2()},"$1",null,2,0,null,65,"call"]},
 e139:{
 "^":"r:14;",
-$1:[function(a){return J.Kt(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSS()},"$1",null,2,0,null,65,"call"]},
 e140:{
 "^":"r:14;",
-$1:[function(a){return J.q8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Kt(a)},"$1",null,2,0,null,65,"call"]},
 e141:{
 "^":"r:14;",
-$1:[function(a){return J.Iz(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.q8(a)},"$1",null,2,0,null,65,"call"]},
 e142:{
 "^":"r:14;",
-$1:[function(a){return J.ZC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Iz(a)},"$1",null,2,0,null,65,"call"]},
 e143:{
 "^":"r:14;",
-$1:[function(a){return J.rn(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ZC(a)},"$1",null,2,0,null,65,"call"]},
 e144:{
 "^":"r:14;",
-$1:[function(a){return J.X7(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.rn(a)},"$1",null,2,0,null,65,"call"]},
 e145:{
 "^":"r:14;",
-$1:[function(a){return J.IR(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.X7(a)},"$1",null,2,0,null,65,"call"]},
 e146:{
 "^":"r:14;",
-$1:[function(a){return a.gPE()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.IR(a)},"$1",null,2,0,null,65,"call"]},
 e147:{
 "^":"r:14;",
-$1:[function(a){return J.wS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gPE()},"$1",null,2,0,null,65,"call"]},
 e148:{
 "^":"r:14;",
-$1:[function(a){return a.gcI()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wS(a)},"$1",null,2,0,null,65,"call"]},
 e149:{
 "^":"r:14;",
-$1:[function(a){return a.gvU()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gcI()},"$1",null,2,0,null,65,"call"]},
 e150:{
 "^":"r:14;",
-$1:[function(a){return J.ik(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvU()},"$1",null,2,0,null,65,"call"]},
 e151:{
 "^":"r:14;",
-$1:[function(a){return J.f2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ik(a)},"$1",null,2,0,null,65,"call"]},
 e152:{
 "^":"r:14;",
-$1:[function(a){return J.zY(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.f2(a)},"$1",null,2,0,null,65,"call"]},
 e153:{
 "^":"r:14;",
-$1:[function(a){return J.de(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zY(a)},"$1",null,2,0,null,65,"call"]},
 e154:{
 "^":"r:14;",
-$1:[function(a){return J.t0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.de(a)},"$1",null,2,0,null,65,"call"]},
 e155:{
 "^":"r:14;",
-$1:[function(a){return J.Ds(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.t0(a)},"$1",null,2,0,null,65,"call"]},
 e156:{
 "^":"r:14;",
-$1:[function(a){return J.cO(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ds(a)},"$1",null,2,0,null,65,"call"]},
 e157:{
 "^":"r:14;",
-$1:[function(a){return a.gzM()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.cO(a)},"$1",null,2,0,null,65,"call"]},
 e158:{
 "^":"r:14;",
-$1:[function(a){return a.gn0()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gzM()},"$1",null,2,0,null,65,"call"]},
 e159:{
 "^":"r:14;",
-$1:[function(a){return a.giP()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gn0()},"$1",null,2,0,null,65,"call"]},
 e160:{
 "^":"r:14;",
-$1:[function(a){return a.gmd()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.giP()},"$1",null,2,0,null,65,"call"]},
 e161:{
 "^":"r:14;",
-$1:[function(a){return a.gIT()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gmd()},"$1",null,2,0,null,65,"call"]},
 e162:{
 "^":"r:14;",
-$1:[function(a){return J.pr(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gIT()},"$1",null,2,0,null,65,"call"]},
 e163:{
 "^":"r:14;",
-$1:[function(a){return J.Yf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pr(a)},"$1",null,2,0,null,65,"call"]},
 e164:{
 "^":"r:14;",
-$1:[function(a){return J.kv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Yf(a)},"$1",null,2,0,null,65,"call"]},
 e165:{
 "^":"r:14;",
-$1:[function(a){return J.QD(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.kv(a)},"$1",null,2,0,null,65,"call"]},
 e166:{
 "^":"r:14;",
-$1:[function(a){return J.jE(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QD(a)},"$1",null,2,0,null,65,"call"]},
 e167:{
 "^":"r:14;",
-$1:[function(a){return J.Oh(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jE(a)},"$1",null,2,0,null,65,"call"]},
 e168:{
 "^":"r:14;",
-$1:[function(a){return J.qx(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Oh(a)},"$1",null,2,0,null,65,"call"]},
 e169:{
 "^":"r:14;",
-$1:[function(a){return J.Kv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.qx(a)},"$1",null,2,0,null,65,"call"]},
 e170:{
 "^":"r:14;",
-$1:[function(a){return J.LY4(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Kv(a)},"$1",null,2,0,null,65,"call"]},
 e171:{
 "^":"r:14;",
-$1:[function(a){return J.ZF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.LY4(a)},"$1",null,2,0,null,65,"call"]},
 e172:{
 "^":"r:14;",
-$1:[function(a){return J.PW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ZF(a)},"$1",null,2,0,null,65,"call"]},
 e173:{
 "^":"r:14;",
-$1:[function(a){return J.Zv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.PW(a)},"$1",null,2,0,null,65,"call"]},
 e174:{
 "^":"r:14;",
-$1:[function(a){return J.DA(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zv(a)},"$1",null,2,0,null,65,"call"]},
 e175:{
 "^":"r:14;",
-$1:[function(a){return J.Pf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.DA(a)},"$1",null,2,0,null,65,"call"]},
 e176:{
 "^":"r:14;",
-$1:[function(a){return a.gDm()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Pf(a)},"$1",null,2,0,null,65,"call"]},
 e177:{
 "^":"r:14;",
-$1:[function(a){return a.gUY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gDm()},"$1",null,2,0,null,65,"call"]},
 e178:{
 "^":"r:14;",
-$1:[function(a){return a.gvK()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUY()},"$1",null,2,0,null,65,"call"]},
 e179:{
 "^":"r:14;",
-$1:[function(a){return J.mk(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvK()},"$1",null,2,0,null,65,"call"]},
 e180:{
 "^":"r:14;",
-$1:[function(a){return J.t8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.mk(a)},"$1",null,2,0,null,65,"call"]},
 e181:{
 "^":"r:14;",
-$1:[function(a){return a.gL1()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.t8(a)},"$1",null,2,0,null,65,"call"]},
 e182:{
 "^":"r:14;",
-$1:[function(a){return a.gxQ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gL1()},"$1",null,2,0,null,65,"call"]},
 e183:{
 "^":"r:14;",
-$1:[function(a){return a.gXP()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gxQ()},"$1",null,2,0,null,65,"call"]},
 e184:{
 "^":"r:14;",
-$1:[function(a){return a.gP2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gXP()},"$1",null,2,0,null,65,"call"]},
 e185:{
 "^":"r:14;",
-$1:[function(a){return a.gxH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gP2()},"$1",null,2,0,null,65,"call"]},
 e186:{
 "^":"r:14;",
-$1:[function(a){return J.qN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gxH()},"$1",null,2,0,null,65,"call"]},
 e187:{
 "^":"r:14;",
-$1:[function(a){return J.mF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.qN(a)},"$1",null,2,0,null,65,"call"]},
 e188:{
 "^":"r:14;",
-$1:[function(a){return J.MT(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.mF(a)},"$1",null,2,0,null,65,"call"]},
 e189:{
 "^":"r:14;",
-$1:[function(a){return J.Lp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.MT(a)},"$1",null,2,0,null,65,"call"]},
 e190:{
 "^":"r:14;",
-$1:[function(a){return a.gqH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Lp(a)},"$1",null,2,0,null,65,"call"]},
 e191:{
 "^":"r:14;",
-$1:[function(a){return J.UZ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gqH()},"$1",null,2,0,null,65,"call"]},
 e192:{
 "^":"r:14;",
-$1:[function(a){return J.WN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.UZ(a)},"$1",null,2,0,null,65,"call"]},
 e193:{
 "^":"r:14;",
-$1:[function(a){return J.fi(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WN(a)},"$1",null,2,0,null,65,"call"]},
 e194:{
 "^":"r:14;",
-$1:[function(a){return J.Kl(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fi(a)},"$1",null,2,0,null,65,"call"]},
 e195:{
 "^":"r:14;",
-$1:[function(a){return a.gU6()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Kl(a)},"$1",null,2,0,null,65,"call"]},
 e196:{
 "^":"r:14;",
-$1:[function(a){return J.cj(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gU6()},"$1",null,2,0,null,65,"call"]},
 e197:{
 "^":"r:14;",
-$1:[function(a){return J.tC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.cj(a)},"$1",null,2,0,null,65,"call"]},
 e198:{
 "^":"r:14;",
-$1:[function(a){return J.jL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.tC(a)},"$1",null,2,0,null,65,"call"]},
 e199:{
 "^":"r:14;",
-$1:[function(a){return J.S5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jL(a)},"$1",null,2,0,null,65,"call"]},
 e200:{
 "^":"r:14;",
-$1:[function(a){return a.gj9()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.S5(a)},"$1",null,2,0,null,65,"call"]},
 e201:{
 "^":"r:14;",
-$1:[function(a){return J.x5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gj9()},"$1",null,2,0,null,65,"call"]},
 e202:{
 "^":"r:14;",
-$1:[function(a){return J.ksQ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.x5(a)},"$1",null,2,0,null,65,"call"]},
 e203:{
 "^":"r:14;",
-$1:[function(a){return J.Q0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ksQ(a)},"$1",null,2,0,null,65,"call"]},
 e204:{
 "^":"r:14;",
-$1:[function(a){return J.u5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Q0(a)},"$1",null,2,0,null,65,"call"]},
 e205:{
 "^":"r:14;",
-$1:[function(a){return J.ul(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.u5(a)},"$1",null,2,0,null,65,"call"]},
 e206:{
 "^":"r:14;",
-$1:[function(a){return a.gUx()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ul(a)},"$1",null,2,0,null,65,"call"]},
 e207:{
 "^":"r:14;",
-$1:[function(a){return J.WV(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUx()},"$1",null,2,0,null,65,"call"]},
 e208:{
 "^":"r:14;",
-$1:[function(a){return a.gm8()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WV(a)},"$1",null,2,0,null,65,"call"]},
 e209:{
 "^":"r:14;",
-$1:[function(a){return J.IS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gm8()},"$1",null,2,0,null,65,"call"]},
 e210:{
 "^":"r:14;",
-$1:[function(a){return J.pg(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.IS(a)},"$1",null,2,0,null,65,"call"]},
 e211:{
 "^":"r:14;",
-$1:[function(a){return a.ghL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pg(a)},"$1",null,2,0,null,65,"call"]},
 e212:{
 "^":"r:14;",
-$1:[function(a){return a.gCM()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.ghL()},"$1",null,2,0,null,65,"call"]},
 e213:{
 "^":"r:14;",
-$1:[function(a){return J.At(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gCM()},"$1",null,2,0,null,65,"call"]},
 e214:{
 "^":"r:14;",
-$1:[function(a){return J.Ou(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.At(a)},"$1",null,2,0,null,65,"call"]},
 e215:{
 "^":"r:14;",
-$1:[function(a){return J.Xp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ou(a)},"$1",null,2,0,null,65,"call"]},
 e216:{
 "^":"r:14;",
-$1:[function(a){return J.up(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Xp(a)},"$1",null,2,0,null,65,"call"]},
 e217:{
 "^":"r:14;",
-$1:[function(a){return J.n8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.up(a)},"$1",null,2,0,null,65,"call"]},
 e218:{
 "^":"r:14;",
-$1:[function(a){return a.gua()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.n8(a)},"$1",null,2,0,null,65,"call"]},
 e219:{
 "^":"r:14;",
-$1:[function(a){return a.gNS()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gua()},"$1",null,2,0,null,65,"call"]},
 e220:{
 "^":"r:14;",
-$1:[function(a){return a.guh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gNS()},"$1",null,2,0,null,65,"call"]},
 e221:{
 "^":"r:14;",
-$1:[function(a){return J.iL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.guh()},"$1",null,2,0,null,65,"call"]},
 e222:{
 "^":"r:14;",
-$1:[function(a){return J.G2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.iL(a)},"$1",null,2,0,null,65,"call"]},
 e223:{
 "^":"r:14;",
-$1:[function(a){return J.uW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.G2(a)},"$1",null,2,0,null,65,"call"]},
 e224:{
 "^":"r:14;",
-$1:[function(a){return J.Z8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.uW(a)},"$1",null,2,0,null,65,"call"]},
 e225:{
 "^":"r:14;",
-$1:[function(a){return J.uN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Z8(a)},"$1",null,2,0,null,65,"call"]},
 e226:{
 "^":"r:14;",
-$1:[function(a){return J.I1(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.uN(a)},"$1",null,2,0,null,65,"call"]},
 e227:{
 "^":"r:14;",
-$1:[function(a){return J.jH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.I1(a)},"$1",null,2,0,null,65,"call"]},
 e228:{
 "^":"r:14;",
-$1:[function(a){return J.jo(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jH(a)},"$1",null,2,0,null,65,"call"]},
 e229:{
 "^":"r:14;",
-$1:[function(a){return a.gVc()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jo(a)},"$1",null,2,0,null,65,"call"]},
 e230:{
 "^":"r:14;",
-$1:[function(a){return a.geH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gVc()},"$1",null,2,0,null,65,"call"]},
 e231:{
 "^":"r:14;",
-$1:[function(a){return J.i8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.geH()},"$1",null,2,0,null,65,"call"]},
 e232:{
 "^":"r:14;",
-$1:[function(a){return a.gGL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.i8(a)},"$1",null,2,0,null,65,"call"]},
 e233:{
 "^":"r:14;",
-$1:[function(a){return J.Hm(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gGL()},"$1",null,2,0,null,65,"call"]},
 e234:{
 "^":"r:14;",
-$1:[function(a){return J.nv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Hm(a)},"$1",null,2,0,null,65,"call"]},
 e235:{
 "^":"r:14;",
-$1:[function(a){return J.UP(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.nv(a)},"$1",null,2,0,null,65,"call"]},
 e236:{
 "^":"r:14;",
-$1:[function(a){return J.zD(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.UP(a)},"$1",null,2,0,null,65,"call"]},
 e237:{
 "^":"r:14;",
-$1:[function(a){return J.fx(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zD(a)},"$1",null,2,0,null,65,"call"]},
 e238:{
 "^":"r:14;",
-$1:[function(a){return J.Zs(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fx(a)},"$1",null,2,0,null,65,"call"]},
 e239:{
 "^":"r:14;",
-$1:[function(a){return J.j8v(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zs(a)},"$1",null,2,0,null,65,"call"]},
 e240:{
 "^":"r:14;",
-$1:[function(a){return a.gXR()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.j8v(a)},"$1",null,2,0,null,65,"call"]},
 e241:{
 "^":"r:14;",
-$1:[function(a){return J.P5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gXR()},"$1",null,2,0,null,65,"call"]},
 e242:{
 "^":"r:14;",
-$1:[function(a){return J.ll(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.P5(a)},"$1",null,2,0,null,65,"call"]},
 e243:{
 "^":"r:14;",
-$1:[function(a){return J.xi(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ll(a)},"$1",null,2,0,null,65,"call"]},
 e244:{
 "^":"r:14;",
-$1:[function(a){return J.Ip(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.xi(a)},"$1",null,2,0,null,65,"call"]},
 e245:{
 "^":"r:14;",
-$1:[function(a){return J.fY(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ip(a)},"$1",null,2,0,null,65,"call"]},
 e246:{
 "^":"r:14;",
-$1:[function(a){return J.aX(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fY(a)},"$1",null,2,0,null,65,"call"]},
 e247:{
 "^":"r:14;",
-$1:[function(a){return J.Hy(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.aX(a)},"$1",null,2,0,null,65,"call"]},
 e248:{
 "^":"r:14;",
-$1:[function(a){return J.Yj(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Hy(a)},"$1",null,2,0,null,65,"call"]},
 e249:{
 "^":"r:14;",
-$1:[function(a){return J.Cr(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Yj(a)},"$1",null,2,0,null,65,"call"]},
 e250:{
 "^":"r:14;",
-$1:[function(a){return J.oN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Cr(a)},"$1",null,2,0,null,65,"call"]},
 e251:{
 "^":"r:14;",
-$1:[function(a){return a.gV8()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.oN(a)},"$1",null,2,0,null,65,"call"]},
 e252:{
 "^":"r:14;",
-$1:[function(a){return J.Jq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gV8()},"$1",null,2,0,null,65,"call"]},
 e253:{
 "^":"r:14;",
-$1:[function(a){return J.TH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Jq(a)},"$1",null,2,0,null,65,"call"]},
 e254:{
 "^":"r:14;",
-$1:[function(a){return a.gp8()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.TH(a)},"$1",null,2,0,null,65,"call"]},
 e255:{
 "^":"r:14;",
-$1:[function(a){return J.F9(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gp8()},"$1",null,2,0,null,65,"call"]},
 e256:{
 "^":"r:14;",
-$1:[function(a){return J.HB(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.F9(a)},"$1",null,2,0,null,65,"call"]},
 e257:{
 "^":"r:14;",
-$1:[function(a){return J.yI(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.HB(a)},"$1",null,2,0,null,65,"call"]},
 e258:{
 "^":"r:14;",
-$1:[function(a){return J.H1(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.yI(a)},"$1",null,2,0,null,65,"call"]},
 e259:{
 "^":"r:14;",
-$1:[function(a){return J.LF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.H1(a)},"$1",null,2,0,null,65,"call"]},
 e260:{
 "^":"r:14;",
-$1:[function(a){return J.Ff(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.LF(a)},"$1",null,2,0,null,65,"call"]},
 e261:{
 "^":"r:14;",
-$1:[function(a){return J.vI(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ff(a)},"$1",null,2,0,null,65,"call"]},
 e262:{
 "^":"r:14;",
-$1:[function(a){return J.Pq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.vI(a)},"$1",null,2,0,null,65,"call"]},
 e263:{
 "^":"r:14;",
-$1:[function(a){return a.gDo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Pq(a)},"$1",null,2,0,null,65,"call"]},
 e264:{
 "^":"r:14;",
-$1:[function(a){return a.gLT()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gDo()},"$1",null,2,0,null,65,"call"]},
 e265:{
 "^":"r:14;",
-$1:[function(a){return a.gAY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gLT()},"$1",null,2,0,null,65,"call"]},
 e266:{
 "^":"r:14;",
-$1:[function(a){return J.Xa(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gAY()},"$1",null,2,0,null,65,"call"]},
 e267:{
 "^":"r:14;",
-$1:[function(a){return J.Aw(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Xa(a)},"$1",null,2,0,null,65,"call"]},
 e268:{
 "^":"r:14;",
-$1:[function(a){return J.Zu(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Aw(a)},"$1",null,2,0,null,65,"call"]},
 e269:{
 "^":"r:14;",
-$1:[function(a){return a.gm2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zu(a)},"$1",null,2,0,null,65,"call"]},
 e270:{
 "^":"r:14;",
-$1:[function(a){return J.dY(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gm2()},"$1",null,2,0,null,65,"call"]},
 e271:{
 "^":"r:14;",
-$1:[function(a){return J.OL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dY(a)},"$1",null,2,0,null,65,"call"]},
 e272:{
 "^":"r:14;",
-$1:[function(a){return J.zB(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.OL(a)},"$1",null,2,0,null,65,"call"]},
 e273:{
 "^":"r:14;",
-$1:[function(a){return a.gki()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zB(a)},"$1",null,2,0,null,65,"call"]},
 e274:{
 "^":"r:14;",
-$1:[function(a){return a.gZn()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gki()},"$1",null,2,0,null,65,"call"]},
 e275:{
 "^":"r:14;",
-$1:[function(a){return a.gGc()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZn()},"$1",null,2,0,null,65,"call"]},
 e276:{
 "^":"r:14;",
-$1:[function(a){return a.gVh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gGc()},"$1",null,2,0,null,65,"call"]},
 e277:{
 "^":"r:14;",
-$1:[function(a){return a.gZX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gVh()},"$1",null,2,0,null,65,"call"]},
 e278:{
 "^":"r:14;",
-$1:[function(a){return J.PS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZX()},"$1",null,2,0,null,65,"call"]},
 e279:{
 "^":"r:14;",
-$1:[function(a){return J.QI(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.PS(a)},"$1",null,2,0,null,65,"call"]},
 e280:{
 "^":"r:14;",
-$1:[function(a){return J.SS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QI(a)},"$1",null,2,0,null,65,"call"]},
 e281:{
 "^":"r:14;",
-$1:[function(a){return J.SG(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.SS(a)},"$1",null,2,0,null,65,"call"]},
 e282:{
 "^":"r:14;",
-$1:[function(a){return J.fv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.SG(a)},"$1",null,2,0,null,65,"call"]},
 e283:{
 "^":"r:14;",
-$1:[function(a){return a.gVF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fv(a)},"$1",null,2,0,null,65,"call"]},
 e284:{
 "^":"r:14;",
-$1:[function(a){return a.gkw()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gVF()},"$1",null,2,0,null,65,"call"]},
 e285:{
 "^":"r:14;",
-$1:[function(a){return J.p6(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkw()},"$1",null,2,0,null,65,"call"]},
 e286:{
 "^":"r:14;",
-$1:[function(a){return J.uy(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.p6(a)},"$1",null,2,0,null,65,"call"]},
 e287:{
 "^":"r:14;",
-$1:[function(a){return J.zH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.uy(a)},"$1",null,2,0,null,65,"call"]},
 e288:{
 "^":"r:14;",
-$1:[function(a){return a.gdW()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zH(a)},"$1",null,2,0,null,65,"call"]},
 e289:{
 "^":"r:14;",
-$1:[function(a){return a.gQR()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gdW()},"$1",null,2,0,null,65,"call"]},
 e290:{
 "^":"r:14;",
-$1:[function(a){return J.Gt(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gQR()},"$1",null,2,0,null,65,"call"]},
 e291:{
 "^":"r:14;",
-$1:[function(a){return a.gjW()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Gt(a)},"$1",null,2,0,null,65,"call"]},
 e292:{
 "^":"r:14;",
-$1:[function(a){return J.Sl(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gjW()},"$1",null,2,0,null,65,"call"]},
 e293:{
 "^":"r:14;",
-$1:[function(a){return a.gJk()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Sl(a)},"$1",null,2,0,null,65,"call"]},
 e294:{
 "^":"r:14;",
-$1:[function(a){return J.Q2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gJk()},"$1",null,2,0,null,65,"call"]},
 e295:{
 "^":"r:14;",
-$1:[function(a){return a.gSu()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Q2(a)},"$1",null,2,0,null,65,"call"]},
 e296:{
 "^":"r:14;",
-$1:[function(a){return a.gcs()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSu()},"$1",null,2,0,null,65,"call"]},
 e297:{
 "^":"r:14;",
-$1:[function(a){return a.gFc()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gcs()},"$1",null,2,0,null,65,"call"]},
 e298:{
 "^":"r:14;",
-$1:[function(a){return J.SW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gFc()},"$1",null,2,0,null,65,"call"]},
 e299:{
 "^":"r:14;",
-$1:[function(a){return a.gHD()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.SW(a)},"$1",null,2,0,null,65,"call"]},
 e300:{
 "^":"r:14;",
-$1:[function(a){return a.gae()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gHD()},"$1",null,2,0,null,65,"call"]},
 e301:{
 "^":"r:14;",
-$1:[function(a){return J.U8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gae()},"$1",null,2,0,null,65,"call"]},
 e302:{
 "^":"r:14;",
-$1:[function(a){return a.gYY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.U8(a)},"$1",null,2,0,null,65,"call"]},
 e303:{
 "^":"r:14;",
-$1:[function(a){return a.gZ3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gYY()},"$1",null,2,0,null,65,"call"]},
 e304:{
 "^":"r:14;",
-$1:[function(a){return J.pU(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSq()},"$1",null,2,0,null,65,"call"]},
 e305:{
 "^":"r:14;",
-$1:[function(a){return J.wp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pU(a)},"$1",null,2,0,null,65,"call"]},
 e306:{
 "^":"r:14;",
-$1:[function(a){return a.gSn()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wp(a)},"$1",null,2,0,null,65,"call"]},
 e307:{
 "^":"r:14;",
-$1:[function(a){return a.gzz()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSn()},"$1",null,2,0,null,65,"call"]},
 e308:{
 "^":"r:14;",
-$1:[function(a){return a.gv5()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gzz()},"$1",null,2,0,null,65,"call"]},
 e309:{
 "^":"r:14;",
-$1:[function(a){return J.GH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gv5()},"$1",null,2,0,null,65,"call"]},
 e310:{
 "^":"r:14;",
-$1:[function(a){return a.gaU()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.GH(a)},"$1",null,2,0,null,65,"call"]},
 e311:{
-"^":"r:80;",
-$2:[function(a,b){J.RX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+"^":"r:14;",
+$1:[function(a){return a.gaU()},"$1",null,2,0,null,65,"call"]},
 e312:{
 "^":"r:80;",
-$2:[function(a,b){J.zv(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.RX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e313:{
 "^":"r:80;",
-$2:[function(a,b){J.Px(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.zv(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e314:{
 "^":"r:80;",
-$2:[function(a,b){J.Tu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Px(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e315:{
 "^":"r:80;",
-$2:[function(a,b){J.Hh(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Tu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e316:{
 "^":"r:80;",
-$2:[function(a,b){J.Fv(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Vd(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e317:{
 "^":"r:80;",
-$2:[function(a,b){J.Ae(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Hh(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e318:{
 "^":"r:80;",
-$2:[function(a,b){J.m8(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Fv(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e319:{
 "^":"r:80;",
-$2:[function(a,b){J.Ed(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ae(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e320:{
 "^":"r:80;",
-$2:[function(a,b){J.NE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.m8(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e321:{
 "^":"r:80;",
-$2:[function(a,b){J.Kw(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ed(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e322:{
 "^":"r:80;",
-$2:[function(a,b){a.sUP(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.NE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e323:{
 "^":"r:80;",
-$2:[function(a,b){a.su5(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Kw(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e324:{
 "^":"r:80;",
-$2:[function(a,b){a.swz(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sUP(b)},"$2",null,4,0,null,65,68,"call"]},
 e325:{
 "^":"r:80;",
-$2:[function(a,b){J.NZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.su5(b)},"$2",null,4,0,null,65,68,"call"]},
 e326:{
 "^":"r:80;",
-$2:[function(a,b){J.T5(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.swz(b)},"$2",null,4,0,null,65,68,"call"]},
 e327:{
 "^":"r:80;",
-$2:[function(a,b){J.FI(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.NZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e328:{
 "^":"r:80;",
-$2:[function(a,b){J.i0(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.T5(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e329:{
 "^":"r:80;",
-$2:[function(a,b){J.Hf(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.FI(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e330:{
 "^":"r:80;",
-$2:[function(a,b){J.aP(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.i0(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e331:{
 "^":"r:80;",
-$2:[function(a,b){J.Jl(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Hf(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e332:{
 "^":"r:80;",
-$2:[function(a,b){J.Sf(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.aP(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e333:{
 "^":"r:80;",
-$2:[function(a,b){a.sOF(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Jl(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e334:{
 "^":"r:80;",
-$2:[function(a,b){J.LM(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Sf(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e335:{
 "^":"r:80;",
-$2:[function(a,b){J.au(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sOF(b)},"$2",null,4,0,null,65,68,"call"]},
 e336:{
 "^":"r:80;",
-$2:[function(a,b){J.Xu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.LM(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e337:{
 "^":"r:80;",
-$2:[function(a,b){J.Ac(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.au(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e338:{
 "^":"r:80;",
-$2:[function(a,b){J.AE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Xu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e339:{
 "^":"r:80;",
-$2:[function(a,b){a.sLK(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ac(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e340:{
 "^":"r:80;",
-$2:[function(a,b){a.sw2(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.AE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e341:{
 "^":"r:80;",
-$2:[function(a,b){J.Qr(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sLK(b)},"$2",null,4,0,null,65,68,"call"]},
 e342:{
 "^":"r:80;",
-$2:[function(a,b){J.P6(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sw2(b)},"$2",null,4,0,null,65,68,"call"]},
 e343:{
 "^":"r:80;",
-$2:[function(a,b){J.Yz(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qr(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e344:{
 "^":"r:80;",
-$2:[function(a,b){J.i2(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.P6(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e345:{
 "^":"r:80;",
-$2:[function(a,b){J.BC(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Yz(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e346:{
 "^":"r:80;",
-$2:[function(a,b){J.pB(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.i2(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e347:{
 "^":"r:80;",
-$2:[function(a,b){J.NO(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.BC(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e348:{
 "^":"r:80;",
-$2:[function(a,b){J.Sm(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.pB(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e349:{
 "^":"r:80;",
-$2:[function(a,b){J.JG(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.NO(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e350:{
 "^":"r:80;",
-$2:[function(a,b){J.JZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Sm(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e351:{
 "^":"r:80;",
-$2:[function(a,b){J.uF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.JG(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e352:{
 "^":"r:80;",
-$2:[function(a,b){J.uP(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.JZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e353:{
 "^":"r:80;",
-$2:[function(a,b){J.vJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.uF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e354:{
 "^":"r:80;",
-$2:[function(a,b){J.Nf(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.uP(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e355:{
 "^":"r:80;",
-$2:[function(a,b){J.Pl(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.vJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e356:{
 "^":"r:80;",
-$2:[function(a,b){J.C3(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Nf(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e357:{
 "^":"r:80;",
-$2:[function(a,b){a.sZD(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Pl(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e358:{
 "^":"r:80;",
-$2:[function(a,b){J.AI(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.C3(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e359:{
 "^":"r:80;",
-$2:[function(a,b){J.OE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sZD(b)},"$2",null,4,0,null,65,68,"call"]},
 e360:{
 "^":"r:80;",
-$2:[function(a,b){J.f6(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.AI(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e361:{
 "^":"r:80;",
-$2:[function(a,b){J.fb(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.OE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e362:{
 "^":"r:80;",
-$2:[function(a,b){a.siq(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.f6(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e363:{
 "^":"r:80;",
-$2:[function(a,b){J.MF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.fb(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e364:{
 "^":"r:80;",
-$2:[function(a,b){J.Qy(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.siq(b)},"$2",null,4,0,null,65,68,"call"]},
 e365:{
 "^":"r:80;",
-$2:[function(a,b){J.x0(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.MF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e366:{
 "^":"r:80;",
-$2:[function(a,b){a.sKt(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qy(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e367:{
 "^":"r:80;",
-$2:[function(a,b){J.cV(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.x0(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e368:{
 "^":"r:80;",
-$2:[function(a,b){J.mU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sKt(b)},"$2",null,4,0,null,65,68,"call"]},
 e369:{
 "^":"r:80;",
-$2:[function(a,b){J.uM(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.cV(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e370:{
 "^":"r:80;",
-$2:[function(a,b){J.Vr(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.mU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e371:{
 "^":"r:80;",
-$2:[function(a,b){J.GZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.uM(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e372:{
 "^":"r:80;",
-$2:[function(a,b){J.cm(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Vr(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e373:{
 "^":"r:80;",
-$2:[function(a,b){J.mz(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.GZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e374:{
 "^":"r:80;",
-$2:[function(a,b){J.pA(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.cm(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e375:{
 "^":"r:80;",
-$2:[function(a,b){a.scI(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.mz(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e376:{
 "^":"r:80;",
-$2:[function(a,b){J.cl(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.pA(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e377:{
 "^":"r:80;",
-$2:[function(a,b){J.BL(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.scI(b)},"$2",null,4,0,null,65,68,"call"]},
 e378:{
 "^":"r:80;",
-$2:[function(a,b){J.Ql(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.cl(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e379:{
 "^":"r:80;",
-$2:[function(a,b){J.xQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.BL(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e380:{
 "^":"r:80;",
-$2:[function(a,b){J.IX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ql(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e381:{
 "^":"r:80;",
-$2:[function(a,b){J.MX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.xQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e382:{
 "^":"r:80;",
-$2:[function(a,b){J.A4(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.IX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e383:{
 "^":"r:80;",
-$2:[function(a,b){J.wD(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.MX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e384:{
 "^":"r:80;",
-$2:[function(a,b){J.wJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.A4(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e385:{
 "^":"r:80;",
-$2:[function(a,b){J.rA(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.wD(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e386:{
 "^":"r:80;",
-$2:[function(a,b){J.oJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.wJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e387:{
 "^":"r:80;",
-$2:[function(a,b){J.WI(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.rA(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e388:{
 "^":"r:80;",
-$2:[function(a,b){a.svK(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.oJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e389:{
 "^":"r:80;",
-$2:[function(a,b){J.h9(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.WI(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e390:{
 "^":"r:80;",
-$2:[function(a,b){a.sL1(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.svK(b)},"$2",null,4,0,null,65,68,"call"]},
 e391:{
 "^":"r:80;",
-$2:[function(a,b){a.sXP(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.h9(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e392:{
 "^":"r:80;",
-$2:[function(a,b){a.sP2(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sL1(b)},"$2",null,4,0,null,65,68,"call"]},
 e393:{
 "^":"r:80;",
-$2:[function(a,b){a.sxH(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sXP(b)},"$2",null,4,0,null,65,68,"call"]},
 e394:{
 "^":"r:80;",
-$2:[function(a,b){J.XF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sP2(b)},"$2",null,4,0,null,65,68,"call"]},
 e395:{
 "^":"r:80;",
-$2:[function(a,b){J.b0(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sxH(b)},"$2",null,4,0,null,65,68,"call"]},
 e396:{
 "^":"r:80;",
-$2:[function(a,b){J.A1(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.XF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e397:{
 "^":"r:80;",
-$2:[function(a,b){a.sqH(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.b0(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e398:{
 "^":"r:80;",
-$2:[function(a,b){J.SF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.A1(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e399:{
 "^":"r:80;",
-$2:[function(a,b){J.Qv(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sqH(b)},"$2",null,4,0,null,65,68,"call"]},
 e400:{
 "^":"r:80;",
-$2:[function(a,b){J.R8(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.SF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e401:{
 "^":"r:80;",
-$2:[function(a,b){J.Xg(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qv(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e402:{
 "^":"r:80;",
-$2:[function(a,b){J.rL(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.R8(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e403:{
 "^":"r:80;",
-$2:[function(a,b){J.CJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Xg(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e404:{
 "^":"r:80;",
-$2:[function(a,b){J.P2(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.rL(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e405:{
 "^":"r:80;",
-$2:[function(a,b){J.jy(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.CJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e406:{
 "^":"r:80;",
-$2:[function(a,b){J.PP(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.P2(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e407:{
 "^":"r:80;",
-$2:[function(a,b){a.shL(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.jy(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e408:{
 "^":"r:80;",
-$2:[function(a,b){a.sCM(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.PP(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e409:{
 "^":"r:80;",
-$2:[function(a,b){J.Sj(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.shL(b)},"$2",null,4,0,null,65,68,"call"]},
 e410:{
 "^":"r:80;",
-$2:[function(a,b){J.TR(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sCM(b)},"$2",null,4,0,null,65,68,"call"]},
 e411:{
 "^":"r:80;",
-$2:[function(a,b){J.Co(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Sj(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e412:{
 "^":"r:80;",
-$2:[function(a,b){J.ME(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.TR(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e413:{
 "^":"r:80;",
-$2:[function(a,b){J.kX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Co(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e414:{
 "^":"r:80;",
-$2:[function(a,b){J.k4(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ME(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e415:{
 "^":"r:80;",
-$2:[function(a,b){J.EJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.kX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e416:{
 "^":"r:80;",
-$2:[function(a,b){J.bU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.k4(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e417:{
 "^":"r:80;",
-$2:[function(a,b){J.SO(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.EJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e418:{
 "^":"r:80;",
-$2:[function(a,b){J.B9(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.bU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e419:{
 "^":"r:80;",
-$2:[function(a,b){J.PN(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.SO(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e420:{
 "^":"r:80;",
-$2:[function(a,b){a.sVc(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.B9(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e421:{
 "^":"r:80;",
-$2:[function(a,b){J.By(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.PN(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e422:{
 "^":"r:80;",
-$2:[function(a,b){J.is(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sVc(b)},"$2",null,4,0,null,65,68,"call"]},
 e423:{
 "^":"r:80;",
-$2:[function(a,b){J.Rx(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.By(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e424:{
 "^":"r:80;",
-$2:[function(a,b){J.ry(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.is(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e425:{
 "^":"r:80;",
-$2:[function(a,b){J.Rd(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Rx(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e426:{
 "^":"r:80;",
-$2:[function(a,b){J.G7(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ry(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e427:{
 "^":"r:80;",
-$2:[function(a,b){J.Ez(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Rd(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e428:{
 "^":"r:80;",
-$2:[function(a,b){J.Qd(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.G7(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e429:{
 "^":"r:80;",
-$2:[function(a,b){J.fa(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ez(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e430:{
 "^":"r:80;",
-$2:[function(a,b){J.Cu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qd(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e431:{
 "^":"r:80;",
-$2:[function(a,b){a.sV8(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.fa(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e432:{
 "^":"r:80;",
-$2:[function(a,b){J.EE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Cu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e433:{
 "^":"r:80;",
-$2:[function(a,b){J.hw(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sV8(b)},"$2",null,4,0,null,65,68,"call"]},
 e434:{
 "^":"r:80;",
-$2:[function(a,b){J.EC(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.EE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e435:{
 "^":"r:80;",
-$2:[function(a,b){J.xH(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.hw(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e436:{
 "^":"r:80;",
-$2:[function(a,b){J.wu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.EC(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e437:{
 "^":"r:80;",
-$2:[function(a,b){J.Tx(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.xH(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e438:{
 "^":"r:80;",
-$2:[function(a,b){J.HT(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.wu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e439:{
 "^":"r:80;",
-$2:[function(a,b){J.FH(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Tx(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e440:{
 "^":"r:80;",
-$2:[function(a,b){J.o8(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.HT(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e441:{
 "^":"r:80;",
-$2:[function(a,b){a.sDo(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.FH(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e442:{
 "^":"r:80;",
-$2:[function(a,b){a.sAY(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.o8(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e443:{
 "^":"r:80;",
-$2:[function(a,b){J.ix(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sDo(b)},"$2",null,4,0,null,65,68,"call"]},
 e444:{
 "^":"r:80;",
-$2:[function(a,b){J.WU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sAY(b)},"$2",null,4,0,null,65,68,"call"]},
 e445:{
 "^":"r:80;",
-$2:[function(a,b){J.t3(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ix(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e446:{
 "^":"r:80;",
-$2:[function(a,b){J.my(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.WU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e447:{
 "^":"r:80;",
-$2:[function(a,b){a.sVF(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.t3(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e448:{
 "^":"r:80;",
-$2:[function(a,b){J.La(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.my(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e449:{
 "^":"r:80;",
-$2:[function(a,b){a.sQR(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sVF(b)},"$2",null,4,0,null,65,68,"call"]},
 e450:{
 "^":"r:80;",
-$2:[function(a,b){J.ZU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.La(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e451:{
 "^":"r:80;",
-$2:[function(a,b){a.sjW(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sQR(b)},"$2",null,4,0,null,65,68,"call"]},
 e452:{
 "^":"r:80;",
-$2:[function(a,b){J.Ja(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ZU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e453:{
 "^":"r:80;",
-$2:[function(a,b){J.tQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sjW(b)},"$2",null,4,0,null,65,68,"call"]},
 e454:{
 "^":"r:80;",
-$2:[function(a,b){J.w7(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ja(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e455:{
-"^":"r:77;",
-$0:[function(){return A.Ad("curly-block",C.Lg)},"$0",null,0,0,null,"call"]},
+"^":"r:80;",
+$2:[function(a,b){J.tQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e456:{
-"^":"r:77;",
-$0:[function(){return A.Ad("observatory-element",C.Mz)},"$0",null,0,0,null,"call"]},
+"^":"r:80;",
+$2:[function(a,b){J.w7(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e457:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-ref",C.il)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("curly-block",C.Lg)},"$0",null,0,0,null,"call"]},
 e458:{
 "^":"r:77;",
-$0:[function(){return A.Ad("any-service-ref",C.R9)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("observatory-element",C.Mz)},"$0",null,0,0,null,"call"]},
 e459:{
 "^":"r:77;",
-$0:[function(){return A.Ad("object-ref",C.OZ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-ref",C.il)},"$0",null,0,0,null,"call"]},
 e460:{
 "^":"r:77;",
-$0:[function(){return A.Ad("instance-ref",C.Wz)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("any-service-ref",C.R9)},"$0",null,0,0,null,"call"]},
 e461:{
 "^":"r:77;",
-$0:[function(){return A.Ad("action-link",C.K4)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("object-ref",C.OZ)},"$0",null,0,0,null,"call"]},
 e462:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-bar",C.LT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("instance-ref",C.Wz)},"$0",null,0,0,null,"call"]},
 e463:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-menu",C.ms)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("action-link",C.K4)},"$0",null,0,0,null,"call"]},
 e464:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-menu-item",C.FA)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-bar",C.LT)},"$0",null,0,0,null,"call"]},
 e465:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-refresh",C.JW)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-menu",C.ms)},"$0",null,0,0,null,"call"]},
 e466:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-control",C.NW)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-menu-item",C.FA)},"$0",null,0,0,null,"call"]},
 e467:{
 "^":"r:77;",
-$0:[function(){return A.Ad("top-nav-menu",C.Mf)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-refresh",C.JW)},"$0",null,0,0,null,"call"]},
 e468:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-nav-menu",C.km)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-control",C.NW)},"$0",null,0,0,null,"call"]},
 e469:{
 "^":"r:77;",
-$0:[function(){return A.Ad("library-nav-menu",C.vw)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("top-nav-menu",C.Mf)},"$0",null,0,0,null,"call"]},
 e470:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-nav-menu",C.Ey)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-nav-menu",C.km)},"$0",null,0,0,null,"call"]},
 e471:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-notify",C.Qt)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("library-nav-menu",C.vw)},"$0",null,0,0,null,"call"]},
 e472:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-notify-item",C.a8)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-nav-menu",C.Ey)},"$0",null,0,0,null,"call"]},
 e473:{
 "^":"r:77;",
-$0:[function(){return A.Ad("breakpoint-list",C.yS)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-notify",C.Qt)},"$0",null,0,0,null,"call"]},
 e474:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-ref",C.OG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-notify-item",C.a8)},"$0",null,0,0,null,"call"]},
 e475:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-tree",C.nw)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("breakpoint-list",C.yS)},"$0",null,0,0,null,"call"]},
 e476:{
 "^":"r:77;",
-$0:[function(){return A.Ad("error-ref",C.Bi)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-ref",C.OG)},"$0",null,0,0,null,"call"]},
 e477:{
 "^":"r:77;",
-$0:[function(){return A.Ad("eval-box",C.wk)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-tree",C.nw)},"$0",null,0,0,null,"call"]},
 e478:{
 "^":"r:77;",
-$0:[function(){return A.Ad("eval-link",C.jA)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("error-ref",C.Bi)},"$0",null,0,0,null,"call"]},
 e479:{
 "^":"r:77;",
-$0:[function(){return A.Ad("field-ref",C.Jo)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("eval-box",C.wk)},"$0",null,0,0,null,"call"]},
 e480:{
 "^":"r:77;",
-$0:[function(){return A.Ad("function-ref",C.lE)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("eval-link",C.jA)},"$0",null,0,0,null,"call"]},
 e481:{
 "^":"r:77;",
-$0:[function(){return A.Ad("library-ref",C.lp)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("field-ref",C.Jo)},"$0",null,0,0,null,"call"]},
 e482:{
 "^":"r:77;",
-$0:[function(){return A.Ad("script-inset",C.ON)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("function-ref",C.lE)},"$0",null,0,0,null,"call"]},
 e483:{
 "^":"r:77;",
-$0:[function(){return A.Ad("breakpoint-toggle",C.Nw)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("library-ref",C.lp)},"$0",null,0,0,null,"call"]},
 e484:{
 "^":"r:77;",
-$0:[function(){return A.Ad("script-ref",C.Sb)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("script-inset",C.ON)},"$0",null,0,0,null,"call"]},
 e485:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-view",C.ou)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("breakpoint-toggle",C.Nw)},"$0",null,0,0,null,"call"]},
 e486:{
 "^":"r:77;",
-$0:[function(){return A.Ad("code-ref",C.oT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("script-ref",C.Sb)},"$0",null,0,0,null,"call"]},
 e487:{
 "^":"r:77;",
-$0:[function(){return A.Ad("code-view",C.jR)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-view",C.ou)},"$0",null,0,0,null,"call"]},
 e488:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-page",C.hM)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("code-ref",C.oT)},"$0",null,0,0,null,"call"]},
 e489:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-stack",C.JX)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("code-view",C.jR)},"$0",null,0,0,null,"call"]},
 e490:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-frame",C.V7)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-page",C.hM)},"$0",null,0,0,null,"call"]},
 e491:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-console",C.Wd)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-stack",C.JX)},"$0",null,0,0,null,"call"]},
 e492:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-input",C.V8)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-frame",C.V7)},"$0",null,0,0,null,"call"]},
 e493:{
 "^":"r:77;",
-$0:[function(){return A.Ad("error-view",C.KO)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-console",C.Wd)},"$0",null,0,0,null,"call"]},
 e494:{
 "^":"r:77;",
-$0:[function(){return A.Ad("field-view",C.Az)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-input",C.V8)},"$0",null,0,0,null,"call"]},
 e495:{
 "^":"r:77;",
-$0:[function(){return A.Ad("flag-list",C.Qb)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("error-view",C.KO)},"$0",null,0,0,null,"call"]},
 e496:{
 "^":"r:77;",
-$0:[function(){return A.Ad("flag-item",C.Vx)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("field-view",C.Az)},"$0",null,0,0,null,"call"]},
 e497:{
 "^":"r:77;",
-$0:[function(){return A.Ad("function-view",C.te)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("flag-list",C.Qb)},"$0",null,0,0,null,"call"]},
 e498:{
 "^":"r:77;",
-$0:[function(){return A.Ad("heap-map",C.iD)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("flag-item",C.Vx)},"$0",null,0,0,null,"call"]},
 e499:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-view",C.tU)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("function-view",C.te)},"$0",null,0,0,null,"call"]},
 e500:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-ref",C.mK)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("heap-map",C.iD)},"$0",null,0,0,null,"call"]},
 e501:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-list-view",C.It)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-view",C.tU)},"$0",null,0,0,null,"call"]},
 e502:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-ref",C.qZ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-ref",C.mK)},"$0",null,0,0,null,"call"]},
 e503:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-view",C.Zj)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-list-view",C.It)},"$0",null,0,0,null,"call"]},
 e504:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-connection-view",C.Wh)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-ref",C.qZ)},"$0",null,0,0,null,"call"]},
 e505:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-connection-ref",C.pF)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-view",C.Zj)},"$0",null,0,0,null,"call"]},
 e506:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-socket-ref",C.FG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-connection-view",C.Wh)},"$0",null,0,0,null,"call"]},
 e507:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-socket-list-view",C.IZ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-connection-ref",C.pF)},"$0",null,0,0,null,"call"]},
 e508:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-socket-view",C.pJ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-socket-ref",C.FG)},"$0",null,0,0,null,"call"]},
 e509:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-web-socket-ref",C.Yy)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-socket-list-view",C.IZ)},"$0",null,0,0,null,"call"]},
 e510:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-web-socket-list-view",C.DD)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-socket-view",C.pJ)},"$0",null,0,0,null,"call"]},
 e511:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-web-socket-view",C.Xv)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-web-socket-ref",C.Yy)},"$0",null,0,0,null,"call"]},
 e512:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-random-access-file-list-view",C.tc)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-web-socket-list-view",C.DD)},"$0",null,0,0,null,"call"]},
 e513:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-random-access-file-ref",C.rR)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-web-socket-view",C.Xv)},"$0",null,0,0,null,"call"]},
 e514:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-random-access-file-view",C.oG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-random-access-file-list-view",C.tc)},"$0",null,0,0,null,"call"]},
 e515:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-process-list-view",C.he)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-random-access-file-ref",C.rR)},"$0",null,0,0,null,"call"]},
 e516:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-process-ref",C.dD)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-random-access-file-view",C.oG)},"$0",null,0,0,null,"call"]},
 e517:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-process-view",C.hP)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-process-list-view",C.he)},"$0",null,0,0,null,"call"]},
 e518:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-ref",C.UJ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-process-ref",C.dD)},"$0",null,0,0,null,"call"]},
 e519:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-summary",C.CT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-process-view",C.hP)},"$0",null,0,0,null,"call"]},
 e520:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-run-state",C.j4)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-ref",C.UJ)},"$0",null,0,0,null,"call"]},
 e521:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-location",C.Io)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-summary",C.CT)},"$0",null,0,0,null,"call"]},
 e522:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-shared-summary",C.EG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-run-state",C.j4)},"$0",null,0,0,null,"call"]},
 e523:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-counter-chart",C.ca)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-location",C.Io)},"$0",null,0,0,null,"call"]},
 e524:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-view",C.mq)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-shared-summary",C.EG)},"$0",null,0,0,null,"call"]},
 e525:{
 "^":"r:77;",
-$0:[function(){return A.Ad("inbound-reference",C.uC)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-counter-chart",C.ca)},"$0",null,0,0,null,"call"]},
 e526:{
 "^":"r:77;",
-$0:[function(){return A.Ad("object-common",C.rC)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-view",C.mq)},"$0",null,0,0,null,"call"]},
 e527:{
 "^":"r:77;",
-$0:[function(){return A.Ad("context-ref",C.XW)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("inbound-reference",C.uC)},"$0",null,0,0,null,"call"]},
 e528:{
 "^":"r:77;",
-$0:[function(){return A.Ad("instance-view",C.Ke)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("object-common",C.rC)},"$0",null,0,0,null,"call"]},
 e529:{
 "^":"r:77;",
-$0:[function(){return A.Ad("json-view",C.Tq)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("context-ref",C.XW)},"$0",null,0,0,null,"call"]},
 e530:{
 "^":"r:77;",
-$0:[function(){return A.Ad("library-view",C.PT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("instance-view",C.Ke)},"$0",null,0,0,null,"call"]},
 e531:{
 "^":"r:77;",
-$0:[function(){return A.Ad("metrics-page",C.Fn)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("json-view",C.Tq)},"$0",null,0,0,null,"call"]},
 e532:{
 "^":"r:77;",
-$0:[function(){return A.Ad("metric-details",C.fU)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("library-view",C.PT)},"$0",null,0,0,null,"call"]},
 e533:{
 "^":"r:77;",
-$0:[function(){return A.Ad("metrics-graph",C.pi)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("metrics-page",C.Fn)},"$0",null,0,0,null,"call"]},
 e534:{
 "^":"r:77;",
-$0:[function(){return A.Ad("object-view",C.kq)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("metric-details",C.fU)},"$0",null,0,0,null,"call"]},
 e535:{
 "^":"r:77;",
-$0:[function(){return A.Ad("context-view",C.kH)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("metrics-graph",C.pi)},"$0",null,0,0,null,"call"]},
 e536:{
 "^":"r:77;",
-$0:[function(){return A.Ad("heap-profile",C.Ju)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("object-view",C.kq)},"$0",null,0,0,null,"call"]},
 e537:{
 "^":"r:77;",
-$0:[function(){return A.Ad("sliding-checkbox",C.Y3)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("context-view",C.kH)},"$0",null,0,0,null,"call"]},
 e538:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-profile",C.ce)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("heap-profile",C.Ju)},"$0",null,0,0,null,"call"]},
 e539:{
 "^":"r:77;",
-$0:[function(){return A.Ad("script-view",C.Th)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("sliding-checkbox",C.Y3)},"$0",null,0,0,null,"call"]},
 e540:{
 "^":"r:77;",
-$0:[function(){return A.Ad("vm-view",C.jK)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-profile",C.ce)},"$0",null,0,0,null,"call"]},
 e541:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-view",C.X8)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("script-view",C.Th)},"$0",null,0,0,null,"call"]},
 e542:{
 "^":"r:77;",
-$0:[function(){return A.Ad("trace-view",C.kt)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("vm-view",C.jK)},"$0",null,0,0,null,"call"]},
 e543:{
 "^":"r:77;",
-$0:[function(){return A.Ad("map-viewer",C.u4)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-view",C.X8)},"$0",null,0,0,null,"call"]},
 e544:{
 "^":"r:77;",
-$0:[function(){return A.Ad("list-viewer",C.QJ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("trace-view",C.kt)},"$0",null,0,0,null,"call"]},
 e545:{
 "^":"r:77;",
-$0:[function(){return A.Ad("observatory-application",C.Dl)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("map-viewer",C.u4)},"$0",null,0,0,null,"call"]},
 e546:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-exception-view",C.pK)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("list-viewer",C.QJ)},"$0",null,0,0,null,"call"]},
 e547:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-error-view",C.wH)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("observatory-application",C.Dl)},"$0",null,0,0,null,"call"]},
 e548:{
 "^":"r:77;",
-$0:[function(){return A.Ad("vm-connect-target",C.ws)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-exception-view",C.pK)},"$0",null,0,0,null,"call"]},
 e549:{
 "^":"r:77;",
-$0:[function(){return A.Ad("vm-connect",C.bC)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-error-view",C.wH)},"$0",null,0,0,null,"call"]},
 e550:{
 "^":"r:77;",
+$0:[function(){return A.Ad("vm-connect-target",C.ws)},"$0",null,0,0,null,"call"]},
+e551:{
+"^":"r:77;",
+$0:[function(){return A.Ad("vm-connect",C.bC)},"$0",null,0,0,null,"call"]},
+e552:{
+"^":"r:77;",
 $0:[function(){return A.Ad("vm-ref",C.cK)},"$0",null,0,0,null,"call"]}},1],["","",,B,{
 "^":"",
 G6:{
@@ -4633,7 +4639,7 @@
 Qx:[function(a){return this.gNe(a)},"$0","gyX",0,0,77],
 SF:[function(a,b,c){var z=a.RZ
 if(b===!0)J.LE(z).ml(new T.WW(a)).wM(c)
-else{z.sZ3(null)
+else{z.sSq(null)
 c.$0()}},"$2","gNe",4,0,118,119,120],
 static:{CvM:function(a){var z,y,x,w
 z=P.L5(null,null,null,P.I,W.Bn)
@@ -4694,7 +4700,7 @@
 gFR:function(a){return a.RZ},
 Ki:function(a){return this.gFR(a).$0()},
 AV:function(a,b,c){return this.gFR(a).$2(b,c)},
-sFR:function(a,b){a.RZ=this.ct(a,C.U,a.RZ,b)},
+sFR:function(a,b){a.RZ=this.ct(a,C.AV,a.RZ,b)},
 git:function(a){return a.ij},
 sit:function(a,b){a.ij=this.ct(a,C.B0,a.ij,b)},
 tn:[function(a,b){var z=a.ij
@@ -9975,7 +9981,7 @@
 OP:function(a,b,c){return a.replaceChild(b,c)},
 $isKV:true,
 "%":"DocumentType|Notation;Node"},
-dX:{
+yk:{
 "^":"ecX;",
 gv:function(a){return a.length},
 p:function(a,b){if(b>>>0!==b||b>=a.length)throw H.b(P.Hj(b,a,null,null,null))
@@ -11773,7 +11779,7 @@
 gFR:function(a){return a.TQ},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.TQ=this.ct(a,C.U,a.TQ,b)},
+sFR:function(a,b){a.TQ=this.ct(a,C.AV,a.TQ,b)},
 gCf:function(a){return a.ca},
 sCf:function(a,b){a.ca=this.ct(a,C.Aa,a.ca,b)},
 y6:[function(a,b,c,d){var z=H.Go(J.Zu(b),"$isSc").value
@@ -11827,7 +11833,7 @@
 gFR:function(a){return a.RZ},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.RZ=this.ct(a,C.U,a.RZ,b)},
+sFR:function(a,b){a.RZ=this.ct(a,C.AV,a.RZ,b)},
 gkZ:function(a){return a.ij},
 skZ:function(a,b){a.ij=this.ct(a,C.YT,a.ij,b)},
 gyG:function(a){return a.TQ},
@@ -12231,7 +12237,7 @@
 if(a>>>0!==a||a>=z.length)return H.e(z,a)
 return J.DA(J.Tf(J.U8(z[a]),b))}return this.k5(a,b)}},
 Ly:{
-"^":"V18;RZ,ij,TQ,ca,Jc,cw,bN,mT,Jr,IL,cy$,db$,LD,kX,cy$,db$,cy$,db$,Q$,a$,b$,c$,d$,e$,f$,r$,x$,y$,z$,ch$,cx$",
+"^":"V18;RZ,ij,TQ,ca,Jc,cw,bN,mT,Jr,IL,TO,S8,cy$,db$,LD,kX,cy$,db$,cy$,db$,Q$,a$,b$,c$,d$,e$,f$,r$,x$,y$,z$,ch$,cx$",
 gYt:function(a){return a.RZ},
 sYt:function(a,b){a.RZ=this.ct(a,C.TN,a.RZ,b)},
 gcH:function(a){return a.ij},
@@ -12240,9 +12246,11 @@
 sLF:function(a,b){a.bN=this.ct(a,C.kG,a.bN,b)},
 gB1:function(a){return a.Jr},
 sB1:function(a,b){a.Jr=this.ct(a,C.vb,a.Jr,b)},
-god:function(a){return a.IL},
-sod:function(a,b){a.IL=this.ct(a,C.rB,a.IL,b)},
-Es:function(a){var z,y
+gyh:function(a){return a.IL},
+syh:function(a,b){a.IL=this.ct(a,C.U,a.IL,b)},
+god:function(a){return a.S8},
+sod:function(a,b){a.S8=this.ct(a,C.rB,a.S8,b)},
+Es:function(a){var z,y,x,w,v
 this.VM(a)
 z=(a.shadowRoot||a.webkitShadowRoot).querySelector("#newPieChart")
 y=new G.qu(null,P.L5(null,null,null,null,null))
@@ -12252,7 +12260,19 @@
 z=new G.qu(null,P.L5(null,null,null,null,null))
 z.Q=P.zV(J.Tf($.NR,"PieChart"),[y])
 a.cw=z
-a.mT=(a.shadowRoot||a.webkitShadowRoot).querySelector("#classTableBody")},
+a.mT=(a.shadowRoot||a.webkitShadowRoot).querySelector("#classTableBody")
+z=J.vo(J.HL(J.um($.Pi.c)),new K.Y1(a))
+y=this.gkC(a)
+x=H.W8(z,"YR",0)
+w=H.W8(z,"YR",1)
+v=$.X3
+v=H.J(new P.fB(z,null,null,null,null,v,0,null,null),[x,w])
+v.Cy(y,null,null,!1,w)
+v.JC(z,y,null,null,!1,x,w)
+a.TO=v},
+dQ:function(a){a.TO.Z3(new K.dk())
+this.eX(a)},
+j5:[function(a,b){if(a.IL===!0&&J.mG(J.Ts(b),"GC"))this.SK(a,new K.Z3())},"$1","gkC",2,0,86,87],
 Qf:function(a){var z,y,x,w
 for(z=J.Nx(J.Tf(a.Jr,"members"));z.D();){y=z.gk()
 x=J.U6(y)
@@ -12339,8 +12359,8 @@
 z=a.Jr
 if(z==null)return
 z=J.wg(z)
-z=this.ct(a,C.rB,a.IL,z)
-a.IL=z
+z=this.ct(a,C.rB,a.S8,z)
+a.S8=z
 z.WU(J.Tf(a.Jr,"heaps"))
 y=H.BU(J.Tf(a.Jr,"dateLastAccumulatorReset"),null,null)
 if(!J.mG(y,0)){z=P.Wu(y,!1).X(0)
@@ -12431,6 +12451,7 @@
 w=P.A(null,null)
 a.RZ="---"
 a.ij="---"
+a.IL=!1
 a.b$=[]
 a.f$=!1
 a.x$=!1
@@ -12444,7 +12465,16 @@
 return a}}},
 V18:{
 "^":"uL+Piz;",
-$isd3:true}}],["","",,P,{
+$isd3:true},
+Y1:{
+"^":"r:14;Q",
+$1:[function(a){return J.mG(J.wg(a),this.Q.S8)},"$1",null,2,0,null,87,"call"]},
+dk:{
+"^":"r:77;",
+$0:[function(){},"$0",null,0,0,null,"call"]},
+Z3:{
+"^":"r:77;",
+$0:[function(){},"$0",null,0,0,null,"call"]}}],["","",,P,{
 "^":"",
 jl:function(a){var z,y
 z=[]
@@ -13050,8 +13080,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.rU.LX(a)
-C.rU.XI(a)
+C.Gg.LX(a)
+C.Gg.XI(a)
 return a}}},
 V26:{
 "^":"uL+Piz;",
@@ -13806,8 +13836,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.Z3.LX(a)
-C.Z3.XI(a)
+C.Z3y.LX(a)
+C.Z3y.XI(a)
 return a}}}}],["","",,M,{
 "^":"",
 CX:{
@@ -13927,14 +13957,14 @@
 "^":"",
 E2:function(){var z,y
 N.QM("").sOR(C.IF)
-N.QM("").gY().yI(new F.e551())
+N.QM("").gY().yI(new F.e553())
 N.QM("").To("Starting Observatory")
 N.QM("").To("Loading Google Charts API")
 z=J.Tf($.Xw(),"google")
 y=$.Ib()
 z.Z("load",["visualization","1",P.jT(P.B(["packages",["corechart","table"],"callback",P.mt(y.gv6(y))],null,null))])
-$.Ib().Q.ml(G.vN()).ml(new F.e552())},
-e551:{
+$.Ib().Q.ml(G.vN()).ml(new F.e554())},
+e553:{
 "^":"r:172;",
 $1:[function(a){var z
 if(J.mG(a.gOR(),C.nT)){z=J.RE(a)
@@ -13942,7 +13972,7 @@
 else z=!1}else z=!1
 if(z)return
 P.FL(a.gOR().Q+": "+a.gFl().X(0)+": "+H.d(J.Oh(a)))},"$1",null,2,0,null,171,"call"]},
-e552:{
+e554:{
 "^":"r:14;",
 $1:[function(a){var z,y,x
 N.QM("").To("Initializing Polymer")
@@ -14204,7 +14234,7 @@
 gFR:function(a){return a.RZ},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.RZ=this.ct(a,C.U,a.RZ,b)},
+sFR:function(a,b){a.RZ=this.ct(a,C.AV,a.RZ,b)},
 gjl:function(a){return a.ij},
 sjl:function(a,b){a.ij=this.ct(a,C.S,a.ij,b)},
 gph:function(a){return a.TQ},
@@ -14446,8 +14476,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.br.LX(a)
-C.br.XI(a)
+C.aD.LX(a)
+C.aD.XI(a)
 return a}}},
 V55:{
 "^":"uL+Piz;",
@@ -15982,8 +16012,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.Ki.LX(a)
-C.Ki.XI(a)
+C.Vk.LX(a)
+C.Vk.XI(a)
 return a}}},
 jpR:{
 "^":"Bo+zs;Cp:r$=,KM:z$=",
@@ -16053,7 +16083,7 @@
 M.uH(b).Jh(null)
 y=this.gZJ(a)
 x=!!J.t(b).$ishs?b:M.uH(b)
-w=J.Km(x,a,y==null&&J.Ee(x)==null?J.vo(a.Q$):y)
+w=J.Km(x,a,y==null&&J.Ee(x)==null?J.rU(a.Q$):y)
 v=a.b$
 u=$.nR().p(0,w)
 C.Nm.FV(v,u!=null?u.gdn():u)
@@ -16193,7 +16223,7 @@
 wc:function(a,b,c){return this.rh(a,b,c,!1)},
 yO:function(a,b){var z=a.Q$.giz().p(0,b)
 if(z==null)return
-return T.pw().$3$globals(T.EPS().$1(z),a,J.vo(a.Q$).a.b)},
+return T.pw().$3$globals(T.EPS().$1(z),a,J.rU(a.Q$).a.b)},
 bT:function(a){var z,y,x,w,v,u,t,s
 z=a.Q$.giz()
 for(v=J.Nx(J.q8(z)),u=a.ch$;v.D();){y=v.gk()
@@ -16317,7 +16347,7 @@
 Jys:{
 "^":"r:80;Q",
 $2:function(a,b){var z=this.Q
-$.Op().Z("addEventListener",[z,a,$.X3.mS(J.vo(z.Q$).Y2(z,z,b))])}},
+$.Op().Z("addEventListener",[z,a,$.X3.mS(J.rU(z.Q$).Y2(z,z,b))])}},
 od:{
 "^":"r:77;Q,a",
 $0:[function(){return">>> ["+H.d(J.RI(this.Q))+"]: dispatch "+H.d(this.a)},"$0",null,0,0,null,"call"]},
@@ -16597,7 +16627,7 @@
 $1:function(a){return this.Q}}}],["","",,T,{
 "^":"",
 Rj:[function(a){var z=J.t(a)
-if(!!z.$isw)z=J.Vk(z.gvc(a),new T.IK(a)).zV(0," ")
+if(!!z.$isw)z=J.vo(z.gvc(a),new T.IK(a)).zV(0," ")
 else z=!!z.$isQV?z.zV(a," "):a
 return z},"$1","PG6",2,0,53,68],
 PX5:[function(a){var z=J.t(a)
@@ -16718,7 +16748,7 @@
 TR:function(a,b){var z,y
 if(this.c!=null)throw H.b(P.s("already open"))
 this.c=b
-z=J.ph(this.b,new K.Oy(P.NZ2(null,null)))
+z=J.okV(this.b,new K.Oy(P.NZ2(null,null)))
 this.e=z
 y=z.gE6().yI(this.gGX())
 y.fm(0,new T.yF(this))
@@ -16727,7 +16757,7 @@
 return this.f},
 kf:function(a){var z,y,x,w
 try{x=this.e
-J.ph(x,new K.pf(this.Q,a))
+J.okV(x,new K.pf(this.Q,a))
 x.gLl()
 x=this.Mr(this.e.gLl(),a)
 return x}catch(w){x=H.Ru(w)
@@ -16748,13 +16778,13 @@
 z=$.Pk()
 y=this.e
 z.toString
-J.ph(y,z)
+J.okV(y,z)
 this.e=null},
 fR:function(){if(this.c!=null)this.Dy()},
 Dy:function(){var z=0
 while(!0){if(!(z<1000&&this.Yg()===!0))break;++z}return z>0},
 static:{"^":"Hi1",rD:function(a,b,c){var z,y,x,w,v
-try{z=J.ph(a,new K.GQ(b))
+try{z=J.okV(a,new K.GQ(b))
 w=c==null?z:c.$1(z)
 return w}catch(v){w=H.Ru(v)
 y=w
@@ -16790,11 +16820,11 @@
 v=!0}else{if(!!y.$iszg){w=a.ghP()
 x=y.goc(a)}else{if(d)throw H.b(K.du("Expression is not assignable: "+H.d(a)))
 return}v=!1}for(y=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);y.D();){u=y.c
-J.ph(u,new K.GQ(c))
+J.okV(u,new K.GQ(c))
 if(d)throw H.b(K.du("filter must implement Transformer to be assignable: "+H.d(u)))
-else return}t=J.ph(w,new K.GQ(c))
+else return}t=J.okV(w,new K.GQ(c))
 if(t==null)return
-if(v)J.H9(t,J.ph(x,new K.GQ(c)),b)
+if(v)J.H9(t,J.okV(x,new K.GQ(c)),b)
 else{y=$.Mg().Q.f.p(0,x)
 $.cp().Q1(t,y,b)}return b},
 cT:function(a,b){var z,y
@@ -16895,7 +16925,7 @@
 return this.Q.Eq(a)},
 X:[function(a){return this.Q.X(0)+" > [local: "+H.d(this.a)+"]"},"$0","gCR",0,0,0]},
 Ph:{
-"^":"PF;eT:Q>,Z3:a<",
+"^":"PF;eT:Q>,Sq:a<",
 gk8:function(a){return this.Q.Q},
 p:function(a,b){var z=this.a
 if(z.NZ(0,b)){z=z.p(0,b)
@@ -16942,16 +16972,16 @@
 W9:function(a){return J.ZH(this.Q)},
 Hs:function(a){return a.Q.RR(0,this)},
 T7:function(a){var z,y,x
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 if(z==null)return
 y=a.goc(a)
 x=$.Mg().Q.f.p(0,y)
 return $.cp().jD(z,x)},
-CU:function(a){var z=J.ph(a.ghP(),this)
+CU:function(a){var z=J.okV(a.ghP(),this)
 if(z==null)return
-return J.Tf(z,J.ph(a.gmU(),this))},
+return J.Tf(z,J.okV(a.gmU(),this))},
 Y7:function(a){var z,y,x,w,v
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 if(z==null)return
 if(a.gre()==null)y=null
 else{x=a.gre()
@@ -16966,13 +16996,13 @@
 o0:function(a){var z,y,x
 z=P.A(null,null)
 for(y=a.gJq(a),y=H.J(new H.a7(y,y.length,0,null),[H.u3(y,0)]);y.D();){x=y.c
-z.q(0,J.ph(J.Kt(x),this),J.ph(x.gv4(),this))}return z},
+z.q(0,J.okV(J.Kt(x),this),J.okV(x.gv4(),this))}return z},
 YV:function(a){return H.vh(P.f("should never be called"))},
 qv:function(a){return J.Tf(this.Q,a.gM(a))},
 ex:function(a){var z,y,x,w,v
 z=a.gxS(a)
-y=J.ph(a.gBb(a),this)
-x=J.ph(a.gT8(a),this)
+y=J.okV(a.gBb(a),this)
+x=J.okV(a.gT8(a),this)
 w=$.RTI().p(0,z)
 v=J.t(z)
 if(v.m(z,"&&")||v.m(z,"||")){v=y==null?!1:y
@@ -16980,11 +17010,11 @@
 else if(y==null||x==null)return
 return w.$2(y,x)},
 Hx:function(a){var z,y
-z=J.ph(a.gO4(),this)
+z=J.okV(a.gO4(),this)
 y=$.fs().p(0,a.gxS(a))
 if(J.mG(a.gxS(a),"!"))return y.$1(z==null?!1:z)
 return z==null?null:y.$1(z)},
-RD:function(a){return J.mG(J.ph(a.gdc(),this),!0)?J.ph(a.gav(),this):J.ph(a.grM(),this)},
+RD:function(a){return J.mG(J.okV(a.gdc(),this),!0)?J.okV(a.gav(),this):J.okV(a.grM(),this)},
 MV:function(a){return H.vh(P.f("can't eval an 'in' expression"))},
 eS:function(a){return H.vh(P.f("can't eval an 'as' expression"))}},
 Oy:{
@@ -16992,19 +17022,19 @@
 W9:function(a){return new K.WhS(a,null,null,null,P.bK(null,null,!1,null))},
 Hs:function(a){return a.Q.RR(0,this)},
 T7:function(a){var z,y
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 y=new K.vl(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(y)
 return y},
 CU:function(a){var z,y,x
-z=J.ph(a.ghP(),this)
-y=J.ph(a.gmU(),this)
+z=J.okV(a.ghP(),this)
+y=J.okV(a.gmU(),this)
 x=new K.iT(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(x)
 y.sHg(x)
 return x},
 Y7:function(a){var z,y,x,w,v
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 if(a.gre()==null)y=null
 else{x=a.gre()
 w=this.gnG()
@@ -17025,29 +17055,29 @@
 C.Nm.aN(z,new K.Xs(y))
 return y},
 YV:function(a){var z,y,x
-z=J.ph(a.gG3(a),this)
-y=J.ph(a.gv4(),this)
+z=J.okV(a.gG3(a),this)
+y=J.okV(a.gv4(),this)
 x=new K.EL(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(x)
 y.sHg(x)
 return x},
 qv:function(a){return new K.ek(a,null,null,null,P.bK(null,null,!1,null))},
 ex:function(a){var z,y,x
-z=J.ph(a.gBb(a),this)
-y=J.ph(a.gT8(a),this)
+z=J.okV(a.gBb(a),this)
+y=J.okV(a.gT8(a),this)
 x=new K.ky(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(x)
 y.sHg(x)
 return x},
 Hx:function(a){var z,y
-z=J.ph(a.gO4(),this)
+z=J.okV(a.gO4(),this)
 y=new K.mv(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(y)
 return y},
 RD:function(a){var z,y,x,w
-z=J.ph(a.gdc(),this)
-y=J.ph(a.gav(),this)
-x=J.ph(a.grM(),this)
+z=J.okV(a.gdc(),this)
+y=J.okV(a.gav(),this)
+x=J.okV(a.grM(),this)
 w=new K.an(z,y,x,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(w)
 y.sHg(w)
@@ -17767,41 +17797,41 @@
 "^":"",
 P55:{
 "^":"a;",
-DV:[function(a){return J.ph(a,this)},"$1","gnG",2,0,208,167]},
+DV:[function(a){return J.okV(a,this)},"$1","gnG",2,0,208,167]},
 cfS:{
 "^":"P55;",
 xn:function(a){},
 W9:function(a){this.xn(a)},
 Hs:function(a){a.Q.RR(0,this)
 this.xn(a)},
-T7:function(a){J.ph(a.ghP(),this)
+T7:function(a){J.okV(a.ghP(),this)
 this.xn(a)},
-CU:function(a){J.ph(a.ghP(),this)
-J.ph(a.gmU(),this)
+CU:function(a){J.okV(a.ghP(),this)
+J.okV(a.gmU(),this)
 this.xn(a)},
 Y7:function(a){var z
-J.ph(a.ghP(),this)
-if(a.gre()!=null)for(z=a.gre(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.ph(z.c,this)
+J.okV(a.ghP(),this)
+if(a.gre()!=null)for(z=a.gre(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.okV(z.c,this)
 this.xn(a)},
 I6:function(a){this.xn(a)},
 Zh:function(a){var z
-for(z=a.gMO(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.ph(z.c,this)
+for(z=a.gMO(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.okV(z.c,this)
 this.xn(a)},
 o0:function(a){var z
-for(z=a.gJq(a),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.ph(z.c,this)
+for(z=a.gJq(a),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.okV(z.c,this)
 this.xn(a)},
-YV:function(a){J.ph(a.gG3(a),this)
-J.ph(a.gv4(),this)
+YV:function(a){J.okV(a.gG3(a),this)
+J.okV(a.gv4(),this)
 this.xn(a)},
 qv:function(a){this.xn(a)},
-ex:function(a){J.ph(a.gBb(a),this)
-J.ph(a.gT8(a),this)
+ex:function(a){J.okV(a.gBb(a),this)
+J.okV(a.gT8(a),this)
 this.xn(a)},
-Hx:function(a){J.ph(a.gO4(),this)
+Hx:function(a){J.okV(a.gO4(),this)
 this.xn(a)},
-RD:function(a){J.ph(a.gdc(),this)
-J.ph(a.gav(),this)
-J.ph(a.grM(),this)
+RD:function(a){J.okV(a.gdc(),this)
+J.okV(a.gav(),this)
+J.okV(a.grM(),this)
 this.xn(a)},
 MV:function(a){a.Q.RR(0,this)
 a.a.RR(0,this)
@@ -19013,7 +19043,7 @@
 "^":"af+Piz;",
 $isd3:true},
 U4:{
-"^":"rG9;x,Pb:y<,XR:z<,DD:ch>,Z3:cx<,jV:cy<,cy$,db$,Q,a,b,c,d,e,f,r,cy$,db$",
+"^":"rG9;x,Pb:y<,XR:z<,DD:ch>,Sq:cx<,jV:cy<,cy$,db$,Q,a,b,c,d,e,f,r,cy$,db$",
 gO3:function(a){return this.x},
 gjm:function(){return!0},
 gM8:function(){return!1},
@@ -19261,8 +19291,8 @@
 sqH:function(a){this.z=F.Wi(this,C.BV,this.z,a)},
 gv:function(a){return this.ch},
 sv:function(a,b){this.ch=F.Wi(this,C.Wn,this.ch,b)},
-gZ3:function(){return this.cx},
-sZ3:function(a){this.cx=F.Wi(this,C.xw,this.cx,a)},
+gSq:function(){return this.cx},
+sSq:function(a){this.cx=F.Wi(this,C.xw,this.cx,a)},
 bF:function(a,b,c){var z,y
 D.kT(b,J.wg(this.Q))
 z=J.U6(b)
@@ -19675,7 +19705,7 @@
 gSS:function(){return this.c},
 gUB:function(){return J.mG(this.Q,0)},
 gvN:function(){return this.d.b.length>0},
-dV:[function(){var z,y
+xtx:[function(){var z,y
 z=this.Q
 y=J.t(z)
 if(y.m(z,0))return""
@@ -20139,8 +20169,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.Vd.LX(a)
-C.Vd.XI(a)
+C.kgQ.LX(a)
+C.kgQ.XI(a)
 return a}}},
 V62:{
 "^":"uL+Piz;",
@@ -21625,7 +21655,7 @@
 yY:function(a){this.Wd(a)},
 wT:function(a,b){if(J.co(b,"ws://"))return b
 return"ws://"+H.d(b)+"/ws"},
-ny:[function(a,b,c,d){var z,y,x
+nyC:[function(a,b,c,d){var z,y,x
 J.Kr(b)
 z=this.wT(a,a.RZ)
 d=$.Pi.d.J8(z)
@@ -22325,8 +22355,8 @@
 J.Ux=function(a){return J.RE(a).geo(a)}
 J.V1=function(a,b){return J.w1(a).Rz(a,b)}
 J.V2=function(a,b,c){return J.w1(a).aP(a,b,c)}
+J.Vd=function(a,b){return J.RE(a).syh(a,b)}
 J.Vj=function(a,b){return J.RE(a).Md(a,b)}
-J.Vk=function(a,b){return J.w1(a).ev(a,b)}
 J.Vr=function(a,b){return J.RE(a).sG3(a,b)}
 J.Vs=function(a){return J.RE(a).gQg(a)}
 J.W1=function(a,b){if(typeof a=="number"&&typeof b=="number")return a<=b
@@ -22397,6 +22427,7 @@
 J.cm=function(a,b){return J.w1(a).srZ(a,b)}
 J.co=function(a,b){return J.NH(a).nC(a,b)}
 J.dH=function(a,b){return J.w1(a).h(a,b)}
+J.dX=function(a){return J.RE(a).gyh(a)}
 J.dY=function(a){return J.RE(a).ga4(a)}
 J.de=function(a){return J.RE(a).gGd(a)}
 J.df=function(a){return J.RE(a).QE(a)}
@@ -22490,6 +22521,7 @@
 J.oJ=function(a,b){return J.RE(a).srs(a,b)}
 J.oN=function(a){return J.RE(a).gj4(a)}
 J.ocJ=function(a,b){return J.RE(a).yU(a,b)}
+J.okV=function(a,b){return J.RE(a).RR(a,b)}
 J.op=function(a){return J.RE(a).gD7(a)}
 J.or=function(a){return J.RE(a).gV5(a)}
 J.p6=function(a){return J.RE(a).gBN(a)}
@@ -22502,7 +22534,6 @@
 J.pU=function(a){return J.RE(a).gYe(a)}
 J.pb=function(a,b){return J.w1(a).Vr(a,b)}
 J.pg=function(a){return J.RE(a).gBj(a)}
-J.ph=function(a,b){return J.RE(a).RR(a,b)}
 J.pr=function(a){return J.RE(a).guS(a)}
 J.pz=function(a){return J.RE(a).gwe(a)}
 J.q0=function(a){return J.RE(a).guz(a)}
@@ -22517,6 +22548,7 @@
 J.qx=function(a){return J.RE(a).gbe(a)}
 J.rA=function(a,b){return J.RE(a).sbe(a,b)}
 J.rL=function(a,b){return J.RE(a).spE(a,b)}
+J.rU=function(a){return J.RE(a).gZJ(a)}
 J.rn=function(a){return J.w1(a).grZ(a)}
 J.ro=function(a){return J.RE(a).gOB(a)}
 J.rp=function(a){return J.RE(a).gd4(a)}
@@ -22556,7 +22588,7 @@
 J.vU=function(a,b){if(typeof a=="number"&&typeof b=="number")return a>b
 return J.Wx(a).A(a,b)}
 J.vX=function(a){return J.w1(a).wg(a)}
-J.vo=function(a){return J.RE(a).gZJ(a)}
+J.vo=function(a,b){return J.w1(a).ev(a,b)}
 J.vu=function(a,b){return J.RE(a).So(a,b)}
 J.w7=function(a,b){return J.RE(a).syW(a,b)}
 J.w8=function(a){return J.RE(a).gkc(a)}
@@ -22654,7 +22686,7 @@
 C.Ag=E.Mb.prototype
 C.ozm=E.oF.prototype
 C.wK=E.qh.prototype
-C.rU=E.Q6.prototype
+C.Gg=E.Q6.prototype
 C.za=E.L4.prototype
 C.ag=E.Zn.prototype
 C.RrX=E.uE.prototype
@@ -22679,7 +22711,7 @@
 C.yo=J.E.prototype
 C.GB=Z.vj.prototype
 C.xA=A.UK.prototype
-C.Z3=R.LU.prototype
+C.Z3y=R.LU.prototype
 C.MG=M.CX.prototype
 C.dl=U.WG.prototype
 C.vmJ=U.VZ.prototype
@@ -22696,19 +22728,19 @@
 C.BJj=A.NK.prototype
 C.L8=A.Zx.prototype
 C.J7=A.Ww.prototype
-C.t5=W.dX.prototype
-C.br=L.qV.prototype
+C.t5=W.yk.prototype
+C.aD=L.qV.prototype
 C.ji=Q.Ce.prototype
 C.Lj=L.NT.prototype
 C.YpE=V.F1.prototype
 C.Pfz=Z.uL.prototype
 C.ZQ=J.iCW.prototype
-C.Ki=A.xc.prototype
+C.Vk=A.xc.prototype
 C.Fa=T.ov.prototype
 C.Wa=A.kn.prototype
 C.cJ0=U.fI.prototype
 C.U0=R.zM.prototype
-C.Vd=D.Rk.prototype
+C.kgQ=D.Rk.prototype
 C.Ns=U.Ti.prototype
 C.HRc=Q.xI.prototype
 C.zb=Q.CY.prototype
@@ -22921,6 +22953,8 @@
 C.UI=new A.ES(C.bJ,C.BM,!1,C.jJ,!1,C.cs)
 C.kw=H.K('w')
 C.hS=new A.ES(C.SR,C.BM,!1,C.kw,!1,C.cs)
+C.U=new H.tx("autoRefresh")
+C.br=new A.ES(C.U,C.BM,!1,C.nd,!1,C.cs)
 C.Zi=new H.tx("lastAccumulatorReset")
 C.vC=new A.ES(C.Zi,C.BM,!1,C.yE,!1,C.y0)
 C.hf=new H.tx("label")
@@ -22988,9 +23022,9 @@
 C.JD=new A.ES(C.am,C.BM,!1,C.Gsc,!1,C.y0)
 C.A7=new H.tx("height")
 C.cD=new A.ES(C.A7,C.BM,!1,C.yE,!1,C.cs)
-C.U=new H.tx("callback")
+C.AV=new H.tx("callback")
 C.Fyq=H.K('Sa')
-C.k1=new A.ES(C.U,C.BM,!1,C.Fyq,!1,C.cs)
+C.k1=new A.ES(C.AV,C.BM,!1,C.Fyq,!1,C.cs)
 C.TW=new H.tx("tagSelector")
 C.B3=new A.ES(C.TW,C.BM,!1,C.yE,!1,C.y0)
 C.r1=new H.tx("expandChanged")
@@ -23010,7 +23044,7 @@
 C.TO=new A.ES(C.kY,C.BM,!1,C.Ct,!1,C.cs)
 C.uG=new H.tx("linesReady")
 C.Df=new A.ES(C.uG,C.BM,!1,C.nd,!1,C.y0)
-C.Qp=new A.ES(C.U,C.BM,!1,C.wG,!1,C.cs)
+C.Qp=new A.ES(C.AV,C.BM,!1,C.wG,!1,C.cs)
 C.vb=new H.tx("profile")
 C.Mq=new A.ES(C.vb,C.BM,!1,C.BY,!1,C.cs)
 C.KK=new A.ES(C.uO,C.BM,!1,C.Gsc,!1,C.y0)
@@ -23190,8 +23224,8 @@
 C.lyV=new H.LPe(14,{domfocusout:"DOMFocusOut",domfocusin:"DOMFocusIn",dommousescroll:"DOMMouseScroll",animationend:"webkitAnimationEnd",animationiteration:"webkitAnimationIteration",animationstart:"webkitAnimationStart",doubleclick:"dblclick",fullscreenchange:"webkitfullscreenchange",fullscreenerror:"webkitfullscreenerror",keyadded:"webkitkeyadded",keyerror:"webkitkeyerror",keymessage:"webkitkeymessage",needkey:"webkitneedkey",speechchange:"webkitSpeechChange"},C.Vgv)
 C.rWc=I.uL(["name","extends","constructor","noscript","assetpath","cache-csstext","attributes"])
 C.pv=new H.LPe(7,{name:1,extends:1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1,attributes:1},C.rWc)
-C.Y1=I.uL(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==","!==","===",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
-C.w0=new H.LPe(29,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,"!==":7,"===":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.Y1)
+C.kKi=I.uL(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==","!==","===",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
+C.w0=new H.LPe(29,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,"!==":7,"===":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.kKi)
 C.MEG=I.uL(["enumerate"])
 C.mB=new H.LPe(1,{enumerate:K.HZg()},C.MEG)
 C.tq=H.K('Bo')
diff --git a/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html b/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html
index a08897a..070f578 100644
--- a/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html
+++ b/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html
@@ -4100,6 +4100,12 @@
     #classtable tr:hover > td {
       background-color: #F4C7C3;
     }
+    .nav-option {
+      color: white;
+      float: right;
+      margin: 3px;
+      padding: 8px;
+    }
   </style>
   <nav-bar>
     <top-nav-menu></top-nav-menu>
@@ -4108,6 +4114,9 @@
     <nav-refresh callback="{{ resetAccumulator }}" label="Reset Accumulator"></nav-refresh>
     <nav-refresh callback="{{ refreshGC }}" label="GC"></nav-refresh>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <div class="nav-option">
+      <input type="checkbox" checked="{{ autoRefresh }}">Auto-refresh on GC
+    </div>
     <nav-control></nav-control>
   </nav-bar>
   <div class="content">
@@ -4240,6 +4249,7 @@
 
 
 
+
 <polymer-element name="sliding-checkbox">
   <template>
     <style>
diff --git a/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html_bootstrap.dart.js b/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html_bootstrap.dart.js
index b0e84c5..6017b53 100644
--- a/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html_bootstrap.dart.js
+++ b/runtime/bin/vmservice/observatory/deployed/web/index_devtools.html_bootstrap.dart.js
@@ -1708,13 +1708,13 @@
 z=this.b
 for(y=0;y<z.length;++y){x=z[y]
 b.$2(x,this.Uf(x))}},
-gvc:function(a){return H.J(new H.AV(this),[H.u3(this,0)])},
+gvc:function(a){return H.J(new H.ph(this),[H.u3(this,0)])},
 gUQ:function(a){return H.fR(this.b,new H.hY(this),H.u3(this,0),H.u3(this,1))},
 $isyN:true},
 hY:{
 "^":"r:14;Q",
 $1:[function(a){return this.Q.Uf(a)},"$1",null,2,0,null,81,"call"]},
-AV:{
+ph:{
 "^":"mW;Q",
 gu:function(a){return J.Nx(this.Q.b)}},
 LI:{
@@ -2136,7 +2136,7 @@
 gFR:function(a){return a.kX},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.kX=this.ct(a,C.U,a.kX,b)},
+sFR:function(a,b){a.kX=this.ct(a,C.AV,a.kX,b)},
 gph:function(a){return a.RZ},
 sph:function(a,b){a.RZ=this.ct(a,C.hf,a.RZ,b)},
 gih:function(a){return a.ij},
@@ -2234,7 +2234,7 @@
 z.giG(b).ml(this.gm6())
 y=b.gG2()
 H.J(new P.rk(y),[H.u3(y,0)]).yI(this.glQ())
-J.HL(z.gRk(b)).yI(this.gPF())
+J.HL(z.gRk(b)).yI(this.gPF(this))
 z=b.gXs()
 H.J(new P.rk(z),[H.u3(z,0)]).yI(this.geO())}this.c=b},
 gvK:function(){return this.x},
@@ -2254,17 +2254,17 @@
 H.J(new W.Ov(0,y.Q,y.a,W.Yt(z.gTk()),y.b),[H.u3(y,0)]).P6()
 z.VA()},
 pZ:function(a){J.OP(this.x,new G.xE(a,new G.cE()))},
-rG:[function(a){var z=J.RE(a)
-switch(z.gfG(a)){case"IsolateCreated":break
-case"IsolateShutdown":this.pZ(z.god(a))
+rG:[function(a,b){var z=J.RE(b)
+switch(z.gfG(b)){case"IsolateCreated":break
+case"IsolateShutdown":this.pZ(z.god(b))
 break
-case"BreakpointResolved":z.god(a).Xb()
+case"BreakpointResolved":z.god(b).Xb()
 break
-case"BreakpointReached":case"IsolateInterrupted":case"ExceptionThrown":this.pZ(z.god(a))
-J.dH(this.x,a)
+case"BreakpointReached":case"IsolateInterrupted":case"ExceptionThrown":this.pZ(z.god(b))
+J.dH(this.x,b)
 break
 case"GC":break
-default:N.QM("").YX("Unrecognized event: "+H.d(a))
+default:N.QM("").YX("Unrecognized event: "+H.d(b))
 break}},"$1","gPF",2,0,86,87],
 Iu:[function(a){this.r=a
 this.aX("error/",null)},"$1","glQ",2,0,88,24],
@@ -2651,14 +2651,14 @@
 return J.WB(z,this.d?"\u25bc":"\u25b2")},"$1","gCO",2,0,16,101]}}],["","",,E,{
 "^":"",
 E24:[function(){var z,y,x
-z=P.B([C.S,new E.L(),C.N,new E.Q(),C.X,new E.O(),C.P,new E.Y(),C.V,new E.em(),C.Z,new E.Lb(),C.W,new E.QA(),C.ET,new E.Cv(),C.T,new E.ed(),C.M,new E.wa(),C.hR,new E.Or(),C.S4,new E.YL(),C.R,new E.wf(),C.hN,new E.Oa(),C.U,new E.emv(),C.bV,new E.Lbd(),C.C0,new E.QAa(),C.eZ,new E.CvS(),C.bk,new E.edy(),C.lH,new E.waE(),C.am,new E.Ore(),C.oE,new E.YLa(),C.kG,new E.wfa(),C.OI,new E.Oaa(),C.Wt,new E.e0(),C.I9,new E.e1(),C.To,new E.e2(),C.mM,new E.e3(),C.aw,new E.e4(),C.XA,new E.e5(),C.i4,new E.e6(),C.mJ,new E.e7(),C.qt,new E.e8(),C.p1,new E.e9(),C.yJ,new E.e10(),C.la,new E.e11(),C.yL,new E.e12(),C.nr,new E.e13(),C.bJ,new E.e14(),C.ox,new E.e15(),C.Je,new E.e16(),C.kI,new E.e17(),C.vY,new E.e18(),C.Rs,new E.e19(),C.hJ,new E.e20(),C.yC,new E.e21(),C.Lw,new E.e22(),C.eR,new E.e23(),C.LS,new E.e24(),C.iE,new E.e25(),C.f4,new E.e26(),C.VK,new E.e27(),C.aH,new E.e28(),C.aK,new E.e29(),C.GP,new E.e30(),C.mw,new E.e31(),C.vs,new E.e32(),C.Gr,new E.e33(),C.TU,new E.e34(),C.Fe,new E.e35(),C.tP,new E.e36(),C.yh,new E.e37(),C.Zb,new E.e38(),C.u7,new E.e39(),C.p8,new E.e40(),C.qR,new E.e41(),C.ld,new E.e42(),C.ne,new E.e43(),C.B0,new E.e44(),C.r1,new E.e45(),C.mr,new E.e46(),C.Ek,new E.e47(),C.Pn,new E.e48(),C.YT,new E.e49(),C.h7,new E.e50(),C.R3,new E.e51(),C.cJ,new E.e52(),C.WQ,new E.e53(),C.fV,new E.e54(),C.jU,new E.e55(),C.OO,new E.e56(),C.Mc,new E.e57(),C.FP,new E.e58(),C.kF,new E.e59(),C.UD,new E.e60(),C.Aq,new E.e61(),C.DS,new E.e62(),C.C9,new E.e63(),C.VF,new E.e64(),C.uU,new E.e65(),C.YJ,new E.e66(),C.EF,new E.e67(),C.oI,new E.e68(),C.ST,new E.e69(),C.QH,new E.e70(),C.qX,new E.e71(),C.rE,new E.e72(),C.nf,new E.e73(),C.EI,new E.e74(),C.JB,new E.e75(),C.RY,new E.e76(),C.d4,new E.e77(),C.cF,new E.e78(),C.ft,new E.e79(),C.dr,new E.e80(),C.SI,new E.e81(),C.zS,new E.e82(),C.YA,new E.e83(),C.Ge,new E.e84(),C.A7,new E.e85(),C.He,new E.e86(),C.im,new E.e87(),C.Ss,new E.e88(),C.k6,new E.e89(),C.oj,new E.e90(),C.PJ,new E.e91(),C.Yb,new E.e92(),C.q2,new E.e93(),C.d2,new E.e94(),C.kN,new E.e95(),C.uO,new E.e96(),C.fn,new E.e97(),C.yB,new E.e98(),C.eJ,new E.e99(),C.iG,new E.e100(),C.Py,new E.e101(),C.pC,new E.e102(),C.uu,new E.e103(),C.qs,new E.e104(),C.XH,new E.e105(),C.XJ,new E.e106(),C.tJ,new E.e107(),C.F8,new E.e108(),C.fy,new E.e109(),C.C1,new E.e110(),C.Nr,new E.e111(),C.nL,new E.e112(),C.a0,new E.e113(),C.Yg,new E.e114(),C.bR,new E.e115(),C.ai,new E.e116(),C.ob,new E.e117(),C.dR,new E.e118(),C.MY,new E.e119(),C.Wg,new E.e120(),C.tD,new E.e121(),C.QS,new E.e122(),C.C7,new E.e123(),C.nZ,new E.e124(),C.Of,new E.e125(),C.Vl,new E.e126(),C.pY,new E.e127(),C.XL,new E.e128(),C.LA,new E.e129(),C.Iw,new E.e130(),C.tz,new E.e131(),C.AT,new E.e132(),C.Lk,new E.e133(),C.GS,new E.e134(),C.rB,new E.e135(),C.bz,new E.e136(),C.Jx,new E.e137(),C.b5,new E.e138(),C.z6,new E.e139(),C.SY,new E.e140(),C.Lc,new E.e141(),C.hf,new E.e142(),C.uk,new E.e143(),C.Zi,new E.e144(),C.TN,new E.e145(),C.GI,new E.e146(),C.Wn,new E.e147(),C.ur,new E.e148(),C.VN,new E.e149(),C.EV,new E.e150(),C.VI,new E.e151(),C.eh,new E.e152(),C.SA,new E.e153(),C.uG,new E.e154(),C.kV,new E.e155(),C.vp,new E.e156(),C.cc,new E.e157(),C.DY,new E.e158(),C.Lx,new E.e159(),C.M3,new E.e160(),C.wT,new E.e161(),C.JK,new E.e162(),C.SR,new E.e163(),C.t6,new E.e164(),C.rP,new E.e165(),C.qi,new E.e166(),C.pX,new E.e167(),C.kB,new E.e168(),C.LH,new E.e169(),C.a2,new E.e170(),C.VD,new E.e171(),C.NN,new E.e172(),C.UX,new E.e173(),C.YS,new E.e174(),C.pu,new E.e175(),C.uw,new E.e176(),C.BJ,new E.e177(),C.c6,new E.e178(),C.td,new E.e179(),C.Gn,new E.e180(),C.zO,new E.e181(),C.vg,new E.e182(),C.Yp,new E.e183(),C.YV,new E.e184(),C.If,new E.e185(),C.Ys,new E.e186(),C.zm,new E.e187(),C.EP,new E.e188(),C.nX,new E.e189(),C.BV,new E.e190(),C.xP,new E.e191(),C.XM,new E.e192(),C.Ic,new E.e193(),C.yG,new E.e194(),C.uI,new E.e195(),C.O9,new E.e196(),C.ba,new E.e197(),C.tW,new E.e198(),C.CG,new E.e199(),C.Jf,new E.e200(),C.Wj,new E.e201(),C.vb,new E.e202(),C.UL,new E.e203(),C.AY,new E.e204(),C.QK,new E.e205(),C.AO,new E.e206(),C.Xd,new E.e207(),C.I7,new E.e208(),C.kY,new E.e209(),C.Wm,new E.e210(),C.vK,new E.e211(),C.Tc,new E.e212(),C.GR,new E.e213(),C.KX,new E.e214(),C.ja,new E.e215(),C.mn,new E.e216(),C.Dj,new E.e217(),C.ir,new E.e218(),C.dx,new E.e219(),C.ni,new E.e220(),C.X2,new E.e221(),C.F3,new E.e222(),C.UY,new E.e223(),C.Aa,new E.e224(),C.nY,new E.e225(),C.tg,new E.e226(),C.HD,new E.e227(),C.iU,new E.e228(),C.eN,new E.e229(),C.ue,new E.e230(),C.nh,new E.e231(),C.L2,new E.e232(),C.vm,new E.e233(),C.Gs,new E.e234(),C.bE,new E.e235(),C.YD,new E.e236(),C.PX,new E.e237(),C.N8,new E.e238(),C.FQ,new E.e239(),C.EA,new E.e240(),C.oW,new E.e241(),C.KC,new E.e242(),C.tf,new E.e243(),C.TI,new E.e244(),C.da,new E.e245(),C.Jd,new E.e246(),C.Y4,new E.e247(),C.Si,new E.e248(),C.pH,new E.e249(),C.Ve,new E.e250(),C.jM,new E.e251(),C.rd,new E.e252(),C.rX,new E.e253(),C.W5,new E.e254(),C.uX,new E.e255(),C.nt,new E.e256(),C.IT,new E.e257(),C.li,new E.e258(),C.PM,new E.e259(),C.ks,new E.e260(),C.Om,new E.e261(),C.iC,new E.e262(),C.Nv,new E.e263(),C.Wo,new E.e264(),C.FZ,new E.e265(),C.TW,new E.e266(),C.xS,new E.e267(),C.pD,new E.e268(),C.QF,new E.e269(),C.mi,new E.e270(),C.zz,new E.e271(),C.eO,new E.e272(),C.hO,new E.e273(),C.ei,new E.e274(),C.HK,new E.e275(),C.je,new E.e276(),C.Ef,new E.e277(),C.QL,new E.e278(),C.RH,new E.e279(),C.SP,new E.e280(),C.Q1,new E.e281(),C.ID,new E.e282(),C.dA,new E.e283(),C.bc,new E.e284(),C.nE,new E.e285(),C.ep,new E.e286(),C.hB,new E.e287(),C.J2,new E.e288(),C.hx,new E.e289(),C.zU,new E.e290(),C.OU,new E.e291(),C.bn,new E.e292(),C.mh,new E.e293(),C.Fh,new E.e294(),C.yv,new E.e295(),C.LP,new E.e296(),C.jh,new E.e297(),C.zd,new E.e298(),C.Db,new E.e299(),C.aF,new E.e300(),C.l4,new E.e301(),C.fj,new E.e302(),C.xw,new E.e303(),C.zn,new E.e304(),C.RJ,new E.e305(),C.Sk,new E.e306(),C.KS,new E.e307(),C.MA,new E.e308(),C.YE,new E.e309(),C.Uy,new E.e310()],null,null)
-y=P.B([C.S,new E.e311(),C.N,new E.e312(),C.P,new E.e313(),C.Z,new E.e314(),C.S4,new E.e315(),C.U,new E.e316(),C.bk,new E.e317(),C.lH,new E.e318(),C.am,new E.e319(),C.oE,new E.e320(),C.kG,new E.e321(),C.Wt,new E.e322(),C.mM,new E.e323(),C.aw,new E.e324(),C.XA,new E.e325(),C.i4,new E.e326(),C.mJ,new E.e327(),C.yL,new E.e328(),C.nr,new E.e329(),C.bJ,new E.e330(),C.kI,new E.e331(),C.vY,new E.e332(),C.yC,new E.e333(),C.VK,new E.e334(),C.aH,new E.e335(),C.GP,new E.e336(),C.vs,new E.e337(),C.Gr,new E.e338(),C.Fe,new E.e339(),C.tP,new E.e340(),C.yh,new E.e341(),C.Zb,new E.e342(),C.p8,new E.e343(),C.ld,new E.e344(),C.ne,new E.e345(),C.B0,new E.e346(),C.mr,new E.e347(),C.YT,new E.e348(),C.cJ,new E.e349(),C.WQ,new E.e350(),C.jU,new E.e351(),C.OO,new E.e352(),C.Mc,new E.e353(),C.QH,new E.e354(),C.rE,new E.e355(),C.nf,new E.e356(),C.ft,new E.e357(),C.Ge,new E.e358(),C.A7,new E.e359(),C.He,new E.e360(),C.oj,new E.e361(),C.d2,new E.e362(),C.uO,new E.e363(),C.fn,new E.e364(),C.yB,new E.e365(),C.Py,new E.e366(),C.uu,new E.e367(),C.qs,new E.e368(),C.rB,new E.e369(),C.z6,new E.e370(),C.hf,new E.e371(),C.uk,new E.e372(),C.Zi,new E.e373(),C.TN,new E.e374(),C.ur,new E.e375(),C.EV,new E.e376(),C.VI,new E.e377(),C.eh,new E.e378(),C.SA,new E.e379(),C.uG,new E.e380(),C.kV,new E.e381(),C.vp,new E.e382(),C.SR,new E.e383(),C.t6,new E.e384(),C.kB,new E.e385(),C.UX,new E.e386(),C.YS,new E.e387(),C.c6,new E.e388(),C.td,new E.e389(),C.zO,new E.e390(),C.Yp,new E.e391(),C.YV,new E.e392(),C.If,new E.e393(),C.Ys,new E.e394(),C.EP,new E.e395(),C.nX,new E.e396(),C.BV,new E.e397(),C.XM,new E.e398(),C.Ic,new E.e399(),C.O9,new E.e400(),C.tW,new E.e401(),C.Wj,new E.e402(),C.vb,new E.e403(),C.QK,new E.e404(),C.Xd,new E.e405(),C.kY,new E.e406(),C.vK,new E.e407(),C.Tc,new E.e408(),C.GR,new E.e409(),C.KX,new E.e410(),C.ja,new E.e411(),C.Dj,new E.e412(),C.X2,new E.e413(),C.UY,new E.e414(),C.Aa,new E.e415(),C.nY,new E.e416(),C.tg,new E.e417(),C.HD,new E.e418(),C.iU,new E.e419(),C.eN,new E.e420(),C.Gs,new E.e421(),C.bE,new E.e422(),C.YD,new E.e423(),C.PX,new E.e424(),C.FQ,new E.e425(),C.tf,new E.e426(),C.TI,new E.e427(),C.Jd,new E.e428(),C.pH,new E.e429(),C.Ve,new E.e430(),C.jM,new E.e431(),C.rd,new E.e432(),C.rX,new E.e433(),C.uX,new E.e434(),C.nt,new E.e435(),C.IT,new E.e436(),C.PM,new E.e437(),C.ks,new E.e438(),C.Om,new E.e439(),C.iC,new E.e440(),C.Nv,new E.e441(),C.FZ,new E.e442(),C.TW,new E.e443(),C.pD,new E.e444(),C.mi,new E.e445(),C.zz,new E.e446(),C.dA,new E.e447(),C.nE,new E.e448(),C.hx,new E.e449(),C.zU,new E.e450(),C.OU,new E.e451(),C.zd,new E.e452(),C.RJ,new E.e453(),C.YE,new E.e454()],null,null)
+z=P.B([C.S,new E.L(),C.N,new E.Q(),C.X,new E.O(),C.P,new E.Y(),C.V,new E.em(),C.Z,new E.Lb(),C.W,new E.QA(),C.ET,new E.Cv(),C.U,new E.ed(),C.T,new E.wa(),C.M,new E.Or(),C.hR,new E.YL(),C.S4,new E.wf(),C.R,new E.Oa(),C.hN,new E.emv(),C.AV,new E.Lbd(),C.bV,new E.QAa(),C.C0,new E.CvS(),C.eZ,new E.edy(),C.bk,new E.waE(),C.lH,new E.Ore(),C.am,new E.YLa(),C.oE,new E.wfa(),C.kG,new E.Oaa(),C.OI,new E.e0(),C.Wt,new E.e1(),C.I9,new E.e2(),C.To,new E.e3(),C.mM,new E.e4(),C.aw,new E.e5(),C.XA,new E.e6(),C.i4,new E.e7(),C.mJ,new E.e8(),C.qt,new E.e9(),C.p1,new E.e10(),C.yJ,new E.e11(),C.la,new E.e12(),C.yL,new E.e13(),C.nr,new E.e14(),C.bJ,new E.e15(),C.ox,new E.e16(),C.Je,new E.e17(),C.kI,new E.e18(),C.vY,new E.e19(),C.Rs,new E.e20(),C.hJ,new E.e21(),C.yC,new E.e22(),C.Lw,new E.e23(),C.eR,new E.e24(),C.LS,new E.e25(),C.iE,new E.e26(),C.f4,new E.e27(),C.VK,new E.e28(),C.aH,new E.e29(),C.aK,new E.e30(),C.GP,new E.e31(),C.mw,new E.e32(),C.vs,new E.e33(),C.Gr,new E.e34(),C.TU,new E.e35(),C.Fe,new E.e36(),C.tP,new E.e37(),C.yh,new E.e38(),C.Zb,new E.e39(),C.u7,new E.e40(),C.p8,new E.e41(),C.qR,new E.e42(),C.ld,new E.e43(),C.ne,new E.e44(),C.B0,new E.e45(),C.r1,new E.e46(),C.mr,new E.e47(),C.Ek,new E.e48(),C.Pn,new E.e49(),C.YT,new E.e50(),C.h7,new E.e51(),C.R3,new E.e52(),C.cJ,new E.e53(),C.WQ,new E.e54(),C.fV,new E.e55(),C.jU,new E.e56(),C.OO,new E.e57(),C.Mc,new E.e58(),C.FP,new E.e59(),C.kF,new E.e60(),C.UD,new E.e61(),C.Aq,new E.e62(),C.DS,new E.e63(),C.C9,new E.e64(),C.VF,new E.e65(),C.uU,new E.e66(),C.YJ,new E.e67(),C.EF,new E.e68(),C.oI,new E.e69(),C.ST,new E.e70(),C.QH,new E.e71(),C.qX,new E.e72(),C.rE,new E.e73(),C.nf,new E.e74(),C.EI,new E.e75(),C.JB,new E.e76(),C.RY,new E.e77(),C.d4,new E.e78(),C.cF,new E.e79(),C.ft,new E.e80(),C.dr,new E.e81(),C.SI,new E.e82(),C.zS,new E.e83(),C.YA,new E.e84(),C.Ge,new E.e85(),C.A7,new E.e86(),C.He,new E.e87(),C.im,new E.e88(),C.Ss,new E.e89(),C.k6,new E.e90(),C.oj,new E.e91(),C.PJ,new E.e92(),C.Yb,new E.e93(),C.q2,new E.e94(),C.d2,new E.e95(),C.kN,new E.e96(),C.uO,new E.e97(),C.fn,new E.e98(),C.yB,new E.e99(),C.eJ,new E.e100(),C.iG,new E.e101(),C.Py,new E.e102(),C.pC,new E.e103(),C.uu,new E.e104(),C.qs,new E.e105(),C.XH,new E.e106(),C.XJ,new E.e107(),C.tJ,new E.e108(),C.F8,new E.e109(),C.fy,new E.e110(),C.C1,new E.e111(),C.Nr,new E.e112(),C.nL,new E.e113(),C.a0,new E.e114(),C.Yg,new E.e115(),C.bR,new E.e116(),C.ai,new E.e117(),C.ob,new E.e118(),C.dR,new E.e119(),C.MY,new E.e120(),C.Wg,new E.e121(),C.tD,new E.e122(),C.QS,new E.e123(),C.C7,new E.e124(),C.nZ,new E.e125(),C.Of,new E.e126(),C.Vl,new E.e127(),C.pY,new E.e128(),C.XL,new E.e129(),C.LA,new E.e130(),C.Iw,new E.e131(),C.tz,new E.e132(),C.AT,new E.e133(),C.Lk,new E.e134(),C.GS,new E.e135(),C.rB,new E.e136(),C.bz,new E.e137(),C.Jx,new E.e138(),C.b5,new E.e139(),C.z6,new E.e140(),C.SY,new E.e141(),C.Lc,new E.e142(),C.hf,new E.e143(),C.uk,new E.e144(),C.Zi,new E.e145(),C.TN,new E.e146(),C.GI,new E.e147(),C.Wn,new E.e148(),C.ur,new E.e149(),C.VN,new E.e150(),C.EV,new E.e151(),C.VI,new E.e152(),C.eh,new E.e153(),C.SA,new E.e154(),C.uG,new E.e155(),C.kV,new E.e156(),C.vp,new E.e157(),C.cc,new E.e158(),C.DY,new E.e159(),C.Lx,new E.e160(),C.M3,new E.e161(),C.wT,new E.e162(),C.JK,new E.e163(),C.SR,new E.e164(),C.t6,new E.e165(),C.rP,new E.e166(),C.qi,new E.e167(),C.pX,new E.e168(),C.kB,new E.e169(),C.LH,new E.e170(),C.a2,new E.e171(),C.VD,new E.e172(),C.NN,new E.e173(),C.UX,new E.e174(),C.YS,new E.e175(),C.pu,new E.e176(),C.uw,new E.e177(),C.BJ,new E.e178(),C.c6,new E.e179(),C.td,new E.e180(),C.Gn,new E.e181(),C.zO,new E.e182(),C.vg,new E.e183(),C.Yp,new E.e184(),C.YV,new E.e185(),C.If,new E.e186(),C.Ys,new E.e187(),C.zm,new E.e188(),C.EP,new E.e189(),C.nX,new E.e190(),C.BV,new E.e191(),C.xP,new E.e192(),C.XM,new E.e193(),C.Ic,new E.e194(),C.yG,new E.e195(),C.uI,new E.e196(),C.O9,new E.e197(),C.ba,new E.e198(),C.tW,new E.e199(),C.CG,new E.e200(),C.Jf,new E.e201(),C.Wj,new E.e202(),C.vb,new E.e203(),C.UL,new E.e204(),C.AY,new E.e205(),C.QK,new E.e206(),C.AO,new E.e207(),C.Xd,new E.e208(),C.I7,new E.e209(),C.kY,new E.e210(),C.Wm,new E.e211(),C.vK,new E.e212(),C.Tc,new E.e213(),C.GR,new E.e214(),C.KX,new E.e215(),C.ja,new E.e216(),C.mn,new E.e217(),C.Dj,new E.e218(),C.ir,new E.e219(),C.dx,new E.e220(),C.ni,new E.e221(),C.X2,new E.e222(),C.F3,new E.e223(),C.UY,new E.e224(),C.Aa,new E.e225(),C.nY,new E.e226(),C.tg,new E.e227(),C.HD,new E.e228(),C.iU,new E.e229(),C.eN,new E.e230(),C.ue,new E.e231(),C.nh,new E.e232(),C.L2,new E.e233(),C.vm,new E.e234(),C.Gs,new E.e235(),C.bE,new E.e236(),C.YD,new E.e237(),C.PX,new E.e238(),C.N8,new E.e239(),C.FQ,new E.e240(),C.EA,new E.e241(),C.oW,new E.e242(),C.KC,new E.e243(),C.tf,new E.e244(),C.TI,new E.e245(),C.da,new E.e246(),C.Jd,new E.e247(),C.Y4,new E.e248(),C.Si,new E.e249(),C.pH,new E.e250(),C.Ve,new E.e251(),C.jM,new E.e252(),C.rd,new E.e253(),C.rX,new E.e254(),C.W5,new E.e255(),C.uX,new E.e256(),C.nt,new E.e257(),C.IT,new E.e258(),C.li,new E.e259(),C.PM,new E.e260(),C.ks,new E.e261(),C.Om,new E.e262(),C.iC,new E.e263(),C.Nv,new E.e264(),C.Wo,new E.e265(),C.FZ,new E.e266(),C.TW,new E.e267(),C.xS,new E.e268(),C.pD,new E.e269(),C.QF,new E.e270(),C.mi,new E.e271(),C.zz,new E.e272(),C.eO,new E.e273(),C.hO,new E.e274(),C.ei,new E.e275(),C.HK,new E.e276(),C.je,new E.e277(),C.Ef,new E.e278(),C.QL,new E.e279(),C.RH,new E.e280(),C.SP,new E.e281(),C.Q1,new E.e282(),C.ID,new E.e283(),C.dA,new E.e284(),C.bc,new E.e285(),C.nE,new E.e286(),C.ep,new E.e287(),C.hB,new E.e288(),C.J2,new E.e289(),C.hx,new E.e290(),C.zU,new E.e291(),C.OU,new E.e292(),C.bn,new E.e293(),C.mh,new E.e294(),C.Fh,new E.e295(),C.yv,new E.e296(),C.LP,new E.e297(),C.jh,new E.e298(),C.zd,new E.e299(),C.Db,new E.e300(),C.aF,new E.e301(),C.l4,new E.e302(),C.fj,new E.e303(),C.xw,new E.e304(),C.zn,new E.e305(),C.RJ,new E.e306(),C.Sk,new E.e307(),C.KS,new E.e308(),C.MA,new E.e309(),C.YE,new E.e310(),C.Uy,new E.e311()],null,null)
+y=P.B([C.S,new E.e312(),C.N,new E.e313(),C.P,new E.e314(),C.Z,new E.e315(),C.U,new E.e316(),C.S4,new E.e317(),C.AV,new E.e318(),C.bk,new E.e319(),C.lH,new E.e320(),C.am,new E.e321(),C.oE,new E.e322(),C.kG,new E.e323(),C.Wt,new E.e324(),C.mM,new E.e325(),C.aw,new E.e326(),C.XA,new E.e327(),C.i4,new E.e328(),C.mJ,new E.e329(),C.yL,new E.e330(),C.nr,new E.e331(),C.bJ,new E.e332(),C.kI,new E.e333(),C.vY,new E.e334(),C.yC,new E.e335(),C.VK,new E.e336(),C.aH,new E.e337(),C.GP,new E.e338(),C.vs,new E.e339(),C.Gr,new E.e340(),C.Fe,new E.e341(),C.tP,new E.e342(),C.yh,new E.e343(),C.Zb,new E.e344(),C.p8,new E.e345(),C.ld,new E.e346(),C.ne,new E.e347(),C.B0,new E.e348(),C.mr,new E.e349(),C.YT,new E.e350(),C.cJ,new E.e351(),C.WQ,new E.e352(),C.jU,new E.e353(),C.OO,new E.e354(),C.Mc,new E.e355(),C.QH,new E.e356(),C.rE,new E.e357(),C.nf,new E.e358(),C.ft,new E.e359(),C.Ge,new E.e360(),C.A7,new E.e361(),C.He,new E.e362(),C.oj,new E.e363(),C.d2,new E.e364(),C.uO,new E.e365(),C.fn,new E.e366(),C.yB,new E.e367(),C.Py,new E.e368(),C.uu,new E.e369(),C.qs,new E.e370(),C.rB,new E.e371(),C.z6,new E.e372(),C.hf,new E.e373(),C.uk,new E.e374(),C.Zi,new E.e375(),C.TN,new E.e376(),C.ur,new E.e377(),C.EV,new E.e378(),C.VI,new E.e379(),C.eh,new E.e380(),C.SA,new E.e381(),C.uG,new E.e382(),C.kV,new E.e383(),C.vp,new E.e384(),C.SR,new E.e385(),C.t6,new E.e386(),C.kB,new E.e387(),C.UX,new E.e388(),C.YS,new E.e389(),C.c6,new E.e390(),C.td,new E.e391(),C.zO,new E.e392(),C.Yp,new E.e393(),C.YV,new E.e394(),C.If,new E.e395(),C.Ys,new E.e396(),C.EP,new E.e397(),C.nX,new E.e398(),C.BV,new E.e399(),C.XM,new E.e400(),C.Ic,new E.e401(),C.O9,new E.e402(),C.tW,new E.e403(),C.Wj,new E.e404(),C.vb,new E.e405(),C.QK,new E.e406(),C.Xd,new E.e407(),C.kY,new E.e408(),C.vK,new E.e409(),C.Tc,new E.e410(),C.GR,new E.e411(),C.KX,new E.e412(),C.ja,new E.e413(),C.Dj,new E.e414(),C.X2,new E.e415(),C.UY,new E.e416(),C.Aa,new E.e417(),C.nY,new E.e418(),C.tg,new E.e419(),C.HD,new E.e420(),C.iU,new E.e421(),C.eN,new E.e422(),C.Gs,new E.e423(),C.bE,new E.e424(),C.YD,new E.e425(),C.PX,new E.e426(),C.FQ,new E.e427(),C.tf,new E.e428(),C.TI,new E.e429(),C.Jd,new E.e430(),C.pH,new E.e431(),C.Ve,new E.e432(),C.jM,new E.e433(),C.rd,new E.e434(),C.rX,new E.e435(),C.uX,new E.e436(),C.nt,new E.e437(),C.IT,new E.e438(),C.PM,new E.e439(),C.ks,new E.e440(),C.Om,new E.e441(),C.iC,new E.e442(),C.Nv,new E.e443(),C.FZ,new E.e444(),C.TW,new E.e445(),C.pD,new E.e446(),C.mi,new E.e447(),C.zz,new E.e448(),C.dA,new E.e449(),C.nE,new E.e450(),C.hx,new E.e451(),C.zU,new E.e452(),C.OU,new E.e453(),C.zd,new E.e454(),C.RJ,new E.e455(),C.YE,new E.e456()],null,null)
 x=P.B([C.K4,C.qJ,C.yS,C.Mt,C.OG,C.il,C.nw,C.Mt,C.ou,C.Mt,C.oT,C.il,C.jR,C.Mt,C.XW,C.il,C.kH,C.Mt,C.Lg,C.qJ,C.Wd,C.Mt,C.V7,C.Mt,C.V8,C.Mt,C.hM,C.Mt,C.JX,C.Mt,C.Bi,C.il,C.KO,C.Mt,C.wk,C.Mt,C.jA,C.qJ,C.Jo,C.il,C.Az,C.Mt,C.Vx,C.Mt,C.Qb,C.Mt,C.lE,C.al,C.te,C.Mt,C.iD,C.Mt,C.Ju,C.Mt,C.uC,C.Mt,C.Wz,C.il,C.Ke,C.Mt,C.pF,C.il,C.Wh,C.Mt,C.It,C.Mt,C.qZ,C.il,C.Zj,C.Mt,C.he,C.Mt,C.dD,C.al,C.hP,C.Mt,C.tc,C.Mt,C.rR,C.il,C.oG,C.Mt,C.mK,C.il,C.IZ,C.Mt,C.FG,C.il,C.pJ,C.Mt,C.tU,C.Mt,C.DD,C.Mt,C.Yy,C.il,C.Xv,C.Mt,C.ce,C.Mt,C.UJ,C.il,C.ca,C.Mt,C.Io,C.Mt,C.j4,C.Mt,C.EG,C.Mt,C.CT,C.Mt,C.mq,C.Mt,C.Tq,C.Mt,C.lp,C.il,C.PT,C.Mt,C.fU,C.Mt,C.pi,C.Mt,C.Fn,C.Mt,C.Ey,C.Mt,C.km,C.Mt,C.vw,C.Mt,C.LT,C.Mt,C.NW,C.Mz,C.ms,C.Mt,C.FA,C.Mt,C.Qt,C.Mt,C.a8,C.Mt,C.JW,C.Mt,C.Mf,C.Mt,C.rC,C.Mt,C.kq,C.Mt,C.Dl,C.Mt,C.Mz,C.qJ,C.Nw,C.Mt,C.ON,C.Mt,C.Sb,C.al,C.Th,C.Mt,C.wH,C.Mt,C.pK,C.Mt,C.R9,C.Mt,C.OZ,C.il,C.il,C.Mt,C.QJ,C.Mt,C.u4,C.Mt,C.X8,C.Mt,C.kt,C.Mt,C.Y3,C.qJ,C.bC,C.Mt,C.ws,C.Mt,C.cK,C.il,C.jK,C.Mt,C.qJ,C.jw,C.Mt,C.Mz,C.al,C.il],null,null)
-y=O.rH(!1,P.B([C.K4,P.B([C.S4,C.aj,C.U,C.Qp,C.mJ,C.Dx,C.hf,C.BT],null,null),C.yS,P.B([C.UX,C.Pt],null,null),C.OG,P.A(null,null),C.nw,P.B([C.rB,C.xY,C.bz,C.Bk],null,null),C.ou,P.B([C.XA,C.dq,C.yB,C.vZ,C.tg,C.DC],null,null),C.oT,P.B([C.i4,C.Qs,C.Wm,C.QW],null,null),C.jR,P.B([C.i4,C.aJ],null,null),C.XW,P.A(null,null),C.kH,P.B([C.nr,C.BO],null,null),C.Lg,P.B([C.S4,C.aj,C.U,C.Qp,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz],null,null),C.Wd,P.B([C.rB,C.RU],null,null),C.V7,P.B([C.S4,C.aj,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz,C.rE,C.B7,C.FQ,C.Ow],null,null),C.V8,P.B([C.rB,C.RU,C.mi,C.VB],null,null),C.hM,P.B([C.rB,C.RU,C.TI,C.NU],null,null),C.JX,P.B([C.N,C.ZX,C.rB,C.RU,C.bz,C.Bk,C.rX,C.Wp],null,null),C.Bi,P.A(null,null),C.KO,P.B([C.yh,C.tO],null,null),C.wk,P.B([C.U,C.k1,C.eh,C.IP,C.Aa,C.k5,C.mi,C.nH],null,null),C.jA,P.B([C.S4,C.aj,C.U,C.Qp,C.YT,C.LC,C.hf,C.BT,C.UY,C.n6],null,null),C.Jo,P.A(null,null),C.Az,P.B([C.WQ,C.on],null,null),C.Vx,P.B([C.OO,C.Cf],null,null),C.Qb,P.B([C.Mc,C.f0],null,null),C.lE,P.B([C.QK,C.P9],null,null),C.te,P.B([C.nf,C.wR],null,null),C.iD,P.B([C.QH,C.C4,C.qX,C.dO,C.PM,C.Jr],null,null),C.Ju,P.B([C.kG,C.Pr,C.rB,C.xY,C.Zi,C.vC,C.TN,C.K1,C.vb,C.Mq,C.UL,C.bG],null,null),C.uC,P.B([C.uO,C.KK,C.kY,C.rT],null,null),C.Wz,P.A(null,null),C.Ke,P.B([C.fn,C.Kk],null,null),C.pF,P.A(null,null),C.Wh,P.B([C.yL,C.j5],null,null),C.It,P.B([C.vp,C.o0],null,null),C.qZ,P.A(null,null),C.Zj,P.B([C.oj,C.GT],null,null),C.he,P.B([C.vp,C.o0],null,null),C.dD,P.B([C.pH,C.xV],null,null),C.hP,P.B([C.Wj,C.Ah],null,null),C.tc,P.B([C.vp,C.o0],null,null),C.rR,P.A(null,null),C.oG,P.B([C.jU,C.bw],null,null),C.mK,P.A(null,null),C.IZ,P.B([C.vp,C.o0],null,null),C.FG,P.A(null,null),C.pJ,P.B([C.Ve,C.X4],null,null),C.tU,P.B([C.qs,C.MN],null,null),C.DD,P.B([C.vp,C.o0],null,null),C.Yy,P.A(null,null),C.Xv,P.B([C.YE,C.Wl],null,null),C.ce,P.B([C.aH,C.Ei,C.He,C.fz,C.vb,C.Mq,C.UL,C.bG,C.Dj,C.kA,C.Gs,C.Wq,C.bE,C.Dh,C.YD,C.bl,C.TW,C.B3,C.xS,C.hd,C.zz,C.mb],null,null),C.UJ,P.A(null,null),C.ca,P.B([C.bJ,C.UI,C.ox,C.Rh],null,null),C.Io,P.B([C.rB,C.RU],null,null),C.j4,P.B([C.rB,C.RU],null,null),C.EG,P.B([C.rB,C.RU],null,null),C.CT,P.B([C.rB,C.RU],null,null),C.mq,P.B([C.rB,C.RU],null,null),C.Tq,P.B([C.SR,C.S9,C.t6,C.Hk,C.rP,C.Nt],null,null),C.lp,P.A(null,null),C.PT,P.B([C.EV,C.V0],null,null),C.fU,P.B([C.kB,C.nq,C.LH,C.oB,C.EP,C.db],null,null),C.pi,P.B([C.rB,C.xY,C.kB,C.nq,C.LH,C.oB],null,null),C.Fn,P.B([C.rB,C.xY,C.bz,C.Bk,C.EP,C.GO,C.tf,C.q6],null,null),C.Ey,P.B([C.XA,C.dq,C.uk,C.rY],null,null),C.km,P.B([C.rB,C.RU,C.bz,C.Bk,C.uk,C.rY],null,null),C.vw,P.B([C.uk,C.rY,C.EV,C.V0],null,null),C.LT,P.B([C.Ys,C.Cg],null,null),C.NW,P.A(null,null),C.ms,P.B([C.P,C.TE,C.uk,C.rY,C.kV,C.RZ],null,null),C.FA,P.B([C.P,C.TE,C.kV,C.RZ],null,null),C.Qt,P.B([C.ld,C.Gw],null,null),C.a8,P.B([C.p8,C.uc,C.ld,C.Gw],null,null),C.JW,P.B([C.S,C.oh,C.U,C.Qp,C.hf,C.BT],null,null),C.Mf,P.B([C.uk,C.rY],null,null),C.rC,P.B([C.uO,C.JT,C.td,C.Zk,C.XM,C.Tt,C.tg,C.DC],null,null),C.kq,P.B([C.td,C.Zk],null,null),C.Dl,P.B([C.VK,C.lW],null,null),C.Mz,P.B([C.O9,C.q9,C.ba,C.yV],null,null),C.Nw,P.B([C.S4,C.aj,C.VI,C.w6],null,null),C.ON,P.B([C.kI,C.Bf,C.vY,C.ZS,C.Rs,C.EW,C.vs,C.MP,C.Gr,C.VJ,C.TU,C.Cp,C.A7,C.cD,C.SA,C.KI,C.uG,C.Df,C.PX,C.jz,C.N8,C.qE,C.nt,C.VS,C.IT,C.NL,C.li,C.Tz],null,null),C.Sb,P.B([C.tW,C.Qc,C.CG,C.Ml],null,null),C.Th,P.B([C.PX,C.jz],null,null),C.wH,P.B([C.yh,C.lJ],null,null),C.pK,P.B([C.ne,C.bp],null,null),C.R9,P.B([C.kY,C.TO,C.Wm,C.QW],null,null),C.OZ,P.A(null,null),C.il,P.B([C.uu,C.NJ,C.kY,C.TO,C.Wm,C.QW],null,null),C.QJ,P.B([C.B0,C.iH,C.vp,C.Rz],null,null),C.u4,P.B([C.B0,C.iH,C.SR,C.hS],null,null),C.X8,P.B([C.Z,C.b7,C.td,C.Zk,C.Gn,C.az],null,null),C.kt,P.B([C.nE,C.FM],null,null),C.Y3,P.B([C.bk,C.NS,C.lH,C.M6,C.zU,C.OS],null,null),C.bC,P.B([C.am,C.JD,C.oE,C.py,C.uX,C.VM],null,null),C.ws,P.B([C.pD,C.Gz],null,null),C.cK,P.A(null,null),C.jK,P.B([C.yh,C.tO,C.RJ,C.BP],null,null)],null,null),z,P.B([C.S,"active",C.N,"activeFrame",C.X,"address",C.P,"anchor",C.V,"app",C.Z,"args",C.W,"asStringLiteral",C.ET,"assertsEnabled",C.T,"averageCollectionPeriodInMillis",C.M,"bpt",C.hR,"breakpoint",C.S4,"busy",C.R,"buttonClick",C.hN,"bytes",C.U,"callback",C.bV,"capacity",C.C0,"change",C.eZ,"changeSort",C.bk,"checked",C.lH,"checkedText",C.am,"chromeTargets",C.oE,"chromiumAddress",C.kG,"classTable",C.OI,"classes",C.Wt,"clazz",C.I9,"closeItem",C.To,"closing",C.mM,"closureCtxt",C.aw,"closureFunc",C.XA,"cls",C.i4,"code",C.mJ,"color",C.qt,"coloring",C.p1,"columns",C.yJ,"connectStandalone",C.la,"connectToVm",C.yL,"connection",C.nr,"context",C.bJ,"counters",C.ox,"countersChanged",C.Je,"current",C.kI,"currentLine",C.vY,"currentPos",C.Rs,"currentPosChanged",C.hJ,"dartMetrics",C.yC,"declaredType",C.Lw,"deleteVm",C.eR,"deoptimizations",C.LS,"description",C.iE,"descriptor",C.f4,"descriptors",C.VK,"devtools",C.aH,"displayCutoff",C.aK,"doAction",C.GP,"element",C.mw,"elements",C.vs,"endLine",C.Gr,"endPos",C.TU,"endPosChanged",C.Fe,"endTokenPos",C.tP,"entry",C.yh,"error",C.Zb,"eval",C.u7,"evalNow",C.p8,"event",C.qR,"eventType",C.ld,"events",C.ne,"exception",C.B0,"expand",C.r1,"expandChanged",C.mr,"expanded",C.Ek,"expander",C.Pn,"expanderStyle",C.YT,"expr",C.h7,"external",C.R3,"fd",C.cJ,"fetchInboundReferences",C.WQ,"field",C.fV,"fields",C.jU,"file",C.OO,"flag",C.Mc,"flagList",C.FP,"formatSize",C.kF,"formatTime",C.UD,"formattedAddress",C.Aq,"formattedAverage",C.DS,"formattedCollections",C.C9,"formattedDeoptId",C.VF,"formattedExclusive",C.uU,"formattedExclusiveTicks",C.YJ,"formattedInclusive",C.EF,"formattedInclusiveTicks",C.oI,"formattedLine",C.ST,"formattedTotalCollectionTime",C.QH,"fragmentation",C.qX,"fragmentationChanged",C.rE,"frame",C.nf,"function",C.EI,"functions",C.JB,"getColumnLabel",C.RY,"getTabs",C.d4,"goto",C.cF,"gotoLink",C.ft,"guardClass",C.dr,"guardNullable",C.SI,"hasDescriptors",C.zS,"hasDisassembly",C.YA,"hasNoAllocations",C.Ge,"hashLinkWorkaround",C.A7,"height",C.He,"hideTagsChecked",C.im,"history",C.Ss,"hits",C.k6,"hoverText",C.oj,"httpServer",C.PJ,"human",C.Yb,"id",C.q2,"idle",C.d2,"imp",C.kN,"imports",C.uO,"inboundReferences",C.fn,"instance",C.yB,"instances",C.eJ,"instruction",C.iG,"instructions",C.Py,"interface",C.pC,"interfaces",C.uu,"internal",C.qs,"io",C.XH,"isAbstract",C.XJ,"isAbstractType",C.tJ,"isBool",C.F8,"isChromeTarget",C.fy,"isClosure",C.C1,"isComment",C.Nr,"isConst",C.nL,"isCurrentTarget",C.a0,"isDart",C.Yg,"isDartCode",C.bR,"isDouble",C.ai,"isEmpty",C.ob,"isError",C.dR,"isFinal",C.MY,"isInlinable",C.Wg,"isInt",C.tD,"isList",C.QS,"isMap",C.C7,"isMirrorReference",C.nZ,"isNotEmpty",C.Of,"isNull",C.Vl,"isOptimizable",C.pY,"isOptimized",C.XL,"isPatch",C.LA,"isPipe",C.Iw,"isPlainInstance",C.tz,"isSentinel",C.AT,"isStatic",C.Lk,"isString",C.GS,"isWeakProperty",C.rB,"isolate",C.bz,"isolateChanged",C.Jx,"isolates",C.b5,"jumpTarget",C.z6,"key",C.SY,"keys",C.Lc,"kind",C.hf,"label",C.uk,"last",C.Zi,"lastAccumulatorReset",C.TN,"lastServiceGC",C.GI,"lastUpdate",C.Wn,"length",C.ur,"lib",C.VN,"libraries",C.EV,"library",C.VI,"line",C.eh,"lineMode",C.SA,"lines",C.uG,"linesReady",C.kV,"link",C.vp,"list",C.cc,"listening",C.DY,"loading",C.Lx,"localAddress",C.M3,"localPort",C.wT,"mainPort",C.JK,"makeLineId",C.SR,"map",C.t6,"mapAsString",C.rP,"mapChanged",C.qi,"max",C.pX,"message",C.kB,"metric",C.LH,"metricChanged",C.a2,"min",C.VD,"mouseOut",C.NN,"mouseOver",C.UX,"msg",C.YS,"name",C.pu,"nameIsEmpty",C.uw,"nativeFields",C.BJ,"newSpace",C.c6,"notifications",C.td,"object",C.Gn,"objectChanged",C.zO,"objectPool",C.vg,"oldSpace",C.Yp,"owner",C.YV,"owningClass",C.If,"owningLibrary",C.Ys,"pad",C.zm,"padding",C.EP,"page",C.nX,"parent",C.BV,"parentContext",C.xP,"parseInt",C.XM,"path",C.Ic,"pause",C.yG,"pauseEvent",C.uI,"pid",C.O9,"pollPeriod",C.ba,"pollPeriodChanged",C.tW,"pos",C.CG,"posChanged",C.Jf,"possibleBpt",C.Wj,"process",C.vb,"profile",C.UL,"profileChanged",C.AY,"protocol",C.QK,"qualified",C.AO,"qualifiedName",C.Xd,"reachable",C.I7,"readClosed",C.kY,"ref",C.Wm,"refChanged",C.vK,"reference",C.Tc,"referent",C.GR,"refresh",C.KX,"refreshCoverage",C.ja,"refreshGC",C.mn,"refreshRateChange",C.Dj,"refreshTime",C.ir,"relativeLink",C.dx,"remoteAddress",C.ni,"remotePort",C.X2,"resetAccumulator",C.F3,"response",C.UY,"result",C.Aa,"results",C.nY,"resume",C.tg,"retainedBytes",C.HD,"retainedSize",C.iU,"retainingPath",C.eN,"rootLib",C.ue,"row",C.nh,"rows",C.L2,"running",C.vm,"sampleBufferSizeChange",C.Gs,"sampleCount",C.bE,"sampleDepth",C.YD,"sampleRate",C.PX,"script",C.N8,"scriptChanged",C.FQ,"scriptHeight",C.EA,"scripts",C.oW,"selectExpr",C.KC,"selectMetric",C.tf,"selectedMetric",C.TI,"showConsole",C.da,"size",C.Jd,"slot",C.Y4,"slotIsArrayIndex",C.Si,"slotIsField",C.pH,"small",C.Ve,"socket",C.jM,"socketOwner",C.rd,"source",C.rX,"stack",C.W5,"standalone",C.uX,"standaloneVmAddress",C.nt,"startLine",C.IT,"startPos",C.li,"startPosChanged",C.PM,"status",C.ks,"stepInto",C.Om,"stepOut",C.iC,"stepOver",C.Nv,"subclass",C.Wo,"subclasses",C.FZ,"superclass",C.TW,"tagSelector",C.xS,"tagSelectorChanged",C.pD,"target",C.QF,"targets",C.mi,"text",C.zz,"timeSpan",C.eO,"timeStamp",C.hO,"tipExclusive",C.ei,"tipKind",C.HK,"tipParent",C.je,"tipTicks",C.Ef,"tipTime",C.QL,"toString",C.RH,"toStringAsFixed",C.SP,"toggleBreakpoint",C.Q1,"toggleExpand",C.ID,"toggleExpanded",C.dA,"tokenPos",C.bc,"topFrame",C.nE,"tracer",C.ep,"tree",C.hB,"type",C.J2,"typeChecksEnabled",C.hx,"typeClass",C.zU,"uncheckedText",C.OU,"unoptimizedCode",C.bn,"updateLineMode",C.mh,"uptime",C.Fh,"url",C.yv,"usageCounter",C.LP,"used",C.jh,"v",C.zd,"value",C.Db,"valueAsString",C.aF,"valueAsStringIsTruncated",C.l4,"values",C.fj,"variable",C.xw,"variables",C.zn,"version",C.RJ,"vm",C.Sk,"vmMetrics",C.KS,"vmName",C.MA,"vmType",C.YE,"webSocket",C.Uy,"writeClosed"],null,null),x,y,null)
+y=O.rH(!1,P.B([C.K4,P.B([C.S4,C.aj,C.AV,C.Qp,C.mJ,C.Dx,C.hf,C.BT],null,null),C.yS,P.B([C.UX,C.Pt],null,null),C.OG,P.A(null,null),C.nw,P.B([C.rB,C.xY,C.bz,C.Bk],null,null),C.ou,P.B([C.XA,C.dq,C.yB,C.vZ,C.tg,C.DC],null,null),C.oT,P.B([C.i4,C.Qs,C.Wm,C.QW],null,null),C.jR,P.B([C.i4,C.aJ],null,null),C.XW,P.A(null,null),C.kH,P.B([C.nr,C.BO],null,null),C.Lg,P.B([C.S4,C.aj,C.AV,C.Qp,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz],null,null),C.Wd,P.B([C.rB,C.RU],null,null),C.V7,P.B([C.S4,C.aj,C.B0,C.iH,C.r1,C.nP,C.mr,C.iz,C.rE,C.B7,C.FQ,C.Ow],null,null),C.V8,P.B([C.rB,C.RU,C.mi,C.VB],null,null),C.hM,P.B([C.rB,C.RU,C.TI,C.NU],null,null),C.JX,P.B([C.N,C.ZX,C.rB,C.RU,C.bz,C.Bk,C.rX,C.Wp],null,null),C.Bi,P.A(null,null),C.KO,P.B([C.yh,C.tO],null,null),C.wk,P.B([C.AV,C.k1,C.eh,C.IP,C.Aa,C.k5,C.mi,C.nH],null,null),C.jA,P.B([C.S4,C.aj,C.AV,C.Qp,C.YT,C.LC,C.hf,C.BT,C.UY,C.n6],null,null),C.Jo,P.A(null,null),C.Az,P.B([C.WQ,C.on],null,null),C.Vx,P.B([C.OO,C.Cf],null,null),C.Qb,P.B([C.Mc,C.f0],null,null),C.lE,P.B([C.QK,C.P9],null,null),C.te,P.B([C.nf,C.wR],null,null),C.iD,P.B([C.QH,C.C4,C.qX,C.dO,C.PM,C.Jr],null,null),C.Ju,P.B([C.U,C.br,C.kG,C.Pr,C.rB,C.xY,C.Zi,C.vC,C.TN,C.K1,C.vb,C.Mq,C.UL,C.bG],null,null),C.uC,P.B([C.uO,C.KK,C.kY,C.rT],null,null),C.Wz,P.A(null,null),C.Ke,P.B([C.fn,C.Kk],null,null),C.pF,P.A(null,null),C.Wh,P.B([C.yL,C.j5],null,null),C.It,P.B([C.vp,C.o0],null,null),C.qZ,P.A(null,null),C.Zj,P.B([C.oj,C.GT],null,null),C.he,P.B([C.vp,C.o0],null,null),C.dD,P.B([C.pH,C.xV],null,null),C.hP,P.B([C.Wj,C.Ah],null,null),C.tc,P.B([C.vp,C.o0],null,null),C.rR,P.A(null,null),C.oG,P.B([C.jU,C.bw],null,null),C.mK,P.A(null,null),C.IZ,P.B([C.vp,C.o0],null,null),C.FG,P.A(null,null),C.pJ,P.B([C.Ve,C.X4],null,null),C.tU,P.B([C.qs,C.MN],null,null),C.DD,P.B([C.vp,C.o0],null,null),C.Yy,P.A(null,null),C.Xv,P.B([C.YE,C.Wl],null,null),C.ce,P.B([C.aH,C.Ei,C.He,C.fz,C.vb,C.Mq,C.UL,C.bG,C.Dj,C.kA,C.Gs,C.Wq,C.bE,C.Dh,C.YD,C.bl,C.TW,C.B3,C.xS,C.hd,C.zz,C.mb],null,null),C.UJ,P.A(null,null),C.ca,P.B([C.bJ,C.UI,C.ox,C.Rh],null,null),C.Io,P.B([C.rB,C.RU],null,null),C.j4,P.B([C.rB,C.RU],null,null),C.EG,P.B([C.rB,C.RU],null,null),C.CT,P.B([C.rB,C.RU],null,null),C.mq,P.B([C.rB,C.RU],null,null),C.Tq,P.B([C.SR,C.S9,C.t6,C.Hk,C.rP,C.Nt],null,null),C.lp,P.A(null,null),C.PT,P.B([C.EV,C.V0],null,null),C.fU,P.B([C.kB,C.nq,C.LH,C.oB,C.EP,C.db],null,null),C.pi,P.B([C.rB,C.xY,C.kB,C.nq,C.LH,C.oB],null,null),C.Fn,P.B([C.rB,C.xY,C.bz,C.Bk,C.EP,C.GO,C.tf,C.q6],null,null),C.Ey,P.B([C.XA,C.dq,C.uk,C.rY],null,null),C.km,P.B([C.rB,C.RU,C.bz,C.Bk,C.uk,C.rY],null,null),C.vw,P.B([C.uk,C.rY,C.EV,C.V0],null,null),C.LT,P.B([C.Ys,C.Cg],null,null),C.NW,P.A(null,null),C.ms,P.B([C.P,C.TE,C.uk,C.rY,C.kV,C.RZ],null,null),C.FA,P.B([C.P,C.TE,C.kV,C.RZ],null,null),C.Qt,P.B([C.ld,C.Gw],null,null),C.a8,P.B([C.p8,C.uc,C.ld,C.Gw],null,null),C.JW,P.B([C.S,C.oh,C.AV,C.Qp,C.hf,C.BT],null,null),C.Mf,P.B([C.uk,C.rY],null,null),C.rC,P.B([C.uO,C.JT,C.td,C.Zk,C.XM,C.Tt,C.tg,C.DC],null,null),C.kq,P.B([C.td,C.Zk],null,null),C.Dl,P.B([C.VK,C.lW],null,null),C.Mz,P.B([C.O9,C.q9,C.ba,C.yV],null,null),C.Nw,P.B([C.S4,C.aj,C.VI,C.w6],null,null),C.ON,P.B([C.kI,C.Bf,C.vY,C.ZS,C.Rs,C.EW,C.vs,C.MP,C.Gr,C.VJ,C.TU,C.Cp,C.A7,C.cD,C.SA,C.KI,C.uG,C.Df,C.PX,C.jz,C.N8,C.qE,C.nt,C.VS,C.IT,C.NL,C.li,C.Tz],null,null),C.Sb,P.B([C.tW,C.Qc,C.CG,C.Ml],null,null),C.Th,P.B([C.PX,C.jz],null,null),C.wH,P.B([C.yh,C.lJ],null,null),C.pK,P.B([C.ne,C.bp],null,null),C.R9,P.B([C.kY,C.TO,C.Wm,C.QW],null,null),C.OZ,P.A(null,null),C.il,P.B([C.uu,C.NJ,C.kY,C.TO,C.Wm,C.QW],null,null),C.QJ,P.B([C.B0,C.iH,C.vp,C.Rz],null,null),C.u4,P.B([C.B0,C.iH,C.SR,C.hS],null,null),C.X8,P.B([C.Z,C.b7,C.td,C.Zk,C.Gn,C.az],null,null),C.kt,P.B([C.nE,C.FM],null,null),C.Y3,P.B([C.bk,C.NS,C.lH,C.M6,C.zU,C.OS],null,null),C.bC,P.B([C.am,C.JD,C.oE,C.py,C.uX,C.VM],null,null),C.ws,P.B([C.pD,C.Gz],null,null),C.cK,P.A(null,null),C.jK,P.B([C.yh,C.tO,C.RJ,C.BP],null,null)],null,null),z,P.B([C.S,"active",C.N,"activeFrame",C.X,"address",C.P,"anchor",C.V,"app",C.Z,"args",C.W,"asStringLiteral",C.ET,"assertsEnabled",C.U,"autoRefresh",C.T,"averageCollectionPeriodInMillis",C.M,"bpt",C.hR,"breakpoint",C.S4,"busy",C.R,"buttonClick",C.hN,"bytes",C.AV,"callback",C.bV,"capacity",C.C0,"change",C.eZ,"changeSort",C.bk,"checked",C.lH,"checkedText",C.am,"chromeTargets",C.oE,"chromiumAddress",C.kG,"classTable",C.OI,"classes",C.Wt,"clazz",C.I9,"closeItem",C.To,"closing",C.mM,"closureCtxt",C.aw,"closureFunc",C.XA,"cls",C.i4,"code",C.mJ,"color",C.qt,"coloring",C.p1,"columns",C.yJ,"connectStandalone",C.la,"connectToVm",C.yL,"connection",C.nr,"context",C.bJ,"counters",C.ox,"countersChanged",C.Je,"current",C.kI,"currentLine",C.vY,"currentPos",C.Rs,"currentPosChanged",C.hJ,"dartMetrics",C.yC,"declaredType",C.Lw,"deleteVm",C.eR,"deoptimizations",C.LS,"description",C.iE,"descriptor",C.f4,"descriptors",C.VK,"devtools",C.aH,"displayCutoff",C.aK,"doAction",C.GP,"element",C.mw,"elements",C.vs,"endLine",C.Gr,"endPos",C.TU,"endPosChanged",C.Fe,"endTokenPos",C.tP,"entry",C.yh,"error",C.Zb,"eval",C.u7,"evalNow",C.p8,"event",C.qR,"eventType",C.ld,"events",C.ne,"exception",C.B0,"expand",C.r1,"expandChanged",C.mr,"expanded",C.Ek,"expander",C.Pn,"expanderStyle",C.YT,"expr",C.h7,"external",C.R3,"fd",C.cJ,"fetchInboundReferences",C.WQ,"field",C.fV,"fields",C.jU,"file",C.OO,"flag",C.Mc,"flagList",C.FP,"formatSize",C.kF,"formatTime",C.UD,"formattedAddress",C.Aq,"formattedAverage",C.DS,"formattedCollections",C.C9,"formattedDeoptId",C.VF,"formattedExclusive",C.uU,"formattedExclusiveTicks",C.YJ,"formattedInclusive",C.EF,"formattedInclusiveTicks",C.oI,"formattedLine",C.ST,"formattedTotalCollectionTime",C.QH,"fragmentation",C.qX,"fragmentationChanged",C.rE,"frame",C.nf,"function",C.EI,"functions",C.JB,"getColumnLabel",C.RY,"getTabs",C.d4,"goto",C.cF,"gotoLink",C.ft,"guardClass",C.dr,"guardNullable",C.SI,"hasDescriptors",C.zS,"hasDisassembly",C.YA,"hasNoAllocations",C.Ge,"hashLinkWorkaround",C.A7,"height",C.He,"hideTagsChecked",C.im,"history",C.Ss,"hits",C.k6,"hoverText",C.oj,"httpServer",C.PJ,"human",C.Yb,"id",C.q2,"idle",C.d2,"imp",C.kN,"imports",C.uO,"inboundReferences",C.fn,"instance",C.yB,"instances",C.eJ,"instruction",C.iG,"instructions",C.Py,"interface",C.pC,"interfaces",C.uu,"internal",C.qs,"io",C.XH,"isAbstract",C.XJ,"isAbstractType",C.tJ,"isBool",C.F8,"isChromeTarget",C.fy,"isClosure",C.C1,"isComment",C.Nr,"isConst",C.nL,"isCurrentTarget",C.a0,"isDart",C.Yg,"isDartCode",C.bR,"isDouble",C.ai,"isEmpty",C.ob,"isError",C.dR,"isFinal",C.MY,"isInlinable",C.Wg,"isInt",C.tD,"isList",C.QS,"isMap",C.C7,"isMirrorReference",C.nZ,"isNotEmpty",C.Of,"isNull",C.Vl,"isOptimizable",C.pY,"isOptimized",C.XL,"isPatch",C.LA,"isPipe",C.Iw,"isPlainInstance",C.tz,"isSentinel",C.AT,"isStatic",C.Lk,"isString",C.GS,"isWeakProperty",C.rB,"isolate",C.bz,"isolateChanged",C.Jx,"isolates",C.b5,"jumpTarget",C.z6,"key",C.SY,"keys",C.Lc,"kind",C.hf,"label",C.uk,"last",C.Zi,"lastAccumulatorReset",C.TN,"lastServiceGC",C.GI,"lastUpdate",C.Wn,"length",C.ur,"lib",C.VN,"libraries",C.EV,"library",C.VI,"line",C.eh,"lineMode",C.SA,"lines",C.uG,"linesReady",C.kV,"link",C.vp,"list",C.cc,"listening",C.DY,"loading",C.Lx,"localAddress",C.M3,"localPort",C.wT,"mainPort",C.JK,"makeLineId",C.SR,"map",C.t6,"mapAsString",C.rP,"mapChanged",C.qi,"max",C.pX,"message",C.kB,"metric",C.LH,"metricChanged",C.a2,"min",C.VD,"mouseOut",C.NN,"mouseOver",C.UX,"msg",C.YS,"name",C.pu,"nameIsEmpty",C.uw,"nativeFields",C.BJ,"newSpace",C.c6,"notifications",C.td,"object",C.Gn,"objectChanged",C.zO,"objectPool",C.vg,"oldSpace",C.Yp,"owner",C.YV,"owningClass",C.If,"owningLibrary",C.Ys,"pad",C.zm,"padding",C.EP,"page",C.nX,"parent",C.BV,"parentContext",C.xP,"parseInt",C.XM,"path",C.Ic,"pause",C.yG,"pauseEvent",C.uI,"pid",C.O9,"pollPeriod",C.ba,"pollPeriodChanged",C.tW,"pos",C.CG,"posChanged",C.Jf,"possibleBpt",C.Wj,"process",C.vb,"profile",C.UL,"profileChanged",C.AY,"protocol",C.QK,"qualified",C.AO,"qualifiedName",C.Xd,"reachable",C.I7,"readClosed",C.kY,"ref",C.Wm,"refChanged",C.vK,"reference",C.Tc,"referent",C.GR,"refresh",C.KX,"refreshCoverage",C.ja,"refreshGC",C.mn,"refreshRateChange",C.Dj,"refreshTime",C.ir,"relativeLink",C.dx,"remoteAddress",C.ni,"remotePort",C.X2,"resetAccumulator",C.F3,"response",C.UY,"result",C.Aa,"results",C.nY,"resume",C.tg,"retainedBytes",C.HD,"retainedSize",C.iU,"retainingPath",C.eN,"rootLib",C.ue,"row",C.nh,"rows",C.L2,"running",C.vm,"sampleBufferSizeChange",C.Gs,"sampleCount",C.bE,"sampleDepth",C.YD,"sampleRate",C.PX,"script",C.N8,"scriptChanged",C.FQ,"scriptHeight",C.EA,"scripts",C.oW,"selectExpr",C.KC,"selectMetric",C.tf,"selectedMetric",C.TI,"showConsole",C.da,"size",C.Jd,"slot",C.Y4,"slotIsArrayIndex",C.Si,"slotIsField",C.pH,"small",C.Ve,"socket",C.jM,"socketOwner",C.rd,"source",C.rX,"stack",C.W5,"standalone",C.uX,"standaloneVmAddress",C.nt,"startLine",C.IT,"startPos",C.li,"startPosChanged",C.PM,"status",C.ks,"stepInto",C.Om,"stepOut",C.iC,"stepOver",C.Nv,"subclass",C.Wo,"subclasses",C.FZ,"superclass",C.TW,"tagSelector",C.xS,"tagSelectorChanged",C.pD,"target",C.QF,"targets",C.mi,"text",C.zz,"timeSpan",C.eO,"timeStamp",C.hO,"tipExclusive",C.ei,"tipKind",C.HK,"tipParent",C.je,"tipTicks",C.Ef,"tipTime",C.QL,"toString",C.RH,"toStringAsFixed",C.SP,"toggleBreakpoint",C.Q1,"toggleExpand",C.ID,"toggleExpanded",C.dA,"tokenPos",C.bc,"topFrame",C.nE,"tracer",C.ep,"tree",C.hB,"type",C.J2,"typeChecksEnabled",C.hx,"typeClass",C.zU,"uncheckedText",C.OU,"unoptimizedCode",C.bn,"updateLineMode",C.mh,"uptime",C.Fh,"url",C.yv,"usageCounter",C.LP,"used",C.jh,"v",C.zd,"value",C.Db,"valueAsString",C.aF,"valueAsStringIsTruncated",C.l4,"values",C.fj,"variable",C.xw,"variables",C.zn,"version",C.RJ,"vm",C.Sk,"vmMetrics",C.KS,"vmName",C.MA,"vmType",C.YE,"webSocket",C.Uy,"writeClosed"],null,null),x,y,null)
 $.j8=new O.fH(y)
 $.Yv=new O.mO(y)
 $.qe=new O.ut(y)
-$.MU=[new E.e455(),new E.e456(),new E.e457(),new E.e458(),new E.e459(),new E.e460(),new E.e461(),new E.e462(),new E.e463(),new E.e464(),new E.e465(),new E.e466(),new E.e467(),new E.e468(),new E.e469(),new E.e470(),new E.e471(),new E.e472(),new E.e473(),new E.e474(),new E.e475(),new E.e476(),new E.e477(),new E.e478(),new E.e479(),new E.e480(),new E.e481(),new E.e482(),new E.e483(),new E.e484(),new E.e485(),new E.e486(),new E.e487(),new E.e488(),new E.e489(),new E.e490(),new E.e491(),new E.e492(),new E.e493(),new E.e494(),new E.e495(),new E.e496(),new E.e497(),new E.e498(),new E.e499(),new E.e500(),new E.e501(),new E.e502(),new E.e503(),new E.e504(),new E.e505(),new E.e506(),new E.e507(),new E.e508(),new E.e509(),new E.e510(),new E.e511(),new E.e512(),new E.e513(),new E.e514(),new E.e515(),new E.e516(),new E.e517(),new E.e518(),new E.e519(),new E.e520(),new E.e521(),new E.e522(),new E.e523(),new E.e524(),new E.e525(),new E.e526(),new E.e527(),new E.e528(),new E.e529(),new E.e530(),new E.e531(),new E.e532(),new E.e533(),new E.e534(),new E.e535(),new E.e536(),new E.e537(),new E.e538(),new E.e539(),new E.e540(),new E.e541(),new E.e542(),new E.e543(),new E.e544(),new E.e545(),new E.e546(),new E.e547(),new E.e548(),new E.e549(),new E.e550()]
+$.MU=[new E.e457(),new E.e458(),new E.e459(),new E.e460(),new E.e461(),new E.e462(),new E.e463(),new E.e464(),new E.e465(),new E.e466(),new E.e467(),new E.e468(),new E.e469(),new E.e470(),new E.e471(),new E.e472(),new E.e473(),new E.e474(),new E.e475(),new E.e476(),new E.e477(),new E.e478(),new E.e479(),new E.e480(),new E.e481(),new E.e482(),new E.e483(),new E.e484(),new E.e485(),new E.e486(),new E.e487(),new E.e488(),new E.e489(),new E.e490(),new E.e491(),new E.e492(),new E.e493(),new E.e494(),new E.e495(),new E.e496(),new E.e497(),new E.e498(),new E.e499(),new E.e500(),new E.e501(),new E.e502(),new E.e503(),new E.e504(),new E.e505(),new E.e506(),new E.e507(),new E.e508(),new E.e509(),new E.e510(),new E.e511(),new E.e512(),new E.e513(),new E.e514(),new E.e515(),new E.e516(),new E.e517(),new E.e518(),new E.e519(),new E.e520(),new E.e521(),new E.e522(),new E.e523(),new E.e524(),new E.e525(),new E.e526(),new E.e527(),new E.e528(),new E.e529(),new E.e530(),new E.e531(),new E.e532(),new E.e533(),new E.e534(),new E.e535(),new E.e536(),new E.e537(),new E.e538(),new E.e539(),new E.e540(),new E.e541(),new E.e542(),new E.e543(),new E.e544(),new E.e545(),new E.e546(),new E.e547(),new E.e548(),new E.e549(),new E.e550(),new E.e551(),new E.e552()]
 $.UG=!0
 F.E2()},"$0","VQk",0,0,1],
 L:{
@@ -2687,1704 +2687,1710 @@
 $1:[function(a){return a.gA3()},"$1",null,2,0,null,65,"call"]},
 ed:{
 "^":"r:14;",
-$1:[function(a){return a.goX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dX(a)},"$1",null,2,0,null,65,"call"]},
 wa:{
 "^":"r:14;",
-$1:[function(a){return a.gqr()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.goX()},"$1",null,2,0,null,65,"call"]},
 Or:{
 "^":"r:14;",
-$1:[function(a){return a.gYZ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gqr()},"$1",null,2,0,null,65,"call"]},
 YL:{
 "^":"r:14;",
-$1:[function(a){return J.zL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gYZ()},"$1",null,2,0,null,65,"call"]},
 wf:{
 "^":"r:14;",
-$1:[function(a){return J.aAQ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zL(a)},"$1",null,2,0,null,65,"call"]},
 Oa:{
 "^":"r:14;",
-$1:[function(a){return a.gET()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.aAQ(a)},"$1",null,2,0,null,65,"call"]},
 emv:{
 "^":"r:14;",
-$1:[function(a){return J.WT(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gET()},"$1",null,2,0,null,65,"call"]},
 Lbd:{
 "^":"r:14;",
-$1:[function(a){return a.gCs()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WT(a)},"$1",null,2,0,null,65,"call"]},
 QAa:{
 "^":"r:14;",
-$1:[function(a){return J.XB(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gCs()},"$1",null,2,0,null,65,"call"]},
 CvS:{
 "^":"r:14;",
-$1:[function(a){return J.n9(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.XB(a)},"$1",null,2,0,null,65,"call"]},
 edy:{
 "^":"r:14;",
-$1:[function(a){return J.rp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.n9(a)},"$1",null,2,0,null,65,"call"]},
 waE:{
 "^":"r:14;",
-$1:[function(a){return J.BS2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.rp(a)},"$1",null,2,0,null,65,"call"]},
 Ore:{
 "^":"r:14;",
-$1:[function(a){return J.LL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.BS2(a)},"$1",null,2,0,null,65,"call"]},
 YLa:{
 "^":"r:14;",
-$1:[function(a){return J.h3(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.LL(a)},"$1",null,2,0,null,65,"call"]},
 wfa:{
 "^":"r:14;",
-$1:[function(a){return J.AJ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.h3(a)},"$1",null,2,0,null,65,"call"]},
 Oaa:{
 "^":"r:14;",
-$1:[function(a){return J.pP(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.AJ(a)},"$1",null,2,0,null,65,"call"]},
 e0:{
 "^":"r:14;",
-$1:[function(a){return a.gUP()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pP(a)},"$1",null,2,0,null,65,"call"]},
 e1:{
 "^":"r:14;",
-$1:[function(a){return J.RC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUP()},"$1",null,2,0,null,65,"call"]},
 e2:{
 "^":"r:14;",
-$1:[function(a){return a.gSf()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.RC(a)},"$1",null,2,0,null,65,"call"]},
 e3:{
 "^":"r:14;",
-$1:[function(a){return a.gu5()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSf()},"$1",null,2,0,null,65,"call"]},
 e4:{
 "^":"r:14;",
-$1:[function(a){return a.gwz()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gu5()},"$1",null,2,0,null,65,"call"]},
 e5:{
 "^":"r:14;",
-$1:[function(a){return J.L6(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gwz()},"$1",null,2,0,null,65,"call"]},
 e6:{
 "^":"r:14;",
-$1:[function(a){return J.tX(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.L6(a)},"$1",null,2,0,null,65,"call"]},
 e7:{
 "^":"r:14;",
-$1:[function(a){return J.zF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.tX(a)},"$1",null,2,0,null,65,"call"]},
 e8:{
 "^":"r:14;",
-$1:[function(a){return J.lK(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zF(a)},"$1",null,2,0,null,65,"call"]},
 e9:{
 "^":"r:14;",
-$1:[function(a){return J.Al(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.lK(a)},"$1",null,2,0,null,65,"call"]},
 e10:{
 "^":"r:14;",
-$1:[function(a){return J.Mh(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Al(a)},"$1",null,2,0,null,65,"call"]},
 e11:{
 "^":"r:14;",
-$1:[function(a){return J.nC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Mh(a)},"$1",null,2,0,null,65,"call"]},
 e12:{
 "^":"r:14;",
-$1:[function(a){return J.xe(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.nC(a)},"$1",null,2,0,null,65,"call"]},
 e13:{
 "^":"r:14;",
-$1:[function(a){return J.Ux(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.xe(a)},"$1",null,2,0,null,65,"call"]},
 e14:{
 "^":"r:14;",
-$1:[function(a){return J.OT(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ux(a)},"$1",null,2,0,null,65,"call"]},
 e15:{
 "^":"r:14;",
-$1:[function(a){return J.Okq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.OT(a)},"$1",null,2,0,null,65,"call"]},
 e16:{
 "^":"r:14;",
-$1:[function(a){return a.gk()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Okq(a)},"$1",null,2,0,null,65,"call"]},
 e17:{
 "^":"r:14;",
-$1:[function(a){return J.h6(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gk()},"$1",null,2,0,null,65,"call"]},
 e18:{
 "^":"r:14;",
-$1:[function(a){return J.kc(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.h6(a)},"$1",null,2,0,null,65,"call"]},
 e19:{
 "^":"r:14;",
-$1:[function(a){return J.P3(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.kc(a)},"$1",null,2,0,null,65,"call"]},
 e20:{
 "^":"r:14;",
-$1:[function(a){return a.gpG()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.P3(a)},"$1",null,2,0,null,65,"call"]},
 e21:{
 "^":"r:14;",
-$1:[function(a){return a.gOF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gpG()},"$1",null,2,0,null,65,"call"]},
 e22:{
 "^":"r:14;",
-$1:[function(a){return J.TG(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gOF()},"$1",null,2,0,null,65,"call"]},
 e23:{
 "^":"r:14;",
-$1:[function(a){return a.gOs()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.TG(a)},"$1",null,2,0,null,65,"call"]},
 e24:{
 "^":"r:14;",
-$1:[function(a){return a.gN0()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gOs()},"$1",null,2,0,null,65,"call"]},
 e25:{
 "^":"r:14;",
-$1:[function(a){return a.gSL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gN0()},"$1",null,2,0,null,65,"call"]},
 e26:{
 "^":"r:14;",
-$1:[function(a){return a.guH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSL()},"$1",null,2,0,null,65,"call"]},
 e27:{
 "^":"r:14;",
-$1:[function(a){return J.mP(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.guH()},"$1",null,2,0,null,65,"call"]},
 e28:{
 "^":"r:14;",
-$1:[function(a){return J.fe(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.mP(a)},"$1",null,2,0,null,65,"call"]},
 e29:{
 "^":"r:14;",
-$1:[function(a){return J.dn(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fe(a)},"$1",null,2,0,null,65,"call"]},
 e30:{
 "^":"r:14;",
-$1:[function(a){return J.y3(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dn(a)},"$1",null,2,0,null,65,"call"]},
 e31:{
 "^":"r:14;",
-$1:[function(a){return J.YH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.y3(a)},"$1",null,2,0,null,65,"call"]},
 e32:{
 "^":"r:14;",
-$1:[function(a){return J.k0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.YH(a)},"$1",null,2,0,null,65,"call"]},
 e33:{
 "^":"r:14;",
-$1:[function(a){return J.yr(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.k0(a)},"$1",null,2,0,null,65,"call"]},
 e34:{
 "^":"r:14;",
-$1:[function(a){return J.lk(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.yr(a)},"$1",null,2,0,null,65,"call"]},
 e35:{
 "^":"r:14;",
-$1:[function(a){return a.gLK()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.lk(a)},"$1",null,2,0,null,65,"call"]},
 e36:{
 "^":"r:14;",
-$1:[function(a){return a.gw2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gLK()},"$1",null,2,0,null,65,"call"]},
 e37:{
 "^":"r:14;",
-$1:[function(a){return J.w8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gw2()},"$1",null,2,0,null,65,"call"]},
 e38:{
 "^":"r:14;",
-$1:[function(a){return J.ht(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.w8(a)},"$1",null,2,0,null,65,"call"]},
 e39:{
 "^":"r:14;",
-$1:[function(a){return J.Pp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ht(a)},"$1",null,2,0,null,65,"call"]},
 e40:{
 "^":"r:14;",
-$1:[function(a){return J.qf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Pp(a)},"$1",null,2,0,null,65,"call"]},
 e41:{
 "^":"r:14;",
-$1:[function(a){return J.Ts(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.qf(a)},"$1",null,2,0,null,65,"call"]},
 e42:{
 "^":"r:14;",
-$1:[function(a){return J.um(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ts(a)},"$1",null,2,0,null,65,"call"]},
 e43:{
 "^":"r:14;",
-$1:[function(a){return J.io(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.um(a)},"$1",null,2,0,null,65,"call"]},
 e44:{
 "^":"r:14;",
-$1:[function(a){return J.UE(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.io(a)},"$1",null,2,0,null,65,"call"]},
 e45:{
 "^":"r:14;",
-$1:[function(a){return J.Ak(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.UE(a)},"$1",null,2,0,null,65,"call"]},
 e46:{
 "^":"r:14;",
-$1:[function(a){return J.IL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ak(a)},"$1",null,2,0,null,65,"call"]},
 e47:{
 "^":"r:14;",
-$1:[function(a){return J.nb(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.IL(a)},"$1",null,2,0,null,65,"call"]},
 e48:{
 "^":"r:14;",
-$1:[function(a){return a.gty()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.nb(a)},"$1",null,2,0,null,65,"call"]},
 e49:{
 "^":"r:14;",
-$1:[function(a){return J.Ua(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gty()},"$1",null,2,0,null,65,"call"]},
 e50:{
 "^":"r:14;",
-$1:[function(a){return a.gMX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ua(a)},"$1",null,2,0,null,65,"call"]},
 e51:{
 "^":"r:14;",
-$1:[function(a){return a.gkE()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gMX()},"$1",null,2,0,null,65,"call"]},
 e52:{
 "^":"r:14;",
-$1:[function(a){return J.E1(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkE()},"$1",null,2,0,null,65,"call"]},
 e53:{
 "^":"r:14;",
-$1:[function(a){return J.Nb(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.E1(a)},"$1",null,2,0,null,65,"call"]},
 e54:{
 "^":"r:14;",
-$1:[function(a){return a.gtJ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Nb(a)},"$1",null,2,0,null,65,"call"]},
 e55:{
 "^":"r:14;",
-$1:[function(a){return J.vE(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gtJ()},"$1",null,2,0,null,65,"call"]},
 e56:{
 "^":"r:14;",
-$1:[function(a){return J.dw(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.vE(a)},"$1",null,2,0,null,65,"call"]},
 e57:{
 "^":"r:14;",
-$1:[function(a){return J.QZ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dw(a)},"$1",null,2,0,null,65,"call"]},
 e58:{
 "^":"r:14;",
-$1:[function(a){return J.WX7(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QZ(a)},"$1",null,2,0,null,65,"call"]},
 e59:{
 "^":"r:14;",
-$1:[function(a){return J.QvL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WX7(a)},"$1",null,2,0,null,65,"call"]},
 e60:{
 "^":"r:14;",
-$1:[function(a){return a.gZd()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QvL(a)},"$1",null,2,0,null,65,"call"]},
 e61:{
 "^":"r:14;",
-$1:[function(a){return J.TM(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZd()},"$1",null,2,0,null,65,"call"]},
 e62:{
 "^":"r:14;",
-$1:[function(a){return J.xo(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.TM(a)},"$1",null,2,0,null,65,"call"]},
 e63:{
 "^":"r:14;",
-$1:[function(a){return a.gkA()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.xo(a)},"$1",null,2,0,null,65,"call"]},
 e64:{
 "^":"r:14;",
-$1:[function(a){return a.gAX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkA()},"$1",null,2,0,null,65,"call"]},
 e65:{
 "^":"r:14;",
-$1:[function(a){return a.ga3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gAX()},"$1",null,2,0,null,65,"call"]},
 e66:{
 "^":"r:14;",
-$1:[function(a){return a.gcQ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.ga3()},"$1",null,2,0,null,65,"call"]},
 e67:{
 "^":"r:14;",
-$1:[function(a){return a.gS7()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gcQ()},"$1",null,2,0,null,65,"call"]},
 e68:{
 "^":"r:14;",
-$1:[function(a){return a.gP3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gS7()},"$1",null,2,0,null,65,"call"]},
 e69:{
 "^":"r:14;",
-$1:[function(a){return J.wm(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gP3()},"$1",null,2,0,null,65,"call"]},
 e70:{
 "^":"r:14;",
-$1:[function(a){return J.bu(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wm(a)},"$1",null,2,0,null,65,"call"]},
 e71:{
 "^":"r:14;",
-$1:[function(a){return J.iq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.bu(a)},"$1",null,2,0,null,65,"call"]},
 e72:{
 "^":"r:14;",
-$1:[function(a){return J.zN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.iq(a)},"$1",null,2,0,null,65,"call"]},
 e73:{
 "^":"r:14;",
-$1:[function(a){return J.m4(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zN(a)},"$1",null,2,0,null,65,"call"]},
 e74:{
 "^":"r:14;",
-$1:[function(a){return a.gjV()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.m4(a)},"$1",null,2,0,null,65,"call"]},
 e75:{
 "^":"r:14;",
-$1:[function(a){return a.gCO()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gjV()},"$1",null,2,0,null,65,"call"]},
 e76:{
 "^":"r:14;",
-$1:[function(a){return J.yf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gCO()},"$1",null,2,0,null,65,"call"]},
 e77:{
 "^":"r:14;",
-$1:[function(a){return J.i2U(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.yf(a)},"$1",null,2,0,null,65,"call"]},
 e78:{
 "^":"r:14;",
-$1:[function(a){return J.Ay(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.i2U(a)},"$1",null,2,0,null,65,"call"]},
 e79:{
 "^":"r:14;",
-$1:[function(a){return a.gZD()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ay(a)},"$1",null,2,0,null,65,"call"]},
 e80:{
 "^":"r:14;",
-$1:[function(a){return a.gRl()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZD()},"$1",null,2,0,null,65,"call"]},
 e81:{
 "^":"r:14;",
-$1:[function(a){return a.gvN()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gRl()},"$1",null,2,0,null,65,"call"]},
 e82:{
 "^":"r:14;",
-$1:[function(a){return a.gUa()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvN()},"$1",null,2,0,null,65,"call"]},
 e83:{
 "^":"r:14;",
-$1:[function(a){return a.gMp()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUa()},"$1",null,2,0,null,65,"call"]},
 e84:{
 "^":"r:14;",
-$1:[function(a){return J.Er(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gMp()},"$1",null,2,0,null,65,"call"]},
 e85:{
 "^":"r:14;",
-$1:[function(a){return J.Jv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Er(a)},"$1",null,2,0,null,65,"call"]},
 e86:{
 "^":"r:14;",
-$1:[function(a){return J.z8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Jv(a)},"$1",null,2,0,null,65,"call"]},
 e87:{
 "^":"r:14;",
-$1:[function(a){return J.Xf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.z8(a)},"$1",null,2,0,null,65,"call"]},
 e88:{
 "^":"r:14;",
-$1:[function(a){return a.gc1()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Xf(a)},"$1",null,2,0,null,65,"call"]},
 e89:{
 "^":"r:14;",
-$1:[function(a){return J.aW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gc1()},"$1",null,2,0,null,65,"call"]},
 e90:{
 "^":"r:14;",
-$1:[function(a){return J.hW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.aW(a)},"$1",null,2,0,null,65,"call"]},
 e91:{
 "^":"r:14;",
-$1:[function(a){return a.gu0()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.hW(a)},"$1",null,2,0,null,65,"call"]},
 e92:{
 "^":"r:14;",
-$1:[function(a){return J.eS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gu0()},"$1",null,2,0,null,65,"call"]},
 e93:{
 "^":"r:14;",
-$1:[function(a){return a.gaj()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.eS(a)},"$1",null,2,0,null,65,"call"]},
 e94:{
 "^":"r:14;",
-$1:[function(a){return a.giq()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gaj()},"$1",null,2,0,null,65,"call"]},
 e95:{
 "^":"r:14;",
-$1:[function(a){return a.gPb()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.giq()},"$1",null,2,0,null,65,"call"]},
 e96:{
 "^":"r:14;",
-$1:[function(a){return J.tl(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gPb()},"$1",null,2,0,null,65,"call"]},
 e97:{
 "^":"r:14;",
-$1:[function(a){return J.Ir(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.tl(a)},"$1",null,2,0,null,65,"call"]},
 e98:{
 "^":"r:14;",
-$1:[function(a){return J.US(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ir(a)},"$1",null,2,0,null,65,"call"]},
 e99:{
 "^":"r:14;",
-$1:[function(a){return a.gNI()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.US(a)},"$1",null,2,0,null,65,"call"]},
 e100:{
 "^":"r:14;",
-$1:[function(a){return a.gGA()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gNI()},"$1",null,2,0,null,65,"call"]},
 e101:{
 "^":"r:14;",
-$1:[function(a){return a.gKt()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gGA()},"$1",null,2,0,null,65,"call"]},
 e102:{
 "^":"r:14;",
-$1:[function(a){return a.gp2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gKt()},"$1",null,2,0,null,65,"call"]},
 e103:{
 "^":"r:14;",
-$1:[function(a){return J.oH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gp2()},"$1",null,2,0,null,65,"call"]},
 e104:{
 "^":"r:14;",
-$1:[function(a){return J.Ew(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.oH(a)},"$1",null,2,0,null,65,"call"]},
 e105:{
 "^":"r:14;",
-$1:[function(a){return a.gvo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ew(a)},"$1",null,2,0,null,65,"call"]},
 e106:{
 "^":"r:14;",
-$1:[function(a){return a.glO()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvo()},"$1",null,2,0,null,65,"call"]},
 e107:{
 "^":"r:14;",
-$1:[function(a){return a.gjS()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.glO()},"$1",null,2,0,null,65,"call"]},
 e108:{
 "^":"r:14;",
-$1:[function(a){return J.v9(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gjS()},"$1",null,2,0,null,65,"call"]},
 e109:{
 "^":"r:14;",
-$1:[function(a){return a.gBF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.v9(a)},"$1",null,2,0,null,65,"call"]},
 e110:{
 "^":"r:14;",
-$1:[function(a){return a.gUB()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gBF()},"$1",null,2,0,null,65,"call"]},
 e111:{
 "^":"r:14;",
-$1:[function(a){return a.gRh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUB()},"$1",null,2,0,null,65,"call"]},
 e112:{
 "^":"r:14;",
-$1:[function(a){return J.id(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gRh()},"$1",null,2,0,null,65,"call"]},
 e113:{
 "^":"r:14;",
-$1:[function(a){return a.gni()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.id(a)},"$1",null,2,0,null,65,"call"]},
 e114:{
 "^":"r:14;",
-$1:[function(a){return a.gkU()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gni()},"$1",null,2,0,null,65,"call"]},
 e115:{
 "^":"r:14;",
-$1:[function(a){return a.gzx()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkU()},"$1",null,2,0,null,65,"call"]},
 e116:{
 "^":"r:14;",
-$1:[function(a){return J.FN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gzx()},"$1",null,2,0,null,65,"call"]},
 e117:{
 "^":"r:14;",
-$1:[function(a){return a.gt3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.FN(a)},"$1",null,2,0,null,65,"call"]},
 e118:{
 "^":"r:14;",
-$1:[function(a){return J.or(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gt3()},"$1",null,2,0,null,65,"call"]},
 e119:{
 "^":"r:14;",
-$1:[function(a){return a.gxL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.or(a)},"$1",null,2,0,null,65,"call"]},
 e120:{
 "^":"r:14;",
-$1:[function(a){return a.gSO()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gxL()},"$1",null,2,0,null,65,"call"]},
 e121:{
 "^":"r:14;",
-$1:[function(a){return J.Zo(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSO()},"$1",null,2,0,null,65,"call"]},
 e122:{
 "^":"r:14;",
-$1:[function(a){return J.GGs(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zo(a)},"$1",null,2,0,null,65,"call"]},
 e123:{
 "^":"r:14;",
-$1:[function(a){return a.gOC()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.GGs(a)},"$1",null,2,0,null,65,"call"]},
 e124:{
 "^":"r:14;",
-$1:[function(a){return J.pO(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gOC()},"$1",null,2,0,null,65,"call"]},
 e125:{
 "^":"r:14;",
-$1:[function(a){return a.gHh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pO(a)},"$1",null,2,0,null,65,"call"]},
 e126:{
 "^":"r:14;",
-$1:[function(a){return a.gW1()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gHh()},"$1",null,2,0,null,65,"call"]},
 e127:{
 "^":"r:14;",
-$1:[function(a){return a.goF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gW1()},"$1",null,2,0,null,65,"call"]},
 e128:{
 "^":"r:14;",
-$1:[function(a){return a.geh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.goF()},"$1",null,2,0,null,65,"call"]},
 e129:{
 "^":"r:14;",
-$1:[function(a){return a.gHY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.geh()},"$1",null,2,0,null,65,"call"]},
 e130:{
 "^":"r:14;",
-$1:[function(a){return a.gXM()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gHY()},"$1",null,2,0,null,65,"call"]},
 e131:{
 "^":"r:14;",
-$1:[function(a){return a.gfo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gXM()},"$1",null,2,0,null,65,"call"]},
 e132:{
 "^":"r:14;",
-$1:[function(a){return a.gFo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gfo()},"$1",null,2,0,null,65,"call"]},
 e133:{
 "^":"r:14;",
-$1:[function(a){return a.gu7()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gFo()},"$1",null,2,0,null,65,"call"]},
 e134:{
 "^":"r:14;",
-$1:[function(a){return a.gl2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gu7()},"$1",null,2,0,null,65,"call"]},
 e135:{
 "^":"r:14;",
-$1:[function(a){return J.wg(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gl2()},"$1",null,2,0,null,65,"call"]},
 e136:{
 "^":"r:14;",
-$1:[function(a){return J.q0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wg(a)},"$1",null,2,0,null,65,"call"]},
 e137:{
 "^":"r:14;",
-$1:[function(a){return a.gi2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.q0(a)},"$1",null,2,0,null,65,"call"]},
 e138:{
 "^":"r:14;",
-$1:[function(a){return a.gSS()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gi2()},"$1",null,2,0,null,65,"call"]},
 e139:{
 "^":"r:14;",
-$1:[function(a){return J.Kt(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSS()},"$1",null,2,0,null,65,"call"]},
 e140:{
 "^":"r:14;",
-$1:[function(a){return J.q8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Kt(a)},"$1",null,2,0,null,65,"call"]},
 e141:{
 "^":"r:14;",
-$1:[function(a){return J.Iz(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.q8(a)},"$1",null,2,0,null,65,"call"]},
 e142:{
 "^":"r:14;",
-$1:[function(a){return J.ZC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Iz(a)},"$1",null,2,0,null,65,"call"]},
 e143:{
 "^":"r:14;",
-$1:[function(a){return J.rn(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ZC(a)},"$1",null,2,0,null,65,"call"]},
 e144:{
 "^":"r:14;",
-$1:[function(a){return J.X7(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.rn(a)},"$1",null,2,0,null,65,"call"]},
 e145:{
 "^":"r:14;",
-$1:[function(a){return J.IR(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.X7(a)},"$1",null,2,0,null,65,"call"]},
 e146:{
 "^":"r:14;",
-$1:[function(a){return a.gPE()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.IR(a)},"$1",null,2,0,null,65,"call"]},
 e147:{
 "^":"r:14;",
-$1:[function(a){return J.wS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gPE()},"$1",null,2,0,null,65,"call"]},
 e148:{
 "^":"r:14;",
-$1:[function(a){return a.gcI()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wS(a)},"$1",null,2,0,null,65,"call"]},
 e149:{
 "^":"r:14;",
-$1:[function(a){return a.gvU()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gcI()},"$1",null,2,0,null,65,"call"]},
 e150:{
 "^":"r:14;",
-$1:[function(a){return J.ik(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvU()},"$1",null,2,0,null,65,"call"]},
 e151:{
 "^":"r:14;",
-$1:[function(a){return J.f2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ik(a)},"$1",null,2,0,null,65,"call"]},
 e152:{
 "^":"r:14;",
-$1:[function(a){return J.zY(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.f2(a)},"$1",null,2,0,null,65,"call"]},
 e153:{
 "^":"r:14;",
-$1:[function(a){return J.de(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zY(a)},"$1",null,2,0,null,65,"call"]},
 e154:{
 "^":"r:14;",
-$1:[function(a){return J.t0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.de(a)},"$1",null,2,0,null,65,"call"]},
 e155:{
 "^":"r:14;",
-$1:[function(a){return J.Ds(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.t0(a)},"$1",null,2,0,null,65,"call"]},
 e156:{
 "^":"r:14;",
-$1:[function(a){return J.cO(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ds(a)},"$1",null,2,0,null,65,"call"]},
 e157:{
 "^":"r:14;",
-$1:[function(a){return a.gzM()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.cO(a)},"$1",null,2,0,null,65,"call"]},
 e158:{
 "^":"r:14;",
-$1:[function(a){return a.gn0()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gzM()},"$1",null,2,0,null,65,"call"]},
 e159:{
 "^":"r:14;",
-$1:[function(a){return a.giP()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gn0()},"$1",null,2,0,null,65,"call"]},
 e160:{
 "^":"r:14;",
-$1:[function(a){return a.gmd()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.giP()},"$1",null,2,0,null,65,"call"]},
 e161:{
 "^":"r:14;",
-$1:[function(a){return a.gIT()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gmd()},"$1",null,2,0,null,65,"call"]},
 e162:{
 "^":"r:14;",
-$1:[function(a){return J.pr(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gIT()},"$1",null,2,0,null,65,"call"]},
 e163:{
 "^":"r:14;",
-$1:[function(a){return J.Yf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pr(a)},"$1",null,2,0,null,65,"call"]},
 e164:{
 "^":"r:14;",
-$1:[function(a){return J.kv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Yf(a)},"$1",null,2,0,null,65,"call"]},
 e165:{
 "^":"r:14;",
-$1:[function(a){return J.QD(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.kv(a)},"$1",null,2,0,null,65,"call"]},
 e166:{
 "^":"r:14;",
-$1:[function(a){return J.jE(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QD(a)},"$1",null,2,0,null,65,"call"]},
 e167:{
 "^":"r:14;",
-$1:[function(a){return J.Oh(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jE(a)},"$1",null,2,0,null,65,"call"]},
 e168:{
 "^":"r:14;",
-$1:[function(a){return J.qx(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Oh(a)},"$1",null,2,0,null,65,"call"]},
 e169:{
 "^":"r:14;",
-$1:[function(a){return J.Kv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.qx(a)},"$1",null,2,0,null,65,"call"]},
 e170:{
 "^":"r:14;",
-$1:[function(a){return J.LY4(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Kv(a)},"$1",null,2,0,null,65,"call"]},
 e171:{
 "^":"r:14;",
-$1:[function(a){return J.ZF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.LY4(a)},"$1",null,2,0,null,65,"call"]},
 e172:{
 "^":"r:14;",
-$1:[function(a){return J.PW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ZF(a)},"$1",null,2,0,null,65,"call"]},
 e173:{
 "^":"r:14;",
-$1:[function(a){return J.Zv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.PW(a)},"$1",null,2,0,null,65,"call"]},
 e174:{
 "^":"r:14;",
-$1:[function(a){return J.DA(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zv(a)},"$1",null,2,0,null,65,"call"]},
 e175:{
 "^":"r:14;",
-$1:[function(a){return J.Pf(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.DA(a)},"$1",null,2,0,null,65,"call"]},
 e176:{
 "^":"r:14;",
-$1:[function(a){return a.gDm()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Pf(a)},"$1",null,2,0,null,65,"call"]},
 e177:{
 "^":"r:14;",
-$1:[function(a){return a.gUY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gDm()},"$1",null,2,0,null,65,"call"]},
 e178:{
 "^":"r:14;",
-$1:[function(a){return a.gvK()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUY()},"$1",null,2,0,null,65,"call"]},
 e179:{
 "^":"r:14;",
-$1:[function(a){return J.mk(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gvK()},"$1",null,2,0,null,65,"call"]},
 e180:{
 "^":"r:14;",
-$1:[function(a){return J.t8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.mk(a)},"$1",null,2,0,null,65,"call"]},
 e181:{
 "^":"r:14;",
-$1:[function(a){return a.gL1()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.t8(a)},"$1",null,2,0,null,65,"call"]},
 e182:{
 "^":"r:14;",
-$1:[function(a){return a.gxQ()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gL1()},"$1",null,2,0,null,65,"call"]},
 e183:{
 "^":"r:14;",
-$1:[function(a){return a.gXP()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gxQ()},"$1",null,2,0,null,65,"call"]},
 e184:{
 "^":"r:14;",
-$1:[function(a){return a.gP2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gXP()},"$1",null,2,0,null,65,"call"]},
 e185:{
 "^":"r:14;",
-$1:[function(a){return a.gxH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gP2()},"$1",null,2,0,null,65,"call"]},
 e186:{
 "^":"r:14;",
-$1:[function(a){return J.qN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gxH()},"$1",null,2,0,null,65,"call"]},
 e187:{
 "^":"r:14;",
-$1:[function(a){return J.mF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.qN(a)},"$1",null,2,0,null,65,"call"]},
 e188:{
 "^":"r:14;",
-$1:[function(a){return J.MT(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.mF(a)},"$1",null,2,0,null,65,"call"]},
 e189:{
 "^":"r:14;",
-$1:[function(a){return J.Lp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.MT(a)},"$1",null,2,0,null,65,"call"]},
 e190:{
 "^":"r:14;",
-$1:[function(a){return a.gqH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Lp(a)},"$1",null,2,0,null,65,"call"]},
 e191:{
 "^":"r:14;",
-$1:[function(a){return J.UZ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gqH()},"$1",null,2,0,null,65,"call"]},
 e192:{
 "^":"r:14;",
-$1:[function(a){return J.WN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.UZ(a)},"$1",null,2,0,null,65,"call"]},
 e193:{
 "^":"r:14;",
-$1:[function(a){return J.fi(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WN(a)},"$1",null,2,0,null,65,"call"]},
 e194:{
 "^":"r:14;",
-$1:[function(a){return J.Kl(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fi(a)},"$1",null,2,0,null,65,"call"]},
 e195:{
 "^":"r:14;",
-$1:[function(a){return a.gU6()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Kl(a)},"$1",null,2,0,null,65,"call"]},
 e196:{
 "^":"r:14;",
-$1:[function(a){return J.cj(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gU6()},"$1",null,2,0,null,65,"call"]},
 e197:{
 "^":"r:14;",
-$1:[function(a){return J.tC(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.cj(a)},"$1",null,2,0,null,65,"call"]},
 e198:{
 "^":"r:14;",
-$1:[function(a){return J.jL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.tC(a)},"$1",null,2,0,null,65,"call"]},
 e199:{
 "^":"r:14;",
-$1:[function(a){return J.S5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jL(a)},"$1",null,2,0,null,65,"call"]},
 e200:{
 "^":"r:14;",
-$1:[function(a){return a.gj9()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.S5(a)},"$1",null,2,0,null,65,"call"]},
 e201:{
 "^":"r:14;",
-$1:[function(a){return J.x5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gj9()},"$1",null,2,0,null,65,"call"]},
 e202:{
 "^":"r:14;",
-$1:[function(a){return J.ksQ(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.x5(a)},"$1",null,2,0,null,65,"call"]},
 e203:{
 "^":"r:14;",
-$1:[function(a){return J.Q0(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ksQ(a)},"$1",null,2,0,null,65,"call"]},
 e204:{
 "^":"r:14;",
-$1:[function(a){return J.u5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Q0(a)},"$1",null,2,0,null,65,"call"]},
 e205:{
 "^":"r:14;",
-$1:[function(a){return J.ul(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.u5(a)},"$1",null,2,0,null,65,"call"]},
 e206:{
 "^":"r:14;",
-$1:[function(a){return a.gUx()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ul(a)},"$1",null,2,0,null,65,"call"]},
 e207:{
 "^":"r:14;",
-$1:[function(a){return J.WV(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gUx()},"$1",null,2,0,null,65,"call"]},
 e208:{
 "^":"r:14;",
-$1:[function(a){return a.gm8()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.WV(a)},"$1",null,2,0,null,65,"call"]},
 e209:{
 "^":"r:14;",
-$1:[function(a){return J.IS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gm8()},"$1",null,2,0,null,65,"call"]},
 e210:{
 "^":"r:14;",
-$1:[function(a){return J.pg(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.IS(a)},"$1",null,2,0,null,65,"call"]},
 e211:{
 "^":"r:14;",
-$1:[function(a){return a.ghL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pg(a)},"$1",null,2,0,null,65,"call"]},
 e212:{
 "^":"r:14;",
-$1:[function(a){return a.gCM()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.ghL()},"$1",null,2,0,null,65,"call"]},
 e213:{
 "^":"r:14;",
-$1:[function(a){return J.At(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gCM()},"$1",null,2,0,null,65,"call"]},
 e214:{
 "^":"r:14;",
-$1:[function(a){return J.Ou(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.At(a)},"$1",null,2,0,null,65,"call"]},
 e215:{
 "^":"r:14;",
-$1:[function(a){return J.Xp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ou(a)},"$1",null,2,0,null,65,"call"]},
 e216:{
 "^":"r:14;",
-$1:[function(a){return J.up(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Xp(a)},"$1",null,2,0,null,65,"call"]},
 e217:{
 "^":"r:14;",
-$1:[function(a){return J.n8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.up(a)},"$1",null,2,0,null,65,"call"]},
 e218:{
 "^":"r:14;",
-$1:[function(a){return a.gua()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.n8(a)},"$1",null,2,0,null,65,"call"]},
 e219:{
 "^":"r:14;",
-$1:[function(a){return a.gNS()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gua()},"$1",null,2,0,null,65,"call"]},
 e220:{
 "^":"r:14;",
-$1:[function(a){return a.guh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gNS()},"$1",null,2,0,null,65,"call"]},
 e221:{
 "^":"r:14;",
-$1:[function(a){return J.iL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.guh()},"$1",null,2,0,null,65,"call"]},
 e222:{
 "^":"r:14;",
-$1:[function(a){return J.G2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.iL(a)},"$1",null,2,0,null,65,"call"]},
 e223:{
 "^":"r:14;",
-$1:[function(a){return J.uW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.G2(a)},"$1",null,2,0,null,65,"call"]},
 e224:{
 "^":"r:14;",
-$1:[function(a){return J.Z8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.uW(a)},"$1",null,2,0,null,65,"call"]},
 e225:{
 "^":"r:14;",
-$1:[function(a){return J.uN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Z8(a)},"$1",null,2,0,null,65,"call"]},
 e226:{
 "^":"r:14;",
-$1:[function(a){return J.I1(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.uN(a)},"$1",null,2,0,null,65,"call"]},
 e227:{
 "^":"r:14;",
-$1:[function(a){return J.jH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.I1(a)},"$1",null,2,0,null,65,"call"]},
 e228:{
 "^":"r:14;",
-$1:[function(a){return J.jo(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jH(a)},"$1",null,2,0,null,65,"call"]},
 e229:{
 "^":"r:14;",
-$1:[function(a){return a.gVc()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.jo(a)},"$1",null,2,0,null,65,"call"]},
 e230:{
 "^":"r:14;",
-$1:[function(a){return a.geH()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gVc()},"$1",null,2,0,null,65,"call"]},
 e231:{
 "^":"r:14;",
-$1:[function(a){return J.i8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.geH()},"$1",null,2,0,null,65,"call"]},
 e232:{
 "^":"r:14;",
-$1:[function(a){return a.gGL()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.i8(a)},"$1",null,2,0,null,65,"call"]},
 e233:{
 "^":"r:14;",
-$1:[function(a){return J.Hm(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gGL()},"$1",null,2,0,null,65,"call"]},
 e234:{
 "^":"r:14;",
-$1:[function(a){return J.nv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Hm(a)},"$1",null,2,0,null,65,"call"]},
 e235:{
 "^":"r:14;",
-$1:[function(a){return J.UP(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.nv(a)},"$1",null,2,0,null,65,"call"]},
 e236:{
 "^":"r:14;",
-$1:[function(a){return J.zD(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.UP(a)},"$1",null,2,0,null,65,"call"]},
 e237:{
 "^":"r:14;",
-$1:[function(a){return J.fx(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zD(a)},"$1",null,2,0,null,65,"call"]},
 e238:{
 "^":"r:14;",
-$1:[function(a){return J.Zs(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fx(a)},"$1",null,2,0,null,65,"call"]},
 e239:{
 "^":"r:14;",
-$1:[function(a){return J.j8v(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zs(a)},"$1",null,2,0,null,65,"call"]},
 e240:{
 "^":"r:14;",
-$1:[function(a){return a.gXR()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.j8v(a)},"$1",null,2,0,null,65,"call"]},
 e241:{
 "^":"r:14;",
-$1:[function(a){return J.P5(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gXR()},"$1",null,2,0,null,65,"call"]},
 e242:{
 "^":"r:14;",
-$1:[function(a){return J.ll(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.P5(a)},"$1",null,2,0,null,65,"call"]},
 e243:{
 "^":"r:14;",
-$1:[function(a){return J.xi(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.ll(a)},"$1",null,2,0,null,65,"call"]},
 e244:{
 "^":"r:14;",
-$1:[function(a){return J.Ip(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.xi(a)},"$1",null,2,0,null,65,"call"]},
 e245:{
 "^":"r:14;",
-$1:[function(a){return J.fY(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ip(a)},"$1",null,2,0,null,65,"call"]},
 e246:{
 "^":"r:14;",
-$1:[function(a){return J.aX(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fY(a)},"$1",null,2,0,null,65,"call"]},
 e247:{
 "^":"r:14;",
-$1:[function(a){return J.Hy(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.aX(a)},"$1",null,2,0,null,65,"call"]},
 e248:{
 "^":"r:14;",
-$1:[function(a){return J.Yj(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Hy(a)},"$1",null,2,0,null,65,"call"]},
 e249:{
 "^":"r:14;",
-$1:[function(a){return J.Cr(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Yj(a)},"$1",null,2,0,null,65,"call"]},
 e250:{
 "^":"r:14;",
-$1:[function(a){return J.oN(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Cr(a)},"$1",null,2,0,null,65,"call"]},
 e251:{
 "^":"r:14;",
-$1:[function(a){return a.gV8()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.oN(a)},"$1",null,2,0,null,65,"call"]},
 e252:{
 "^":"r:14;",
-$1:[function(a){return J.Jq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gV8()},"$1",null,2,0,null,65,"call"]},
 e253:{
 "^":"r:14;",
-$1:[function(a){return J.TH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Jq(a)},"$1",null,2,0,null,65,"call"]},
 e254:{
 "^":"r:14;",
-$1:[function(a){return a.gp8()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.TH(a)},"$1",null,2,0,null,65,"call"]},
 e255:{
 "^":"r:14;",
-$1:[function(a){return J.F9(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gp8()},"$1",null,2,0,null,65,"call"]},
 e256:{
 "^":"r:14;",
-$1:[function(a){return J.HB(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.F9(a)},"$1",null,2,0,null,65,"call"]},
 e257:{
 "^":"r:14;",
-$1:[function(a){return J.yI(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.HB(a)},"$1",null,2,0,null,65,"call"]},
 e258:{
 "^":"r:14;",
-$1:[function(a){return J.H1(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.yI(a)},"$1",null,2,0,null,65,"call"]},
 e259:{
 "^":"r:14;",
-$1:[function(a){return J.LF(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.H1(a)},"$1",null,2,0,null,65,"call"]},
 e260:{
 "^":"r:14;",
-$1:[function(a){return J.Ff(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.LF(a)},"$1",null,2,0,null,65,"call"]},
 e261:{
 "^":"r:14;",
-$1:[function(a){return J.vI(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Ff(a)},"$1",null,2,0,null,65,"call"]},
 e262:{
 "^":"r:14;",
-$1:[function(a){return J.Pq(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.vI(a)},"$1",null,2,0,null,65,"call"]},
 e263:{
 "^":"r:14;",
-$1:[function(a){return a.gDo()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Pq(a)},"$1",null,2,0,null,65,"call"]},
 e264:{
 "^":"r:14;",
-$1:[function(a){return a.gLT()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gDo()},"$1",null,2,0,null,65,"call"]},
 e265:{
 "^":"r:14;",
-$1:[function(a){return a.gAY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gLT()},"$1",null,2,0,null,65,"call"]},
 e266:{
 "^":"r:14;",
-$1:[function(a){return J.Xa(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gAY()},"$1",null,2,0,null,65,"call"]},
 e267:{
 "^":"r:14;",
-$1:[function(a){return J.Aw(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Xa(a)},"$1",null,2,0,null,65,"call"]},
 e268:{
 "^":"r:14;",
-$1:[function(a){return J.Zu(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Aw(a)},"$1",null,2,0,null,65,"call"]},
 e269:{
 "^":"r:14;",
-$1:[function(a){return a.gm2()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Zu(a)},"$1",null,2,0,null,65,"call"]},
 e270:{
 "^":"r:14;",
-$1:[function(a){return J.dY(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gm2()},"$1",null,2,0,null,65,"call"]},
 e271:{
 "^":"r:14;",
-$1:[function(a){return J.OL(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.dY(a)},"$1",null,2,0,null,65,"call"]},
 e272:{
 "^":"r:14;",
-$1:[function(a){return J.zB(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.OL(a)},"$1",null,2,0,null,65,"call"]},
 e273:{
 "^":"r:14;",
-$1:[function(a){return a.gki()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zB(a)},"$1",null,2,0,null,65,"call"]},
 e274:{
 "^":"r:14;",
-$1:[function(a){return a.gZn()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gki()},"$1",null,2,0,null,65,"call"]},
 e275:{
 "^":"r:14;",
-$1:[function(a){return a.gGc()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZn()},"$1",null,2,0,null,65,"call"]},
 e276:{
 "^":"r:14;",
-$1:[function(a){return a.gVh()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gGc()},"$1",null,2,0,null,65,"call"]},
 e277:{
 "^":"r:14;",
-$1:[function(a){return a.gZX()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gVh()},"$1",null,2,0,null,65,"call"]},
 e278:{
 "^":"r:14;",
-$1:[function(a){return J.PS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gZX()},"$1",null,2,0,null,65,"call"]},
 e279:{
 "^":"r:14;",
-$1:[function(a){return J.QI(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.PS(a)},"$1",null,2,0,null,65,"call"]},
 e280:{
 "^":"r:14;",
-$1:[function(a){return J.SS(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.QI(a)},"$1",null,2,0,null,65,"call"]},
 e281:{
 "^":"r:14;",
-$1:[function(a){return J.SG(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.SS(a)},"$1",null,2,0,null,65,"call"]},
 e282:{
 "^":"r:14;",
-$1:[function(a){return J.fv(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.SG(a)},"$1",null,2,0,null,65,"call"]},
 e283:{
 "^":"r:14;",
-$1:[function(a){return a.gVF()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.fv(a)},"$1",null,2,0,null,65,"call"]},
 e284:{
 "^":"r:14;",
-$1:[function(a){return a.gkw()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gVF()},"$1",null,2,0,null,65,"call"]},
 e285:{
 "^":"r:14;",
-$1:[function(a){return J.p6(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gkw()},"$1",null,2,0,null,65,"call"]},
 e286:{
 "^":"r:14;",
-$1:[function(a){return J.uy(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.p6(a)},"$1",null,2,0,null,65,"call"]},
 e287:{
 "^":"r:14;",
-$1:[function(a){return J.zH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.uy(a)},"$1",null,2,0,null,65,"call"]},
 e288:{
 "^":"r:14;",
-$1:[function(a){return a.gdW()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.zH(a)},"$1",null,2,0,null,65,"call"]},
 e289:{
 "^":"r:14;",
-$1:[function(a){return a.gQR()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gdW()},"$1",null,2,0,null,65,"call"]},
 e290:{
 "^":"r:14;",
-$1:[function(a){return J.Gt(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gQR()},"$1",null,2,0,null,65,"call"]},
 e291:{
 "^":"r:14;",
-$1:[function(a){return a.gjW()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Gt(a)},"$1",null,2,0,null,65,"call"]},
 e292:{
 "^":"r:14;",
-$1:[function(a){return J.Sl(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gjW()},"$1",null,2,0,null,65,"call"]},
 e293:{
 "^":"r:14;",
-$1:[function(a){return a.gJk()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Sl(a)},"$1",null,2,0,null,65,"call"]},
 e294:{
 "^":"r:14;",
-$1:[function(a){return J.Q2(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gJk()},"$1",null,2,0,null,65,"call"]},
 e295:{
 "^":"r:14;",
-$1:[function(a){return a.gSu()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.Q2(a)},"$1",null,2,0,null,65,"call"]},
 e296:{
 "^":"r:14;",
-$1:[function(a){return a.gcs()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSu()},"$1",null,2,0,null,65,"call"]},
 e297:{
 "^":"r:14;",
-$1:[function(a){return a.gFc()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gcs()},"$1",null,2,0,null,65,"call"]},
 e298:{
 "^":"r:14;",
-$1:[function(a){return J.SW(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gFc()},"$1",null,2,0,null,65,"call"]},
 e299:{
 "^":"r:14;",
-$1:[function(a){return a.gHD()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.SW(a)},"$1",null,2,0,null,65,"call"]},
 e300:{
 "^":"r:14;",
-$1:[function(a){return a.gae()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gHD()},"$1",null,2,0,null,65,"call"]},
 e301:{
 "^":"r:14;",
-$1:[function(a){return J.U8(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gae()},"$1",null,2,0,null,65,"call"]},
 e302:{
 "^":"r:14;",
-$1:[function(a){return a.gYY()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.U8(a)},"$1",null,2,0,null,65,"call"]},
 e303:{
 "^":"r:14;",
-$1:[function(a){return a.gZ3()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gYY()},"$1",null,2,0,null,65,"call"]},
 e304:{
 "^":"r:14;",
-$1:[function(a){return J.pU(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSq()},"$1",null,2,0,null,65,"call"]},
 e305:{
 "^":"r:14;",
-$1:[function(a){return J.wp(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.pU(a)},"$1",null,2,0,null,65,"call"]},
 e306:{
 "^":"r:14;",
-$1:[function(a){return a.gSn()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.wp(a)},"$1",null,2,0,null,65,"call"]},
 e307:{
 "^":"r:14;",
-$1:[function(a){return a.gzz()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gSn()},"$1",null,2,0,null,65,"call"]},
 e308:{
 "^":"r:14;",
-$1:[function(a){return a.gv5()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gzz()},"$1",null,2,0,null,65,"call"]},
 e309:{
 "^":"r:14;",
-$1:[function(a){return J.GH(a)},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return a.gv5()},"$1",null,2,0,null,65,"call"]},
 e310:{
 "^":"r:14;",
-$1:[function(a){return a.gaU()},"$1",null,2,0,null,65,"call"]},
+$1:[function(a){return J.GH(a)},"$1",null,2,0,null,65,"call"]},
 e311:{
-"^":"r:80;",
-$2:[function(a,b){J.RX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+"^":"r:14;",
+$1:[function(a){return a.gaU()},"$1",null,2,0,null,65,"call"]},
 e312:{
 "^":"r:80;",
-$2:[function(a,b){J.zv(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.RX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e313:{
 "^":"r:80;",
-$2:[function(a,b){J.Px(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.zv(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e314:{
 "^":"r:80;",
-$2:[function(a,b){J.Tu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Px(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e315:{
 "^":"r:80;",
-$2:[function(a,b){J.Hh(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Tu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e316:{
 "^":"r:80;",
-$2:[function(a,b){J.Fv(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Vd(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e317:{
 "^":"r:80;",
-$2:[function(a,b){J.Ae(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Hh(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e318:{
 "^":"r:80;",
-$2:[function(a,b){J.m8(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Fv(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e319:{
 "^":"r:80;",
-$2:[function(a,b){J.Ed(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ae(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e320:{
 "^":"r:80;",
-$2:[function(a,b){J.NE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.m8(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e321:{
 "^":"r:80;",
-$2:[function(a,b){J.Kw(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ed(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e322:{
 "^":"r:80;",
-$2:[function(a,b){a.sUP(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.NE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e323:{
 "^":"r:80;",
-$2:[function(a,b){a.su5(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Kw(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e324:{
 "^":"r:80;",
-$2:[function(a,b){a.swz(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sUP(b)},"$2",null,4,0,null,65,68,"call"]},
 e325:{
 "^":"r:80;",
-$2:[function(a,b){J.NZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.su5(b)},"$2",null,4,0,null,65,68,"call"]},
 e326:{
 "^":"r:80;",
-$2:[function(a,b){J.T5(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.swz(b)},"$2",null,4,0,null,65,68,"call"]},
 e327:{
 "^":"r:80;",
-$2:[function(a,b){J.FI(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.NZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e328:{
 "^":"r:80;",
-$2:[function(a,b){J.i0(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.T5(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e329:{
 "^":"r:80;",
-$2:[function(a,b){J.Hf(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.FI(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e330:{
 "^":"r:80;",
-$2:[function(a,b){J.aP(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.i0(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e331:{
 "^":"r:80;",
-$2:[function(a,b){J.Jl(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Hf(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e332:{
 "^":"r:80;",
-$2:[function(a,b){J.Sf(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.aP(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e333:{
 "^":"r:80;",
-$2:[function(a,b){a.sOF(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Jl(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e334:{
 "^":"r:80;",
-$2:[function(a,b){J.LM(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Sf(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e335:{
 "^":"r:80;",
-$2:[function(a,b){J.au(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sOF(b)},"$2",null,4,0,null,65,68,"call"]},
 e336:{
 "^":"r:80;",
-$2:[function(a,b){J.Xu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.LM(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e337:{
 "^":"r:80;",
-$2:[function(a,b){J.Ac(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.au(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e338:{
 "^":"r:80;",
-$2:[function(a,b){J.AE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Xu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e339:{
 "^":"r:80;",
-$2:[function(a,b){a.sLK(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ac(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e340:{
 "^":"r:80;",
-$2:[function(a,b){a.sw2(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.AE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e341:{
 "^":"r:80;",
-$2:[function(a,b){J.Qr(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sLK(b)},"$2",null,4,0,null,65,68,"call"]},
 e342:{
 "^":"r:80;",
-$2:[function(a,b){J.P6(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sw2(b)},"$2",null,4,0,null,65,68,"call"]},
 e343:{
 "^":"r:80;",
-$2:[function(a,b){J.Yz(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qr(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e344:{
 "^":"r:80;",
-$2:[function(a,b){J.i2(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.P6(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e345:{
 "^":"r:80;",
-$2:[function(a,b){J.BC(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Yz(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e346:{
 "^":"r:80;",
-$2:[function(a,b){J.pB(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.i2(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e347:{
 "^":"r:80;",
-$2:[function(a,b){J.NO(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.BC(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e348:{
 "^":"r:80;",
-$2:[function(a,b){J.Sm(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.pB(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e349:{
 "^":"r:80;",
-$2:[function(a,b){J.JG(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.NO(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e350:{
 "^":"r:80;",
-$2:[function(a,b){J.JZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Sm(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e351:{
 "^":"r:80;",
-$2:[function(a,b){J.uF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.JG(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e352:{
 "^":"r:80;",
-$2:[function(a,b){J.uP(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.JZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e353:{
 "^":"r:80;",
-$2:[function(a,b){J.vJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.uF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e354:{
 "^":"r:80;",
-$2:[function(a,b){J.Nf(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.uP(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e355:{
 "^":"r:80;",
-$2:[function(a,b){J.Pl(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.vJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e356:{
 "^":"r:80;",
-$2:[function(a,b){J.C3(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Nf(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e357:{
 "^":"r:80;",
-$2:[function(a,b){a.sZD(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Pl(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e358:{
 "^":"r:80;",
-$2:[function(a,b){J.AI(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.C3(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e359:{
 "^":"r:80;",
-$2:[function(a,b){J.OE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sZD(b)},"$2",null,4,0,null,65,68,"call"]},
 e360:{
 "^":"r:80;",
-$2:[function(a,b){J.f6(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.AI(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e361:{
 "^":"r:80;",
-$2:[function(a,b){J.fb(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.OE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e362:{
 "^":"r:80;",
-$2:[function(a,b){a.siq(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.f6(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e363:{
 "^":"r:80;",
-$2:[function(a,b){J.MF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.fb(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e364:{
 "^":"r:80;",
-$2:[function(a,b){J.Qy(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.siq(b)},"$2",null,4,0,null,65,68,"call"]},
 e365:{
 "^":"r:80;",
-$2:[function(a,b){J.x0(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.MF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e366:{
 "^":"r:80;",
-$2:[function(a,b){a.sKt(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qy(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e367:{
 "^":"r:80;",
-$2:[function(a,b){J.cV(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.x0(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e368:{
 "^":"r:80;",
-$2:[function(a,b){J.mU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sKt(b)},"$2",null,4,0,null,65,68,"call"]},
 e369:{
 "^":"r:80;",
-$2:[function(a,b){J.uM(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.cV(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e370:{
 "^":"r:80;",
-$2:[function(a,b){J.Vr(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.mU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e371:{
 "^":"r:80;",
-$2:[function(a,b){J.GZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.uM(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e372:{
 "^":"r:80;",
-$2:[function(a,b){J.cm(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Vr(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e373:{
 "^":"r:80;",
-$2:[function(a,b){J.mz(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.GZ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e374:{
 "^":"r:80;",
-$2:[function(a,b){J.pA(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.cm(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e375:{
 "^":"r:80;",
-$2:[function(a,b){a.scI(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.mz(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e376:{
 "^":"r:80;",
-$2:[function(a,b){J.cl(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.pA(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e377:{
 "^":"r:80;",
-$2:[function(a,b){J.BL(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.scI(b)},"$2",null,4,0,null,65,68,"call"]},
 e378:{
 "^":"r:80;",
-$2:[function(a,b){J.Ql(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.cl(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e379:{
 "^":"r:80;",
-$2:[function(a,b){J.xQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.BL(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e380:{
 "^":"r:80;",
-$2:[function(a,b){J.IX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ql(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e381:{
 "^":"r:80;",
-$2:[function(a,b){J.MX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.xQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e382:{
 "^":"r:80;",
-$2:[function(a,b){J.A4(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.IX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e383:{
 "^":"r:80;",
-$2:[function(a,b){J.wD(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.MX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e384:{
 "^":"r:80;",
-$2:[function(a,b){J.wJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.A4(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e385:{
 "^":"r:80;",
-$2:[function(a,b){J.rA(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.wD(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e386:{
 "^":"r:80;",
-$2:[function(a,b){J.oJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.wJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e387:{
 "^":"r:80;",
-$2:[function(a,b){J.WI(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.rA(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e388:{
 "^":"r:80;",
-$2:[function(a,b){a.svK(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.oJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e389:{
 "^":"r:80;",
-$2:[function(a,b){J.h9(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.WI(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e390:{
 "^":"r:80;",
-$2:[function(a,b){a.sL1(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.svK(b)},"$2",null,4,0,null,65,68,"call"]},
 e391:{
 "^":"r:80;",
-$2:[function(a,b){a.sXP(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.h9(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e392:{
 "^":"r:80;",
-$2:[function(a,b){a.sP2(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sL1(b)},"$2",null,4,0,null,65,68,"call"]},
 e393:{
 "^":"r:80;",
-$2:[function(a,b){a.sxH(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sXP(b)},"$2",null,4,0,null,65,68,"call"]},
 e394:{
 "^":"r:80;",
-$2:[function(a,b){J.XF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sP2(b)},"$2",null,4,0,null,65,68,"call"]},
 e395:{
 "^":"r:80;",
-$2:[function(a,b){J.b0(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sxH(b)},"$2",null,4,0,null,65,68,"call"]},
 e396:{
 "^":"r:80;",
-$2:[function(a,b){J.A1(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.XF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e397:{
 "^":"r:80;",
-$2:[function(a,b){a.sqH(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.b0(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e398:{
 "^":"r:80;",
-$2:[function(a,b){J.SF(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.A1(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e399:{
 "^":"r:80;",
-$2:[function(a,b){J.Qv(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sqH(b)},"$2",null,4,0,null,65,68,"call"]},
 e400:{
 "^":"r:80;",
-$2:[function(a,b){J.R8(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.SF(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e401:{
 "^":"r:80;",
-$2:[function(a,b){J.Xg(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qv(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e402:{
 "^":"r:80;",
-$2:[function(a,b){J.rL(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.R8(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e403:{
 "^":"r:80;",
-$2:[function(a,b){J.CJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Xg(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e404:{
 "^":"r:80;",
-$2:[function(a,b){J.P2(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.rL(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e405:{
 "^":"r:80;",
-$2:[function(a,b){J.jy(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.CJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e406:{
 "^":"r:80;",
-$2:[function(a,b){J.PP(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.P2(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e407:{
 "^":"r:80;",
-$2:[function(a,b){a.shL(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.jy(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e408:{
 "^":"r:80;",
-$2:[function(a,b){a.sCM(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.PP(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e409:{
 "^":"r:80;",
-$2:[function(a,b){J.Sj(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.shL(b)},"$2",null,4,0,null,65,68,"call"]},
 e410:{
 "^":"r:80;",
-$2:[function(a,b){J.TR(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sCM(b)},"$2",null,4,0,null,65,68,"call"]},
 e411:{
 "^":"r:80;",
-$2:[function(a,b){J.Co(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Sj(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e412:{
 "^":"r:80;",
-$2:[function(a,b){J.ME(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.TR(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e413:{
 "^":"r:80;",
-$2:[function(a,b){J.kX(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Co(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e414:{
 "^":"r:80;",
-$2:[function(a,b){J.k4(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ME(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e415:{
 "^":"r:80;",
-$2:[function(a,b){J.EJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.kX(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e416:{
 "^":"r:80;",
-$2:[function(a,b){J.bU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.k4(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e417:{
 "^":"r:80;",
-$2:[function(a,b){J.SO(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.EJ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e418:{
 "^":"r:80;",
-$2:[function(a,b){J.B9(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.bU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e419:{
 "^":"r:80;",
-$2:[function(a,b){J.PN(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.SO(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e420:{
 "^":"r:80;",
-$2:[function(a,b){a.sVc(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.B9(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e421:{
 "^":"r:80;",
-$2:[function(a,b){J.By(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.PN(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e422:{
 "^":"r:80;",
-$2:[function(a,b){J.is(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sVc(b)},"$2",null,4,0,null,65,68,"call"]},
 e423:{
 "^":"r:80;",
-$2:[function(a,b){J.Rx(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.By(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e424:{
 "^":"r:80;",
-$2:[function(a,b){J.ry(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.is(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e425:{
 "^":"r:80;",
-$2:[function(a,b){J.Rd(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Rx(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e426:{
 "^":"r:80;",
-$2:[function(a,b){J.G7(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ry(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e427:{
 "^":"r:80;",
-$2:[function(a,b){J.Ez(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Rd(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e428:{
 "^":"r:80;",
-$2:[function(a,b){J.Qd(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.G7(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e429:{
 "^":"r:80;",
-$2:[function(a,b){J.fa(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ez(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e430:{
 "^":"r:80;",
-$2:[function(a,b){J.Cu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Qd(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e431:{
 "^":"r:80;",
-$2:[function(a,b){a.sV8(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.fa(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e432:{
 "^":"r:80;",
-$2:[function(a,b){J.EE(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Cu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e433:{
 "^":"r:80;",
-$2:[function(a,b){J.hw(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sV8(b)},"$2",null,4,0,null,65,68,"call"]},
 e434:{
 "^":"r:80;",
-$2:[function(a,b){J.EC(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.EE(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e435:{
 "^":"r:80;",
-$2:[function(a,b){J.xH(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.hw(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e436:{
 "^":"r:80;",
-$2:[function(a,b){J.wu(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.EC(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e437:{
 "^":"r:80;",
-$2:[function(a,b){J.Tx(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.xH(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e438:{
 "^":"r:80;",
-$2:[function(a,b){J.HT(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.wu(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e439:{
 "^":"r:80;",
-$2:[function(a,b){J.FH(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Tx(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e440:{
 "^":"r:80;",
-$2:[function(a,b){J.o8(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.HT(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e441:{
 "^":"r:80;",
-$2:[function(a,b){a.sDo(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.FH(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e442:{
 "^":"r:80;",
-$2:[function(a,b){a.sAY(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.o8(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e443:{
 "^":"r:80;",
-$2:[function(a,b){J.ix(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sDo(b)},"$2",null,4,0,null,65,68,"call"]},
 e444:{
 "^":"r:80;",
-$2:[function(a,b){J.WU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sAY(b)},"$2",null,4,0,null,65,68,"call"]},
 e445:{
 "^":"r:80;",
-$2:[function(a,b){J.t3(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ix(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e446:{
 "^":"r:80;",
-$2:[function(a,b){J.my(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.WU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e447:{
 "^":"r:80;",
-$2:[function(a,b){a.sVF(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.t3(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e448:{
 "^":"r:80;",
-$2:[function(a,b){J.La(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.my(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e449:{
 "^":"r:80;",
-$2:[function(a,b){a.sQR(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sVF(b)},"$2",null,4,0,null,65,68,"call"]},
 e450:{
 "^":"r:80;",
-$2:[function(a,b){J.ZU(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.La(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e451:{
 "^":"r:80;",
-$2:[function(a,b){a.sjW(b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sQR(b)},"$2",null,4,0,null,65,68,"call"]},
 e452:{
 "^":"r:80;",
-$2:[function(a,b){J.Ja(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.ZU(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e453:{
 "^":"r:80;",
-$2:[function(a,b){J.tQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){a.sjW(b)},"$2",null,4,0,null,65,68,"call"]},
 e454:{
 "^":"r:80;",
-$2:[function(a,b){J.w7(a,b)},"$2",null,4,0,null,65,68,"call"]},
+$2:[function(a,b){J.Ja(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e455:{
-"^":"r:77;",
-$0:[function(){return A.Ad("curly-block",C.Lg)},"$0",null,0,0,null,"call"]},
+"^":"r:80;",
+$2:[function(a,b){J.tQ(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e456:{
-"^":"r:77;",
-$0:[function(){return A.Ad("observatory-element",C.Mz)},"$0",null,0,0,null,"call"]},
+"^":"r:80;",
+$2:[function(a,b){J.w7(a,b)},"$2",null,4,0,null,65,68,"call"]},
 e457:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-ref",C.il)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("curly-block",C.Lg)},"$0",null,0,0,null,"call"]},
 e458:{
 "^":"r:77;",
-$0:[function(){return A.Ad("any-service-ref",C.R9)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("observatory-element",C.Mz)},"$0",null,0,0,null,"call"]},
 e459:{
 "^":"r:77;",
-$0:[function(){return A.Ad("object-ref",C.OZ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-ref",C.il)},"$0",null,0,0,null,"call"]},
 e460:{
 "^":"r:77;",
-$0:[function(){return A.Ad("instance-ref",C.Wz)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("any-service-ref",C.R9)},"$0",null,0,0,null,"call"]},
 e461:{
 "^":"r:77;",
-$0:[function(){return A.Ad("action-link",C.K4)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("object-ref",C.OZ)},"$0",null,0,0,null,"call"]},
 e462:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-bar",C.LT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("instance-ref",C.Wz)},"$0",null,0,0,null,"call"]},
 e463:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-menu",C.ms)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("action-link",C.K4)},"$0",null,0,0,null,"call"]},
 e464:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-menu-item",C.FA)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-bar",C.LT)},"$0",null,0,0,null,"call"]},
 e465:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-refresh",C.JW)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-menu",C.ms)},"$0",null,0,0,null,"call"]},
 e466:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-control",C.NW)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-menu-item",C.FA)},"$0",null,0,0,null,"call"]},
 e467:{
 "^":"r:77;",
-$0:[function(){return A.Ad("top-nav-menu",C.Mf)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-refresh",C.JW)},"$0",null,0,0,null,"call"]},
 e468:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-nav-menu",C.km)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-control",C.NW)},"$0",null,0,0,null,"call"]},
 e469:{
 "^":"r:77;",
-$0:[function(){return A.Ad("library-nav-menu",C.vw)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("top-nav-menu",C.Mf)},"$0",null,0,0,null,"call"]},
 e470:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-nav-menu",C.Ey)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-nav-menu",C.km)},"$0",null,0,0,null,"call"]},
 e471:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-notify",C.Qt)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("library-nav-menu",C.vw)},"$0",null,0,0,null,"call"]},
 e472:{
 "^":"r:77;",
-$0:[function(){return A.Ad("nav-notify-item",C.a8)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-nav-menu",C.Ey)},"$0",null,0,0,null,"call"]},
 e473:{
 "^":"r:77;",
-$0:[function(){return A.Ad("breakpoint-list",C.yS)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-notify",C.Qt)},"$0",null,0,0,null,"call"]},
 e474:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-ref",C.OG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("nav-notify-item",C.a8)},"$0",null,0,0,null,"call"]},
 e475:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-tree",C.nw)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("breakpoint-list",C.yS)},"$0",null,0,0,null,"call"]},
 e476:{
 "^":"r:77;",
-$0:[function(){return A.Ad("error-ref",C.Bi)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-ref",C.OG)},"$0",null,0,0,null,"call"]},
 e477:{
 "^":"r:77;",
-$0:[function(){return A.Ad("eval-box",C.wk)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-tree",C.nw)},"$0",null,0,0,null,"call"]},
 e478:{
 "^":"r:77;",
-$0:[function(){return A.Ad("eval-link",C.jA)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("error-ref",C.Bi)},"$0",null,0,0,null,"call"]},
 e479:{
 "^":"r:77;",
-$0:[function(){return A.Ad("field-ref",C.Jo)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("eval-box",C.wk)},"$0",null,0,0,null,"call"]},
 e480:{
 "^":"r:77;",
-$0:[function(){return A.Ad("function-ref",C.lE)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("eval-link",C.jA)},"$0",null,0,0,null,"call"]},
 e481:{
 "^":"r:77;",
-$0:[function(){return A.Ad("library-ref",C.lp)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("field-ref",C.Jo)},"$0",null,0,0,null,"call"]},
 e482:{
 "^":"r:77;",
-$0:[function(){return A.Ad("script-inset",C.ON)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("function-ref",C.lE)},"$0",null,0,0,null,"call"]},
 e483:{
 "^":"r:77;",
-$0:[function(){return A.Ad("breakpoint-toggle",C.Nw)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("library-ref",C.lp)},"$0",null,0,0,null,"call"]},
 e484:{
 "^":"r:77;",
-$0:[function(){return A.Ad("script-ref",C.Sb)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("script-inset",C.ON)},"$0",null,0,0,null,"call"]},
 e485:{
 "^":"r:77;",
-$0:[function(){return A.Ad("class-view",C.ou)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("breakpoint-toggle",C.Nw)},"$0",null,0,0,null,"call"]},
 e486:{
 "^":"r:77;",
-$0:[function(){return A.Ad("code-ref",C.oT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("script-ref",C.Sb)},"$0",null,0,0,null,"call"]},
 e487:{
 "^":"r:77;",
-$0:[function(){return A.Ad("code-view",C.jR)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("class-view",C.ou)},"$0",null,0,0,null,"call"]},
 e488:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-page",C.hM)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("code-ref",C.oT)},"$0",null,0,0,null,"call"]},
 e489:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-stack",C.JX)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("code-view",C.jR)},"$0",null,0,0,null,"call"]},
 e490:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-frame",C.V7)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-page",C.hM)},"$0",null,0,0,null,"call"]},
 e491:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-console",C.Wd)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-stack",C.JX)},"$0",null,0,0,null,"call"]},
 e492:{
 "^":"r:77;",
-$0:[function(){return A.Ad("debugger-input",C.V8)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-frame",C.V7)},"$0",null,0,0,null,"call"]},
 e493:{
 "^":"r:77;",
-$0:[function(){return A.Ad("error-view",C.KO)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-console",C.Wd)},"$0",null,0,0,null,"call"]},
 e494:{
 "^":"r:77;",
-$0:[function(){return A.Ad("field-view",C.Az)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("debugger-input",C.V8)},"$0",null,0,0,null,"call"]},
 e495:{
 "^":"r:77;",
-$0:[function(){return A.Ad("flag-list",C.Qb)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("error-view",C.KO)},"$0",null,0,0,null,"call"]},
 e496:{
 "^":"r:77;",
-$0:[function(){return A.Ad("flag-item",C.Vx)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("field-view",C.Az)},"$0",null,0,0,null,"call"]},
 e497:{
 "^":"r:77;",
-$0:[function(){return A.Ad("function-view",C.te)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("flag-list",C.Qb)},"$0",null,0,0,null,"call"]},
 e498:{
 "^":"r:77;",
-$0:[function(){return A.Ad("heap-map",C.iD)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("flag-item",C.Vx)},"$0",null,0,0,null,"call"]},
 e499:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-view",C.tU)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("function-view",C.te)},"$0",null,0,0,null,"call"]},
 e500:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-ref",C.mK)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("heap-map",C.iD)},"$0",null,0,0,null,"call"]},
 e501:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-list-view",C.It)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-view",C.tU)},"$0",null,0,0,null,"call"]},
 e502:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-ref",C.qZ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-ref",C.mK)},"$0",null,0,0,null,"call"]},
 e503:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-view",C.Zj)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-list-view",C.It)},"$0",null,0,0,null,"call"]},
 e504:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-connection-view",C.Wh)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-ref",C.qZ)},"$0",null,0,0,null,"call"]},
 e505:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-http-server-connection-ref",C.pF)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-view",C.Zj)},"$0",null,0,0,null,"call"]},
 e506:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-socket-ref",C.FG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-connection-view",C.Wh)},"$0",null,0,0,null,"call"]},
 e507:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-socket-list-view",C.IZ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-http-server-connection-ref",C.pF)},"$0",null,0,0,null,"call"]},
 e508:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-socket-view",C.pJ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-socket-ref",C.FG)},"$0",null,0,0,null,"call"]},
 e509:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-web-socket-ref",C.Yy)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-socket-list-view",C.IZ)},"$0",null,0,0,null,"call"]},
 e510:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-web-socket-list-view",C.DD)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-socket-view",C.pJ)},"$0",null,0,0,null,"call"]},
 e511:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-web-socket-view",C.Xv)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-web-socket-ref",C.Yy)},"$0",null,0,0,null,"call"]},
 e512:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-random-access-file-list-view",C.tc)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-web-socket-list-view",C.DD)},"$0",null,0,0,null,"call"]},
 e513:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-random-access-file-ref",C.rR)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-web-socket-view",C.Xv)},"$0",null,0,0,null,"call"]},
 e514:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-random-access-file-view",C.oG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-random-access-file-list-view",C.tc)},"$0",null,0,0,null,"call"]},
 e515:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-process-list-view",C.he)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-random-access-file-ref",C.rR)},"$0",null,0,0,null,"call"]},
 e516:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-process-ref",C.dD)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-random-access-file-view",C.oG)},"$0",null,0,0,null,"call"]},
 e517:{
 "^":"r:77;",
-$0:[function(){return A.Ad("io-process-view",C.hP)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-process-list-view",C.he)},"$0",null,0,0,null,"call"]},
 e518:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-ref",C.UJ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-process-ref",C.dD)},"$0",null,0,0,null,"call"]},
 e519:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-summary",C.CT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("io-process-view",C.hP)},"$0",null,0,0,null,"call"]},
 e520:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-run-state",C.j4)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-ref",C.UJ)},"$0",null,0,0,null,"call"]},
 e521:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-location",C.Io)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-summary",C.CT)},"$0",null,0,0,null,"call"]},
 e522:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-shared-summary",C.EG)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-run-state",C.j4)},"$0",null,0,0,null,"call"]},
 e523:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-counter-chart",C.ca)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-location",C.Io)},"$0",null,0,0,null,"call"]},
 e524:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-view",C.mq)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-shared-summary",C.EG)},"$0",null,0,0,null,"call"]},
 e525:{
 "^":"r:77;",
-$0:[function(){return A.Ad("inbound-reference",C.uC)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-counter-chart",C.ca)},"$0",null,0,0,null,"call"]},
 e526:{
 "^":"r:77;",
-$0:[function(){return A.Ad("object-common",C.rC)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-view",C.mq)},"$0",null,0,0,null,"call"]},
 e527:{
 "^":"r:77;",
-$0:[function(){return A.Ad("context-ref",C.XW)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("inbound-reference",C.uC)},"$0",null,0,0,null,"call"]},
 e528:{
 "^":"r:77;",
-$0:[function(){return A.Ad("instance-view",C.Ke)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("object-common",C.rC)},"$0",null,0,0,null,"call"]},
 e529:{
 "^":"r:77;",
-$0:[function(){return A.Ad("json-view",C.Tq)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("context-ref",C.XW)},"$0",null,0,0,null,"call"]},
 e530:{
 "^":"r:77;",
-$0:[function(){return A.Ad("library-view",C.PT)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("instance-view",C.Ke)},"$0",null,0,0,null,"call"]},
 e531:{
 "^":"r:77;",
-$0:[function(){return A.Ad("metrics-page",C.Fn)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("json-view",C.Tq)},"$0",null,0,0,null,"call"]},
 e532:{
 "^":"r:77;",
-$0:[function(){return A.Ad("metric-details",C.fU)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("library-view",C.PT)},"$0",null,0,0,null,"call"]},
 e533:{
 "^":"r:77;",
-$0:[function(){return A.Ad("metrics-graph",C.pi)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("metrics-page",C.Fn)},"$0",null,0,0,null,"call"]},
 e534:{
 "^":"r:77;",
-$0:[function(){return A.Ad("object-view",C.kq)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("metric-details",C.fU)},"$0",null,0,0,null,"call"]},
 e535:{
 "^":"r:77;",
-$0:[function(){return A.Ad("context-view",C.kH)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("metrics-graph",C.pi)},"$0",null,0,0,null,"call"]},
 e536:{
 "^":"r:77;",
-$0:[function(){return A.Ad("heap-profile",C.Ju)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("object-view",C.kq)},"$0",null,0,0,null,"call"]},
 e537:{
 "^":"r:77;",
-$0:[function(){return A.Ad("sliding-checkbox",C.Y3)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("context-view",C.kH)},"$0",null,0,0,null,"call"]},
 e538:{
 "^":"r:77;",
-$0:[function(){return A.Ad("isolate-profile",C.ce)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("heap-profile",C.Ju)},"$0",null,0,0,null,"call"]},
 e539:{
 "^":"r:77;",
-$0:[function(){return A.Ad("script-view",C.Th)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("sliding-checkbox",C.Y3)},"$0",null,0,0,null,"call"]},
 e540:{
 "^":"r:77;",
-$0:[function(){return A.Ad("vm-view",C.jK)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("isolate-profile",C.ce)},"$0",null,0,0,null,"call"]},
 e541:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-view",C.X8)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("script-view",C.Th)},"$0",null,0,0,null,"call"]},
 e542:{
 "^":"r:77;",
-$0:[function(){return A.Ad("trace-view",C.kt)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("vm-view",C.jK)},"$0",null,0,0,null,"call"]},
 e543:{
 "^":"r:77;",
-$0:[function(){return A.Ad("map-viewer",C.u4)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-view",C.X8)},"$0",null,0,0,null,"call"]},
 e544:{
 "^":"r:77;",
-$0:[function(){return A.Ad("list-viewer",C.QJ)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("trace-view",C.kt)},"$0",null,0,0,null,"call"]},
 e545:{
 "^":"r:77;",
-$0:[function(){return A.Ad("observatory-application",C.Dl)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("map-viewer",C.u4)},"$0",null,0,0,null,"call"]},
 e546:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-exception-view",C.pK)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("list-viewer",C.QJ)},"$0",null,0,0,null,"call"]},
 e547:{
 "^":"r:77;",
-$0:[function(){return A.Ad("service-error-view",C.wH)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("observatory-application",C.Dl)},"$0",null,0,0,null,"call"]},
 e548:{
 "^":"r:77;",
-$0:[function(){return A.Ad("vm-connect-target",C.ws)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-exception-view",C.pK)},"$0",null,0,0,null,"call"]},
 e549:{
 "^":"r:77;",
-$0:[function(){return A.Ad("vm-connect",C.bC)},"$0",null,0,0,null,"call"]},
+$0:[function(){return A.Ad("service-error-view",C.wH)},"$0",null,0,0,null,"call"]},
 e550:{
 "^":"r:77;",
+$0:[function(){return A.Ad("vm-connect-target",C.ws)},"$0",null,0,0,null,"call"]},
+e551:{
+"^":"r:77;",
+$0:[function(){return A.Ad("vm-connect",C.bC)},"$0",null,0,0,null,"call"]},
+e552:{
+"^":"r:77;",
 $0:[function(){return A.Ad("vm-ref",C.cK)},"$0",null,0,0,null,"call"]}},1],["","",,B,{
 "^":"",
 G6:{
@@ -4633,7 +4639,7 @@
 Qx:[function(a){return this.gNe(a)},"$0","gyX",0,0,77],
 SF:[function(a,b,c){var z=a.RZ
 if(b===!0)J.LE(z).ml(new T.WW(a)).wM(c)
-else{z.sZ3(null)
+else{z.sSq(null)
 c.$0()}},"$2","gNe",4,0,118,119,120],
 static:{CvM:function(a){var z,y,x,w
 z=P.L5(null,null,null,P.I,W.Bn)
@@ -4694,7 +4700,7 @@
 gFR:function(a){return a.RZ},
 Ki:function(a){return this.gFR(a).$0()},
 AV:function(a,b,c){return this.gFR(a).$2(b,c)},
-sFR:function(a,b){a.RZ=this.ct(a,C.U,a.RZ,b)},
+sFR:function(a,b){a.RZ=this.ct(a,C.AV,a.RZ,b)},
 git:function(a){return a.ij},
 sit:function(a,b){a.ij=this.ct(a,C.B0,a.ij,b)},
 tn:[function(a,b){var z=a.ij
@@ -9975,7 +9981,7 @@
 OP:function(a,b,c){return a.replaceChild(b,c)},
 $isKV:true,
 "%":"DocumentType|Notation;Node"},
-dX:{
+yk:{
 "^":"ecX;",
 gv:function(a){return a.length},
 p:function(a,b){if(b>>>0!==b||b>=a.length)throw H.b(P.Hj(b,a,null,null,null))
@@ -11773,7 +11779,7 @@
 gFR:function(a){return a.TQ},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.TQ=this.ct(a,C.U,a.TQ,b)},
+sFR:function(a,b){a.TQ=this.ct(a,C.AV,a.TQ,b)},
 gCf:function(a){return a.ca},
 sCf:function(a,b){a.ca=this.ct(a,C.Aa,a.ca,b)},
 y6:[function(a,b,c,d){var z=H.Go(J.Zu(b),"$isSc").value
@@ -11827,7 +11833,7 @@
 gFR:function(a){return a.RZ},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.RZ=this.ct(a,C.U,a.RZ,b)},
+sFR:function(a,b){a.RZ=this.ct(a,C.AV,a.RZ,b)},
 gkZ:function(a){return a.ij},
 skZ:function(a,b){a.ij=this.ct(a,C.YT,a.ij,b)},
 gyG:function(a){return a.TQ},
@@ -12231,7 +12237,7 @@
 if(a>>>0!==a||a>=z.length)return H.e(z,a)
 return J.DA(J.Tf(J.U8(z[a]),b))}return this.k5(a,b)}},
 Ly:{
-"^":"V18;RZ,ij,TQ,ca,Jc,cw,bN,mT,Jr,IL,cy$,db$,LD,kX,cy$,db$,cy$,db$,Q$,a$,b$,c$,d$,e$,f$,r$,x$,y$,z$,ch$,cx$",
+"^":"V18;RZ,ij,TQ,ca,Jc,cw,bN,mT,Jr,IL,TO,S8,cy$,db$,LD,kX,cy$,db$,cy$,db$,Q$,a$,b$,c$,d$,e$,f$,r$,x$,y$,z$,ch$,cx$",
 gYt:function(a){return a.RZ},
 sYt:function(a,b){a.RZ=this.ct(a,C.TN,a.RZ,b)},
 gcH:function(a){return a.ij},
@@ -12240,9 +12246,11 @@
 sLF:function(a,b){a.bN=this.ct(a,C.kG,a.bN,b)},
 gB1:function(a){return a.Jr},
 sB1:function(a,b){a.Jr=this.ct(a,C.vb,a.Jr,b)},
-god:function(a){return a.IL},
-sod:function(a,b){a.IL=this.ct(a,C.rB,a.IL,b)},
-Es:function(a){var z,y
+gyh:function(a){return a.IL},
+syh:function(a,b){a.IL=this.ct(a,C.U,a.IL,b)},
+god:function(a){return a.S8},
+sod:function(a,b){a.S8=this.ct(a,C.rB,a.S8,b)},
+Es:function(a){var z,y,x,w,v
 this.VM(a)
 z=(a.shadowRoot||a.webkitShadowRoot).querySelector("#newPieChart")
 y=new G.qu(null,P.L5(null,null,null,null,null))
@@ -12252,7 +12260,19 @@
 z=new G.qu(null,P.L5(null,null,null,null,null))
 z.Q=P.zV(J.Tf($.NR,"PieChart"),[y])
 a.cw=z
-a.mT=(a.shadowRoot||a.webkitShadowRoot).querySelector("#classTableBody")},
+a.mT=(a.shadowRoot||a.webkitShadowRoot).querySelector("#classTableBody")
+z=J.vo(J.HL(J.um($.Pi.c)),new K.Y1(a))
+y=this.gkC(a)
+x=H.W8(z,"YR",0)
+w=H.W8(z,"YR",1)
+v=$.X3
+v=H.J(new P.fB(z,null,null,null,null,v,0,null,null),[x,w])
+v.Cy(y,null,null,!1,w)
+v.JC(z,y,null,null,!1,x,w)
+a.TO=v},
+dQ:function(a){a.TO.Z3(new K.dk())
+this.eX(a)},
+j5:[function(a,b){if(a.IL===!0&&J.mG(J.Ts(b),"GC"))this.SK(a,new K.Z3())},"$1","gkC",2,0,86,87],
 Qf:function(a){var z,y,x,w
 for(z=J.Nx(J.Tf(a.Jr,"members"));z.D();){y=z.gk()
 x=J.U6(y)
@@ -12339,8 +12359,8 @@
 z=a.Jr
 if(z==null)return
 z=J.wg(z)
-z=this.ct(a,C.rB,a.IL,z)
-a.IL=z
+z=this.ct(a,C.rB,a.S8,z)
+a.S8=z
 z.WU(J.Tf(a.Jr,"heaps"))
 y=H.BU(J.Tf(a.Jr,"dateLastAccumulatorReset"),null,null)
 if(!J.mG(y,0)){z=P.Wu(y,!1).X(0)
@@ -12431,6 +12451,7 @@
 w=P.A(null,null)
 a.RZ="---"
 a.ij="---"
+a.IL=!1
 a.b$=[]
 a.f$=!1
 a.x$=!1
@@ -12444,7 +12465,16 @@
 return a}}},
 V18:{
 "^":"uL+Piz;",
-$isd3:true}}],["","",,P,{
+$isd3:true},
+Y1:{
+"^":"r:14;Q",
+$1:[function(a){return J.mG(J.wg(a),this.Q.S8)},"$1",null,2,0,null,87,"call"]},
+dk:{
+"^":"r:77;",
+$0:[function(){},"$0",null,0,0,null,"call"]},
+Z3:{
+"^":"r:77;",
+$0:[function(){},"$0",null,0,0,null,"call"]}}],["","",,P,{
 "^":"",
 jl:function(a){var z,y
 z=[]
@@ -13050,8 +13080,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.rU.LX(a)
-C.rU.XI(a)
+C.Gg.LX(a)
+C.Gg.XI(a)
 return a}}},
 V26:{
 "^":"uL+Piz;",
@@ -13806,8 +13836,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.Z3.LX(a)
-C.Z3.XI(a)
+C.Z3y.LX(a)
+C.Z3y.XI(a)
 return a}}}}],["","",,M,{
 "^":"",
 CX:{
@@ -13927,14 +13957,14 @@
 "^":"",
 E2:function(){var z,y
 N.QM("").sOR(C.IF)
-N.QM("").gY().yI(new F.e551())
+N.QM("").gY().yI(new F.e553())
 N.QM("").To("Starting Observatory")
 N.QM("").To("Loading Google Charts API")
 z=J.Tf($.Xw(),"google")
 y=$.Ib()
 z.Z("load",["visualization","1",P.jT(P.B(["packages",["corechart","table"],"callback",P.mt(y.gv6(y))],null,null))])
-$.Ib().Q.ml(G.vN()).ml(new F.e552())},
-e551:{
+$.Ib().Q.ml(G.vN()).ml(new F.e554())},
+e553:{
 "^":"r:172;",
 $1:[function(a){var z
 if(J.mG(a.gOR(),C.nT)){z=J.RE(a)
@@ -13942,7 +13972,7 @@
 else z=!1}else z=!1
 if(z)return
 P.FL(a.gOR().Q+": "+a.gFl().X(0)+": "+H.d(J.Oh(a)))},"$1",null,2,0,null,171,"call"]},
-e552:{
+e554:{
 "^":"r:14;",
 $1:[function(a){var z,y,x
 N.QM("").To("Initializing Polymer")
@@ -14204,7 +14234,7 @@
 gFR:function(a){return a.RZ},
 Ki:function(a){return this.gFR(a).$0()},
 LY:function(a,b){return this.gFR(a).$1(b)},
-sFR:function(a,b){a.RZ=this.ct(a,C.U,a.RZ,b)},
+sFR:function(a,b){a.RZ=this.ct(a,C.AV,a.RZ,b)},
 gjl:function(a){return a.ij},
 sjl:function(a,b){a.ij=this.ct(a,C.S,a.ij,b)},
 gph:function(a){return a.TQ},
@@ -14446,8 +14476,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.br.LX(a)
-C.br.XI(a)
+C.aD.LX(a)
+C.aD.XI(a)
 return a}}},
 V55:{
 "^":"uL+Piz;",
@@ -15982,8 +16012,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.Ki.LX(a)
-C.Ki.XI(a)
+C.Vk.LX(a)
+C.Vk.XI(a)
 return a}}},
 jpR:{
 "^":"Bo+zs;Cp:r$=,KM:z$=",
@@ -16053,7 +16083,7 @@
 M.uH(b).Jh(null)
 y=this.gZJ(a)
 x=!!J.t(b).$ishs?b:M.uH(b)
-w=J.Km(x,a,y==null&&J.Ee(x)==null?J.vo(a.Q$):y)
+w=J.Km(x,a,y==null&&J.Ee(x)==null?J.rU(a.Q$):y)
 v=a.b$
 u=$.nR().p(0,w)
 C.Nm.FV(v,u!=null?u.gdn():u)
@@ -16193,7 +16223,7 @@
 wc:function(a,b,c){return this.rh(a,b,c,!1)},
 yO:function(a,b){var z=a.Q$.giz().p(0,b)
 if(z==null)return
-return T.pw().$3$globals(T.EPS().$1(z),a,J.vo(a.Q$).a.b)},
+return T.pw().$3$globals(T.EPS().$1(z),a,J.rU(a.Q$).a.b)},
 bT:function(a){var z,y,x,w,v,u,t,s
 z=a.Q$.giz()
 for(v=J.Nx(J.q8(z)),u=a.ch$;v.D();){y=v.gk()
@@ -16317,7 +16347,7 @@
 Jys:{
 "^":"r:80;Q",
 $2:function(a,b){var z=this.Q
-$.Op().Z("addEventListener",[z,a,$.X3.mS(J.vo(z.Q$).Y2(z,z,b))])}},
+$.Op().Z("addEventListener",[z,a,$.X3.mS(J.rU(z.Q$).Y2(z,z,b))])}},
 od:{
 "^":"r:77;Q,a",
 $0:[function(){return">>> ["+H.d(J.RI(this.Q))+"]: dispatch "+H.d(this.a)},"$0",null,0,0,null,"call"]},
@@ -16597,7 +16627,7 @@
 $1:function(a){return this.Q}}}],["","",,T,{
 "^":"",
 Rj:[function(a){var z=J.t(a)
-if(!!z.$isw)z=J.Vk(z.gvc(a),new T.IK(a)).zV(0," ")
+if(!!z.$isw)z=J.vo(z.gvc(a),new T.IK(a)).zV(0," ")
 else z=!!z.$isQV?z.zV(a," "):a
 return z},"$1","PG6",2,0,53,68],
 PX5:[function(a){var z=J.t(a)
@@ -16718,7 +16748,7 @@
 TR:function(a,b){var z,y
 if(this.c!=null)throw H.b(P.s("already open"))
 this.c=b
-z=J.ph(this.b,new K.Oy(P.NZ2(null,null)))
+z=J.okV(this.b,new K.Oy(P.NZ2(null,null)))
 this.e=z
 y=z.gE6().yI(this.gGX())
 y.fm(0,new T.yF(this))
@@ -16727,7 +16757,7 @@
 return this.f},
 kf:function(a){var z,y,x,w
 try{x=this.e
-J.ph(x,new K.pf(this.Q,a))
+J.okV(x,new K.pf(this.Q,a))
 x.gLl()
 x=this.Mr(this.e.gLl(),a)
 return x}catch(w){x=H.Ru(w)
@@ -16748,13 +16778,13 @@
 z=$.Pk()
 y=this.e
 z.toString
-J.ph(y,z)
+J.okV(y,z)
 this.e=null},
 fR:function(){if(this.c!=null)this.Dy()},
 Dy:function(){var z=0
 while(!0){if(!(z<1000&&this.Yg()===!0))break;++z}return z>0},
 static:{"^":"Hi1",rD:function(a,b,c){var z,y,x,w,v
-try{z=J.ph(a,new K.GQ(b))
+try{z=J.okV(a,new K.GQ(b))
 w=c==null?z:c.$1(z)
 return w}catch(v){w=H.Ru(v)
 y=w
@@ -16790,11 +16820,11 @@
 v=!0}else{if(!!y.$iszg){w=a.ghP()
 x=y.goc(a)}else{if(d)throw H.b(K.du("Expression is not assignable: "+H.d(a)))
 return}v=!1}for(y=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);y.D();){u=y.c
-J.ph(u,new K.GQ(c))
+J.okV(u,new K.GQ(c))
 if(d)throw H.b(K.du("filter must implement Transformer to be assignable: "+H.d(u)))
-else return}t=J.ph(w,new K.GQ(c))
+else return}t=J.okV(w,new K.GQ(c))
 if(t==null)return
-if(v)J.H9(t,J.ph(x,new K.GQ(c)),b)
+if(v)J.H9(t,J.okV(x,new K.GQ(c)),b)
 else{y=$.Mg().Q.f.p(0,x)
 $.cp().Q1(t,y,b)}return b},
 cT:function(a,b){var z,y
@@ -16895,7 +16925,7 @@
 return this.Q.Eq(a)},
 X:[function(a){return this.Q.X(0)+" > [local: "+H.d(this.a)+"]"},"$0","gCR",0,0,0]},
 Ph:{
-"^":"PF;eT:Q>,Z3:a<",
+"^":"PF;eT:Q>,Sq:a<",
 gk8:function(a){return this.Q.Q},
 p:function(a,b){var z=this.a
 if(z.NZ(0,b)){z=z.p(0,b)
@@ -16942,16 +16972,16 @@
 W9:function(a){return J.ZH(this.Q)},
 Hs:function(a){return a.Q.RR(0,this)},
 T7:function(a){var z,y,x
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 if(z==null)return
 y=a.goc(a)
 x=$.Mg().Q.f.p(0,y)
 return $.cp().jD(z,x)},
-CU:function(a){var z=J.ph(a.ghP(),this)
+CU:function(a){var z=J.okV(a.ghP(),this)
 if(z==null)return
-return J.Tf(z,J.ph(a.gmU(),this))},
+return J.Tf(z,J.okV(a.gmU(),this))},
 Y7:function(a){var z,y,x,w,v
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 if(z==null)return
 if(a.gre()==null)y=null
 else{x=a.gre()
@@ -16966,13 +16996,13 @@
 o0:function(a){var z,y,x
 z=P.A(null,null)
 for(y=a.gJq(a),y=H.J(new H.a7(y,y.length,0,null),[H.u3(y,0)]);y.D();){x=y.c
-z.q(0,J.ph(J.Kt(x),this),J.ph(x.gv4(),this))}return z},
+z.q(0,J.okV(J.Kt(x),this),J.okV(x.gv4(),this))}return z},
 YV:function(a){return H.vh(P.f("should never be called"))},
 qv:function(a){return J.Tf(this.Q,a.gM(a))},
 ex:function(a){var z,y,x,w,v
 z=a.gxS(a)
-y=J.ph(a.gBb(a),this)
-x=J.ph(a.gT8(a),this)
+y=J.okV(a.gBb(a),this)
+x=J.okV(a.gT8(a),this)
 w=$.RTI().p(0,z)
 v=J.t(z)
 if(v.m(z,"&&")||v.m(z,"||")){v=y==null?!1:y
@@ -16980,11 +17010,11 @@
 else if(y==null||x==null)return
 return w.$2(y,x)},
 Hx:function(a){var z,y
-z=J.ph(a.gO4(),this)
+z=J.okV(a.gO4(),this)
 y=$.fs().p(0,a.gxS(a))
 if(J.mG(a.gxS(a),"!"))return y.$1(z==null?!1:z)
 return z==null?null:y.$1(z)},
-RD:function(a){return J.mG(J.ph(a.gdc(),this),!0)?J.ph(a.gav(),this):J.ph(a.grM(),this)},
+RD:function(a){return J.mG(J.okV(a.gdc(),this),!0)?J.okV(a.gav(),this):J.okV(a.grM(),this)},
 MV:function(a){return H.vh(P.f("can't eval an 'in' expression"))},
 eS:function(a){return H.vh(P.f("can't eval an 'as' expression"))}},
 Oy:{
@@ -16992,19 +17022,19 @@
 W9:function(a){return new K.WhS(a,null,null,null,P.bK(null,null,!1,null))},
 Hs:function(a){return a.Q.RR(0,this)},
 T7:function(a){var z,y
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 y=new K.vl(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(y)
 return y},
 CU:function(a){var z,y,x
-z=J.ph(a.ghP(),this)
-y=J.ph(a.gmU(),this)
+z=J.okV(a.ghP(),this)
+y=J.okV(a.gmU(),this)
 x=new K.iT(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(x)
 y.sHg(x)
 return x},
 Y7:function(a){var z,y,x,w,v
-z=J.ph(a.ghP(),this)
+z=J.okV(a.ghP(),this)
 if(a.gre()==null)y=null
 else{x=a.gre()
 w=this.gnG()
@@ -17025,29 +17055,29 @@
 C.Nm.aN(z,new K.Xs(y))
 return y},
 YV:function(a){var z,y,x
-z=J.ph(a.gG3(a),this)
-y=J.ph(a.gv4(),this)
+z=J.okV(a.gG3(a),this)
+y=J.okV(a.gv4(),this)
 x=new K.EL(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(x)
 y.sHg(x)
 return x},
 qv:function(a){return new K.ek(a,null,null,null,P.bK(null,null,!1,null))},
 ex:function(a){var z,y,x
-z=J.ph(a.gBb(a),this)
-y=J.ph(a.gT8(a),this)
+z=J.okV(a.gBb(a),this)
+y=J.okV(a.gT8(a),this)
 x=new K.ky(z,y,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(x)
 y.sHg(x)
 return x},
 Hx:function(a){var z,y
-z=J.ph(a.gO4(),this)
+z=J.okV(a.gO4(),this)
 y=new K.mv(z,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(y)
 return y},
 RD:function(a){var z,y,x,w
-z=J.ph(a.gdc(),this)
-y=J.ph(a.gav(),this)
-x=J.ph(a.grM(),this)
+z=J.okV(a.gdc(),this)
+y=J.okV(a.gav(),this)
+x=J.okV(a.grM(),this)
 w=new K.an(z,y,x,a,null,null,null,P.bK(null,null,!1,null))
 z.sHg(w)
 y.sHg(w)
@@ -17767,41 +17797,41 @@
 "^":"",
 P55:{
 "^":"a;",
-DV:[function(a){return J.ph(a,this)},"$1","gnG",2,0,208,167]},
+DV:[function(a){return J.okV(a,this)},"$1","gnG",2,0,208,167]},
 cfS:{
 "^":"P55;",
 xn:function(a){},
 W9:function(a){this.xn(a)},
 Hs:function(a){a.Q.RR(0,this)
 this.xn(a)},
-T7:function(a){J.ph(a.ghP(),this)
+T7:function(a){J.okV(a.ghP(),this)
 this.xn(a)},
-CU:function(a){J.ph(a.ghP(),this)
-J.ph(a.gmU(),this)
+CU:function(a){J.okV(a.ghP(),this)
+J.okV(a.gmU(),this)
 this.xn(a)},
 Y7:function(a){var z
-J.ph(a.ghP(),this)
-if(a.gre()!=null)for(z=a.gre(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.ph(z.c,this)
+J.okV(a.ghP(),this)
+if(a.gre()!=null)for(z=a.gre(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.okV(z.c,this)
 this.xn(a)},
 I6:function(a){this.xn(a)},
 Zh:function(a){var z
-for(z=a.gMO(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.ph(z.c,this)
+for(z=a.gMO(),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.okV(z.c,this)
 this.xn(a)},
 o0:function(a){var z
-for(z=a.gJq(a),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.ph(z.c,this)
+for(z=a.gJq(a),z=H.J(new H.a7(z,z.length,0,null),[H.u3(z,0)]);z.D();)J.okV(z.c,this)
 this.xn(a)},
-YV:function(a){J.ph(a.gG3(a),this)
-J.ph(a.gv4(),this)
+YV:function(a){J.okV(a.gG3(a),this)
+J.okV(a.gv4(),this)
 this.xn(a)},
 qv:function(a){this.xn(a)},
-ex:function(a){J.ph(a.gBb(a),this)
-J.ph(a.gT8(a),this)
+ex:function(a){J.okV(a.gBb(a),this)
+J.okV(a.gT8(a),this)
 this.xn(a)},
-Hx:function(a){J.ph(a.gO4(),this)
+Hx:function(a){J.okV(a.gO4(),this)
 this.xn(a)},
-RD:function(a){J.ph(a.gdc(),this)
-J.ph(a.gav(),this)
-J.ph(a.grM(),this)
+RD:function(a){J.okV(a.gdc(),this)
+J.okV(a.gav(),this)
+J.okV(a.grM(),this)
 this.xn(a)},
 MV:function(a){a.Q.RR(0,this)
 a.a.RR(0,this)
@@ -19013,7 +19043,7 @@
 "^":"af+Piz;",
 $isd3:true},
 U4:{
-"^":"rG9;x,Pb:y<,XR:z<,DD:ch>,Z3:cx<,jV:cy<,cy$,db$,Q,a,b,c,d,e,f,r,cy$,db$",
+"^":"rG9;x,Pb:y<,XR:z<,DD:ch>,Sq:cx<,jV:cy<,cy$,db$,Q,a,b,c,d,e,f,r,cy$,db$",
 gO3:function(a){return this.x},
 gjm:function(){return!0},
 gM8:function(){return!1},
@@ -19261,8 +19291,8 @@
 sqH:function(a){this.z=F.Wi(this,C.BV,this.z,a)},
 gv:function(a){return this.ch},
 sv:function(a,b){this.ch=F.Wi(this,C.Wn,this.ch,b)},
-gZ3:function(){return this.cx},
-sZ3:function(a){this.cx=F.Wi(this,C.xw,this.cx,a)},
+gSq:function(){return this.cx},
+sSq:function(a){this.cx=F.Wi(this,C.xw,this.cx,a)},
 bF:function(a,b,c){var z,y
 D.kT(b,J.wg(this.Q))
 z=J.U6(b)
@@ -19675,7 +19705,7 @@
 gSS:function(){return this.c},
 gUB:function(){return J.mG(this.Q,0)},
 gvN:function(){return this.d.b.length>0},
-dV:[function(){var z,y
+xtx:[function(){var z,y
 z=this.Q
 y=J.t(z)
 if(y.m(z,0))return""
@@ -20139,8 +20169,8 @@
 a.z$=y
 a.ch$=x
 a.cx$=w
-C.Vd.LX(a)
-C.Vd.XI(a)
+C.kgQ.LX(a)
+C.kgQ.XI(a)
 return a}}},
 V62:{
 "^":"uL+Piz;",
@@ -21625,7 +21655,7 @@
 yY:function(a){this.Wd(a)},
 wT:function(a,b){if(J.co(b,"ws://"))return b
 return"ws://"+H.d(b)+"/ws"},
-ny:[function(a,b,c,d){var z,y,x
+nyC:[function(a,b,c,d){var z,y,x
 J.Kr(b)
 z=this.wT(a,a.RZ)
 d=$.Pi.d.J8(z)
@@ -22325,8 +22355,8 @@
 J.Ux=function(a){return J.RE(a).geo(a)}
 J.V1=function(a,b){return J.w1(a).Rz(a,b)}
 J.V2=function(a,b,c){return J.w1(a).aP(a,b,c)}
+J.Vd=function(a,b){return J.RE(a).syh(a,b)}
 J.Vj=function(a,b){return J.RE(a).Md(a,b)}
-J.Vk=function(a,b){return J.w1(a).ev(a,b)}
 J.Vr=function(a,b){return J.RE(a).sG3(a,b)}
 J.Vs=function(a){return J.RE(a).gQg(a)}
 J.W1=function(a,b){if(typeof a=="number"&&typeof b=="number")return a<=b
@@ -22397,6 +22427,7 @@
 J.cm=function(a,b){return J.w1(a).srZ(a,b)}
 J.co=function(a,b){return J.NH(a).nC(a,b)}
 J.dH=function(a,b){return J.w1(a).h(a,b)}
+J.dX=function(a){return J.RE(a).gyh(a)}
 J.dY=function(a){return J.RE(a).ga4(a)}
 J.de=function(a){return J.RE(a).gGd(a)}
 J.df=function(a){return J.RE(a).QE(a)}
@@ -22490,6 +22521,7 @@
 J.oJ=function(a,b){return J.RE(a).srs(a,b)}
 J.oN=function(a){return J.RE(a).gj4(a)}
 J.ocJ=function(a,b){return J.RE(a).yU(a,b)}
+J.okV=function(a,b){return J.RE(a).RR(a,b)}
 J.op=function(a){return J.RE(a).gD7(a)}
 J.or=function(a){return J.RE(a).gV5(a)}
 J.p6=function(a){return J.RE(a).gBN(a)}
@@ -22502,7 +22534,6 @@
 J.pU=function(a){return J.RE(a).gYe(a)}
 J.pb=function(a,b){return J.w1(a).Vr(a,b)}
 J.pg=function(a){return J.RE(a).gBj(a)}
-J.ph=function(a,b){return J.RE(a).RR(a,b)}
 J.pr=function(a){return J.RE(a).guS(a)}
 J.pz=function(a){return J.RE(a).gwe(a)}
 J.q0=function(a){return J.RE(a).guz(a)}
@@ -22517,6 +22548,7 @@
 J.qx=function(a){return J.RE(a).gbe(a)}
 J.rA=function(a,b){return J.RE(a).sbe(a,b)}
 J.rL=function(a,b){return J.RE(a).spE(a,b)}
+J.rU=function(a){return J.RE(a).gZJ(a)}
 J.rn=function(a){return J.w1(a).grZ(a)}
 J.ro=function(a){return J.RE(a).gOB(a)}
 J.rp=function(a){return J.RE(a).gd4(a)}
@@ -22556,7 +22588,7 @@
 J.vU=function(a,b){if(typeof a=="number"&&typeof b=="number")return a>b
 return J.Wx(a).A(a,b)}
 J.vX=function(a){return J.w1(a).wg(a)}
-J.vo=function(a){return J.RE(a).gZJ(a)}
+J.vo=function(a,b){return J.w1(a).ev(a,b)}
 J.vu=function(a,b){return J.RE(a).So(a,b)}
 J.w7=function(a,b){return J.RE(a).syW(a,b)}
 J.w8=function(a){return J.RE(a).gkc(a)}
@@ -22654,7 +22686,7 @@
 C.Ag=E.Mb.prototype
 C.ozm=E.oF.prototype
 C.wK=E.qh.prototype
-C.rU=E.Q6.prototype
+C.Gg=E.Q6.prototype
 C.za=E.L4.prototype
 C.ag=E.Zn.prototype
 C.RrX=E.uE.prototype
@@ -22679,7 +22711,7 @@
 C.yo=J.E.prototype
 C.GB=Z.vj.prototype
 C.xA=A.UK.prototype
-C.Z3=R.LU.prototype
+C.Z3y=R.LU.prototype
 C.MG=M.CX.prototype
 C.dl=U.WG.prototype
 C.vmJ=U.VZ.prototype
@@ -22696,19 +22728,19 @@
 C.BJj=A.NK.prototype
 C.L8=A.Zx.prototype
 C.J7=A.Ww.prototype
-C.t5=W.dX.prototype
-C.br=L.qV.prototype
+C.t5=W.yk.prototype
+C.aD=L.qV.prototype
 C.ji=Q.Ce.prototype
 C.Lj=L.NT.prototype
 C.YpE=V.F1.prototype
 C.Pfz=Z.uL.prototype
 C.ZQ=J.iCW.prototype
-C.Ki=A.xc.prototype
+C.Vk=A.xc.prototype
 C.Fa=T.ov.prototype
 C.Wa=A.kn.prototype
 C.cJ0=U.fI.prototype
 C.U0=R.zM.prototype
-C.Vd=D.Rk.prototype
+C.kgQ=D.Rk.prototype
 C.Ns=U.Ti.prototype
 C.HRc=Q.xI.prototype
 C.zb=Q.CY.prototype
@@ -22921,6 +22953,8 @@
 C.UI=new A.ES(C.bJ,C.BM,!1,C.jJ,!1,C.cs)
 C.kw=H.K('w')
 C.hS=new A.ES(C.SR,C.BM,!1,C.kw,!1,C.cs)
+C.U=new H.tx("autoRefresh")
+C.br=new A.ES(C.U,C.BM,!1,C.nd,!1,C.cs)
 C.Zi=new H.tx("lastAccumulatorReset")
 C.vC=new A.ES(C.Zi,C.BM,!1,C.yE,!1,C.y0)
 C.hf=new H.tx("label")
@@ -22988,9 +23022,9 @@
 C.JD=new A.ES(C.am,C.BM,!1,C.Gsc,!1,C.y0)
 C.A7=new H.tx("height")
 C.cD=new A.ES(C.A7,C.BM,!1,C.yE,!1,C.cs)
-C.U=new H.tx("callback")
+C.AV=new H.tx("callback")
 C.Fyq=H.K('Sa')
-C.k1=new A.ES(C.U,C.BM,!1,C.Fyq,!1,C.cs)
+C.k1=new A.ES(C.AV,C.BM,!1,C.Fyq,!1,C.cs)
 C.TW=new H.tx("tagSelector")
 C.B3=new A.ES(C.TW,C.BM,!1,C.yE,!1,C.y0)
 C.r1=new H.tx("expandChanged")
@@ -23010,7 +23044,7 @@
 C.TO=new A.ES(C.kY,C.BM,!1,C.Ct,!1,C.cs)
 C.uG=new H.tx("linesReady")
 C.Df=new A.ES(C.uG,C.BM,!1,C.nd,!1,C.y0)
-C.Qp=new A.ES(C.U,C.BM,!1,C.wG,!1,C.cs)
+C.Qp=new A.ES(C.AV,C.BM,!1,C.wG,!1,C.cs)
 C.vb=new H.tx("profile")
 C.Mq=new A.ES(C.vb,C.BM,!1,C.BY,!1,C.cs)
 C.KK=new A.ES(C.uO,C.BM,!1,C.Gsc,!1,C.y0)
@@ -23190,8 +23224,8 @@
 C.lyV=new H.LPe(14,{domfocusout:"DOMFocusOut",domfocusin:"DOMFocusIn",dommousescroll:"DOMMouseScroll",animationend:"webkitAnimationEnd",animationiteration:"webkitAnimationIteration",animationstart:"webkitAnimationStart",doubleclick:"dblclick",fullscreenchange:"webkitfullscreenchange",fullscreenerror:"webkitfullscreenerror",keyadded:"webkitkeyadded",keyerror:"webkitkeyerror",keymessage:"webkitkeymessage",needkey:"webkitneedkey",speechchange:"webkitSpeechChange"},C.Vgv)
 C.rWc=I.uL(["name","extends","constructor","noscript","assetpath","cache-csstext","attributes"])
 C.pv=new H.LPe(7,{name:1,extends:1,constructor:1,noscript:1,assetpath:1,"cache-csstext":1,attributes:1},C.rWc)
-C.Y1=I.uL(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==","!==","===",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
-C.w0=new H.LPe(29,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,"!==":7,"===":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.Y1)
+C.kKi=I.uL(["!",":",",",")","]","}","?","||","&&","|","^","&","!=","==","!==","===",">=",">","<=","<","+","-","%","/","*","(","[",".","{"])
+C.w0=new H.LPe(29,{"!":0,":":0,",":0,")":0,"]":0,"}":0,"?":1,"||":2,"&&":3,"|":4,"^":5,"&":6,"!=":7,"==":7,"!==":7,"===":7,">=":8,">":8,"<=":8,"<":8,"+":9,"-":9,"%":10,"/":10,"*":10,"(":11,"[":11,".":11,"{":11},C.kKi)
 C.MEG=I.uL(["enumerate"])
 C.mB=new H.LPe(1,{enumerate:K.HZg()},C.MEG)
 C.tq=H.K('Bo')
diff --git a/runtime/bin/vmservice/observatory/deployed/web/packages/observatory/src/elements/heap_profile.html b/runtime/bin/vmservice/observatory/deployed/web/packages/observatory/src/elements/heap_profile.html
index f6a324e..fafdcfb 100644
--- a/runtime/bin/vmservice/observatory/deployed/web/packages/observatory/src/elements/heap_profile.html
+++ b/runtime/bin/vmservice/observatory/deployed/web/packages/observatory/src/elements/heap_profile.html
@@ -43,6 +43,12 @@
     #classtable tr:hover > td {
       background-color: #F4C7C3;
     }
+    .nav-option {
+      color: white;
+      float: right;
+      margin: 3px;
+      padding: 8px;
+    }
   </style>
   <nav-bar>
     <top-nav-menu></top-nav-menu>
@@ -51,6 +57,9 @@
     <nav-refresh callback="{{ resetAccumulator }}" label="Reset Accumulator"></nav-refresh>
     <nav-refresh callback="{{ refreshGC }}" label="GC"></nav-refresh>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <div class="nav-option">
+      <input type="checkbox" checked="{{ autoRefresh }}">Auto-refresh on GC
+    </div>
     <nav-control></nav-control>
   </nav-bar>
   <div class="content">
@@ -174,4 +183,4 @@
 </template>
 </polymer-element>
 
-<script type="application/dart" src="heap_profile.dart"></script>
\ No newline at end of file
+<script type="application/dart" src="heap_profile.dart"></script>
diff --git a/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.dart b/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.dart
index 132e43b..1171fb6 100644
--- a/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.dart
+++ b/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.dart
@@ -43,6 +43,8 @@
   var _classTableBody;
 
   @published ServiceMap profile;
+  @published bool autoRefresh = false;
+  var _subscription;
 
   @observable Isolate isolate;
 
@@ -91,8 +93,22 @@
     _oldPieChart = new Chart('PieChart',
         shadowRoot.querySelector('#oldPieChart'));
     _classTableBody = shadowRoot.querySelector('#classTableBody');
+    _subscription = app.vm.events.stream.where(
+        (event) => event.isolate == isolate).listen(_onEvent);
   }
 
+  @override
+  void detached() {
+    _subscription.cancel((){});
+    super.detached();
+  }
+  
+  void _onEvent(ServiceEvent event) {
+    if (autoRefresh && event.eventType == 'GC') {
+      refresh((){});
+    }
+  }
+  
   void _updatePieCharts() {
     assert(profile != null);
     _newPieDataTable.clearRows();
diff --git a/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.html b/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.html
index f6a324e..fafdcfb 100644
--- a/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.html
+++ b/runtime/bin/vmservice/observatory/lib/src/elements/heap_profile.html
@@ -43,6 +43,12 @@
     #classtable tr:hover > td {
       background-color: #F4C7C3;
     }
+    .nav-option {
+      color: white;
+      float: right;
+      margin: 3px;
+      padding: 8px;
+    }
   </style>
   <nav-bar>
     <top-nav-menu></top-nav-menu>
@@ -51,6 +57,9 @@
     <nav-refresh callback="{{ resetAccumulator }}" label="Reset Accumulator"></nav-refresh>
     <nav-refresh callback="{{ refreshGC }}" label="GC"></nav-refresh>
     <nav-refresh callback="{{ refresh }}"></nav-refresh>
+    <div class="nav-option">
+      <input type="checkbox" checked="{{ autoRefresh }}">Auto-refresh on GC
+    </div>
     <nav-control></nav-control>
   </nav-bar>
   <div class="content">
@@ -174,4 +183,4 @@
 </template>
 </polymer-element>
 
-<script type="application/dart" src="heap_profile.dart"></script>
\ No newline at end of file
+<script type="application/dart" src="heap_profile.dart"></script>
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index e5430f8..5c3d966 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -323,6 +323,7 @@
   static const _PAUSE = 1;
   static const _RESUME = 2;
   static const _PING = 3;
+  static const _KILL = 4;
 
 
   static SendPort _spawnFunction(SendPort readyPort, Function topLevelFunction,
@@ -338,7 +339,7 @@
 
   /* patch */ void _pause(Capability resumeCapability) {
     var msg = new List(4)
-        ..[0] = 0  // Make room for OOM message type.
+        ..[0] = 0  // Make room for OOB message type.
         ..[1] = _PAUSE
         ..[2] = pauseCapability
         ..[3] = resumeCapability;
@@ -347,7 +348,7 @@
 
   /* patch */ void resume(Capability resumeCapability) {
     var msg = new List(4)
-        ..[0] = 0  // Make room for OOM message type.
+        ..[0] = 0  // Make room for OOB message type.
         ..[1] = _RESUME
         ..[2] = pauseCapability
         ..[3] = resumeCapability;
@@ -367,7 +368,12 @@
   }
 
   /* patch */ void kill([int priority = BEFORE_NEXT_EVENT]) {
-    throw new UnsupportedError("kill");
+    var msg = new List(4)
+        ..[0] = 0  // Make room for OOB message type.
+        ..[1] = _KILL
+        ..[2] = terminateCapability
+        ..[3] = priority;
+    _sendOOB(controlPort, msg);
   }
 
   /* patch */ void ping(SendPort responsePort, [int pingType = IMMEDIATE]) {
diff --git a/runtime/lib/regexp.cc b/runtime/lib/regexp.cc
index 057087e..ba26324 100644
--- a/runtime/lib/regexp.cc
+++ b/runtime/lib/regexp.cc
@@ -14,7 +14,7 @@
 namespace dart {
 
 DECLARE_FLAG(bool, trace_irregexp);
-DEFINE_FLAG(bool, use_jscre, true, "Use the JSCRE regular expression engine");
+DEFINE_FLAG(bool, use_jscre, false, "Use the JSCRE regular expression engine");
 
 
 DEFINE_NATIVE_ENTRY(JSSyntaxRegExp_factory, 4) {
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index 1fe7e91..8d1e57f 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -1934,6 +1934,47 @@
 }
 
 
+void Assembler::ComputeRange(Register result,
+                             Register value,
+                             Register scratch,
+                             Label* not_mint) {
+  const Register hi = TMP;
+  const Register lo = scratch;
+
+  Label done;
+  mov(result, Operand(value, LSR, kBitsPerWord - 1));
+  tst(value, Operand(kSmiTagMask));
+  b(&done, EQ);
+  CompareClassId(value, kMintCid, result);
+  b(not_mint, NE);
+  ldr(hi, FieldAddress(value, Mint::value_offset() + kWordSize));
+  ldr(lo, FieldAddress(value, Mint::value_offset()));
+  rsb(result, hi, Operand(ICData::kInt32RangeBit));
+  cmp(hi, Operand(lo, ASR, kBitsPerWord - 1));
+  b(&done, EQ);
+  LoadImmediate(result, ICData::kUint32RangeBit);  // Uint32
+  tst(hi, Operand(hi));
+  LoadImmediate(result, ICData::kInt64RangeBit, NE);  // Int64
+  Bind(&done);
+}
+
+
+void Assembler::UpdateRangeFeedback(Register value,
+                                    intptr_t index,
+                                    Register ic_data,
+                                    Register scratch1,
+                                    Register scratch2,
+                                    Label* miss) {
+  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
+  ComputeRange(scratch1, value, scratch2, miss);
+  ldr(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()));
+  orr(scratch2,
+      scratch2,
+      Operand(scratch1, LSL, ICData::RangeFeedbackShift(index)));
+  str(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()));
+}
+
+
 static bool CanEncodeBranchOffset(int32_t offset) {
   ASSERT(Utils::IsAligned(offset, 4));
   return Utils::IsInt(Utils::CountOneBits(kBranchOffsetMask), offset);
diff --git a/runtime/vm/assembler_arm.h b/runtime/vm/assembler_arm.h
index 4b479a9..07d1bdb 100644
--- a/runtime/vm/assembler_arm.h
+++ b/runtime/vm/assembler_arm.h
@@ -711,6 +711,18 @@
   void CompareClassId(Register object, intptr_t class_id, Register scratch);
   void LoadTaggedClassIdMayBeSmi(Register result, Register object);
 
+  void ComputeRange(Register result,
+                    Register value,
+                    Register scratch,
+                    Label* miss);
+
+  void UpdateRangeFeedback(Register value,
+                           intptr_t idx,
+                           Register ic_data,
+                           Register scratch1,
+                           Register scratch2,
+                           Label* miss);
+
   void LoadWordFromPoolOffset(Register rd, int32_t offset, Condition cond = AL);
   void LoadFromOffset(OperandSize type,
                       Register reg,
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index e163e1d..d56cb3c 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
+#include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_ARM64)
 
 #include "vm/assembler.h"
@@ -1133,6 +1133,51 @@
 }
 
 
+void Assembler::ComputeRange(Register result,
+                             Register value,
+                             Register scratch,
+                             Label* not_mint) {
+  Label done, not_smi;
+  tsti(value, Immediate(kSmiTagMask));
+  b(&not_smi, NE);
+
+  AsrImmediate(scratch, value, 32);
+  LoadImmediate(result, ICData::kUint32RangeBit, PP);
+  cmp(scratch, Operand(1));
+  b(&done, EQ);
+
+  neg(scratch, scratch);
+  add(result, scratch, Operand(ICData::kInt32RangeBit));
+  cmp(scratch, Operand(1));
+  LoadImmediate(TMP, ICData::kSignedRangeBit, PP);
+  csel(result, result, TMP, LS);
+  b(&done);
+
+  Bind(&not_smi);
+  CompareClassId(value, kMintCid, PP);
+  b(not_mint, NE);
+
+  LoadImmediate(result, ICData::kInt64RangeBit, PP);
+  Bind(&done);
+}
+
+
+void Assembler::UpdateRangeFeedback(Register value,
+                                    intptr_t index,
+                                    Register ic_data,
+                                    Register scratch1,
+                                    Register scratch2,
+                                    Label* miss) {
+  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
+  ComputeRange(scratch1, value, scratch2, miss);
+  ldr(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()), kWord);
+  orrw(scratch2,
+       scratch2,
+       Operand(scratch1, LSL, ICData::RangeFeedbackShift(index)));
+  str(scratch2, FieldAddress(ic_data, ICData::state_bits_offset()), kWord);
+}
+
+
 // Frame entry and exit.
 void Assembler::ReserveAlignedFrameSpace(intptr_t frame_space) {
   // Reserve space for arguments and align frame before entering
diff --git a/runtime/vm/assembler_arm64.h b/runtime/vm/assembler_arm64.h
index f080961..172851c 100644
--- a/runtime/vm/assembler_arm64.h
+++ b/runtime/vm/assembler_arm64.h
@@ -633,6 +633,9 @@
   void orr(Register rd, Register rn, Operand o) {
     EmitLogicalShiftOp(ORR, rd, rn, o, kDoubleWord);
   }
+  void orrw(Register rd, Register rn, Operand o) {
+    EmitLogicalShiftOp(ORR, rd, rn, o, kWord);
+  }
   void orn(Register rd, Register rn, Operand o) {
     EmitLogicalShiftOp(ORN, rd, rn, o, kDoubleWord);
   }
@@ -1338,6 +1341,18 @@
   void CompareClassId(Register object, intptr_t class_id, Register pp);
   void LoadTaggedClassIdMayBeSmi(Register result, Register object);
 
+  void ComputeRange(Register result,
+                    Register value,
+                    Register scratch,
+                    Label* miss);
+
+  void UpdateRangeFeedback(Register value,
+                           intptr_t idx,
+                           Register ic_data,
+                           Register scratch1,
+                           Register scratch2,
+                           Label* miss);
+
   void EnterFrame(intptr_t frame_size);
   void LeaveFrame();
 
diff --git a/runtime/vm/assembler_arm64_test.cc b/runtime/vm/assembler_arm64_test.cc
index bb6bd0a..ab3874c 100644
--- a/runtime/vm/assembler_arm64_test.cc
+++ b/runtime/vm/assembler_arm64_test.cc
@@ -3523,6 +3523,67 @@
   __ ret();
 }
 
+
+ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
+  __ SetupDartSP(kTestStackSpace);
+  __ TagAndPushPP();
+  __ LoadPoolPointer(PP);
+  Label miss, done;
+  __ mov(R1, R0);
+  __ ComputeRange(R0, R1, R2, &miss);
+  __ b(&done);
+
+  __ Bind(&miss);
+  __ LoadImmediate(R0, -1, kNoPP);
+
+  __ Bind(&done);
+  __ PopAndUntagPP();
+  __ mov(CSP, SP);
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(ComputeRange, test) {
+  typedef intptr_t (*ComputeRange)(intptr_t value) DART_UNUSED;
+
+#define RANGE_OF(v)                                              \
+  (EXECUTE_TEST_CODE_INTPTR_INTPTR(                              \
+    ComputeRange, test->entry(), reinterpret_cast<intptr_t>(v)))
+
+  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Smi::New(0)));
+  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Smi::New(1)));
+  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Smi::New(kMaxInt32)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            RANGE_OF(Smi::New(-1)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            RANGE_OF(Smi::New(kMinInt32)));
+
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            RANGE_OF(Smi::New(static_cast<int64_t>(kMaxInt32) + 1)));
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            RANGE_OF(Smi::New(kMaxUint32)));
+
+  // On 64-bit platforms we don't track the sign of the smis outside of
+  // int32 range because it is not needed to distinguish kInt32Range from
+  // kUint32Range.
+  EXPECT_EQ(ICData::kSignedRangeBit,
+            RANGE_OF(Smi::New(static_cast<int64_t>(kMinInt32) - 1)));
+  EXPECT_EQ(ICData::kSignedRangeBit,
+            RANGE_OF(Smi::New(static_cast<int64_t>(kMaxUint32) + 1)));
+  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(Smi::kMaxValue)));
+  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(Smi::kMinValue)));
+
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(Smi::kMaxValue + 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(Smi::kMinValue - 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMaxInt64)));
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMinInt64)));
+
+  EXPECT_EQ(-1, RANGE_OF(Bool::True().raw()));
+
+#undef RANGE_OF
+}
+
+
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_ARM64)
diff --git a/runtime/vm/assembler_arm_test.cc b/runtime/vm/assembler_arm_test.cc
index 01f2350..7026c2e 100644
--- a/runtime/vm/assembler_arm_test.cc
+++ b/runtime/vm/assembler_arm_test.cc
@@ -4215,6 +4215,59 @@
   __ Ret();
 }
 
+
+ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
+  Label miss, done;
+  __ mov(R1, Operand(R0));
+  __ ComputeRange(R0, R1, R2, &miss);
+  __ b(&done);
+
+  __ Bind(&miss);
+  __ LoadImmediate(R0, -1);
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(ComputeRange, test) {
+  typedef intptr_t (*ComputeRange)(intptr_t value) DART_UNUSED;
+
+#define RANGE_OF(v)                                              \
+  (EXECUTE_TEST_CODE_INTPTR_INTPTR(                              \
+    ComputeRange, test->entry(), reinterpret_cast<intptr_t>(v)))
+
+  EXPECT_EQ(0, RANGE_OF(Smi::New(0)));
+  EXPECT_EQ(0, RANGE_OF(Smi::New(1)));
+  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(-1)));
+  EXPECT_EQ(0, RANGE_OF(Smi::New(Smi::kMaxValue)));
+  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(Smi::kMinValue)));
+
+  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(Smi::kMaxValue + 1)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            RANGE_OF(Integer::New(Smi::kMinValue - 1)));
+  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(kMaxInt32)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            RANGE_OF(Integer::New(kMinInt32)));
+
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxInt32) + 1)));
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            RANGE_OF(Integer::New(kMaxUint32)));
+
+  EXPECT_EQ(ICData::kInt64RangeBit,
+            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxUint32) + 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit,
+            RANGE_OF(Integer::New(static_cast<int64_t>(kMinInt32) - 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMaxInt64)));
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMinInt64)));
+
+  EXPECT_EQ(-1, RANGE_OF(Bool::True().raw()));
+
+#undef RANGE_OF
+}
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_ARM
diff --git a/runtime/vm/assembler_ia32.cc b/runtime/vm/assembler_ia32.cc
index f05f3bc..adc9505 100644
--- a/runtime/vm/assembler_ia32.cc
+++ b/runtime/vm/assembler_ia32.cc
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
+#include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_IA32)
 
 #include "vm/assembler.h"
@@ -1497,6 +1497,13 @@
 }
 
 
+void Assembler::orl(const Address& address, Register reg) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitUint8(0x09);
+  EmitOperand(reg, address);
+}
+
+
 void Assembler::xorl(Register dst, Register src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0x33);
@@ -2918,6 +2925,47 @@
 }
 
 
+void Assembler::ComputeRange(Register result,
+                             Register value,
+                             Register lo_temp,
+                             Register hi_temp,
+                             Label* not_mint) {
+  Label done;
+  movl(result, value);
+  shrl(result, Immediate(kBitsPerWord - 1));  // Sign bit.
+  testl(value, Immediate(kSmiTagMask));
+  j(ZERO, &done, Assembler::kNearJump);
+  CompareClassId(value, kMintCid, result);
+  j(NOT_EQUAL, not_mint);
+  movl(lo_temp, FieldAddress(value, Mint::value_offset()));
+  movl(hi_temp, FieldAddress(value, Mint::value_offset() + kWordSize));
+  movl(result, Immediate(ICData::kInt32RangeBit));
+  subl(result, hi_temp);  // 10 (positive int32), 11 (negative int32)
+  sarl(lo_temp, Immediate(kBitsPerWord - 1));
+  cmpl(lo_temp, hi_temp);
+  j(EQUAL, &done, Assembler::kNearJump);
+  movl(result, Immediate(ICData::kUint32RangeBit));  // Uint32
+  cmpl(hi_temp, Immediate(0));
+  j(EQUAL, &done, Assembler::kNearJump);
+  movl(result, Immediate(ICData::kInt64RangeBit));  // Int64
+  Bind(&done);
+}
+
+
+void Assembler::UpdateRangeFeedback(Register value,
+                                    intptr_t index,
+                                    Register ic_data,
+                                    Register scratch1,
+                                    Register scratch2,
+                                    Register scratch3,
+                                    Label* miss) {
+  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
+  ComputeRange(scratch1, value, scratch2, scratch3, miss);
+  shll(scratch1, Immediate(ICData::RangeFeedbackShift(index)));
+  orl(FieldAddress(ic_data, ICData::state_bits_offset()), scratch1);
+}
+
+
 Address Assembler::ElementAddressForIntIndex(bool is_external,
                                              intptr_t cid,
                                              intptr_t index_scale,
diff --git a/runtime/vm/assembler_ia32.h b/runtime/vm/assembler_ia32.h
index eae58e0..23ea4a2 100644
--- a/runtime/vm/assembler_ia32.h
+++ b/runtime/vm/assembler_ia32.h
@@ -544,6 +544,7 @@
   void orl(Register dst, const Immediate& imm);
   void orl(Register dst, Register src);
   void orl(Register dst, const Address& address);
+  void orl(const Address& address, Register dst);
 
   void xorl(Register dst, const Immediate& imm);
   void xorl(Register dst, Register src);
@@ -726,6 +727,20 @@
                             Register scratch,
                             Label* is_smi);
 
+  void ComputeRange(Register result,
+                    Register value,
+                    Register lo_temp,
+                    Register hi_temp,
+                    Label* miss);
+
+  void UpdateRangeFeedback(Register value,
+                           intptr_t index,
+                           Register ic_data,
+                           Register scratch1,
+                           Register scratch2,
+                           Register scratch3,
+                           Label* miss);
+
   static Address ElementAddressForIntIndex(bool is_external,
                                            intptr_t cid,
                                            intptr_t index_scale,
diff --git a/runtime/vm/assembler_ia32_test.cc b/runtime/vm/assembler_ia32_test.cc
index bd5a0fc..b260e17 100644
--- a/runtime/vm/assembler_ia32_test.cc
+++ b/runtime/vm/assembler_ia32_test.cc
@@ -398,14 +398,20 @@
   __ pushl(Immediate(0x1C));
   __ xorl(ECX, Address(ESP, 0));  // 0x65B.
   __ popl(EAX);  // Discard.
+  __ movl(EAX, Address(ESP, kWordSize));
+  __ movl(EDX, Immediate(0xB0));
+  __ orl(Address(EAX, 0), EDX);
   __ movl(EAX, ECX);
   __ ret();
 }
 
 
 ASSEMBLER_TEST_RUN(Bitwise, test) {
-  typedef int (*Bitwise)();
-  EXPECT_EQ(0x65B, reinterpret_cast<Bitwise>(test->entry())());
+  typedef int (*Bitwise)(int* value);
+  int value = 0xA;
+  const int result = reinterpret_cast<Bitwise>(test->entry())(&value);
+  EXPECT_EQ(0x65B, result);
+  EXPECT_EQ(0xBA, value);
 }
 
 
@@ -3399,6 +3405,57 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
+  Label miss, done;
+  __ movl(ECX, Address(ESP, 1 * kWordSize));
+
+  __ pushl(ESI);
+  __ pushl(EDI);
+  __ ComputeRange(EAX, ECX, ESI, EDI, &miss);
+  __ jmp(&done);
+
+  __ Bind(&miss);
+  __ movl(EAX, Immediate(-1));
+
+  __ Bind(&done);
+  __ popl(EDI);
+  __ popl(ESI);
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(ComputeRange, test) {
+  typedef intptr_t (*ComputeRange)(RawObject* value);
+  ComputeRange range_of = reinterpret_cast<ComputeRange>(test->entry());
+
+  EXPECT_EQ(0, range_of(Smi::New(0)));
+  EXPECT_EQ(0, range_of(Smi::New(1)));
+  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(-1)));
+  EXPECT_EQ(0, range_of(Smi::New(Smi::kMaxValue)));
+  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(Smi::kMinValue)));
+
+  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Integer::New(Smi::kMaxValue + 1)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            range_of(Integer::New(Smi::kMinValue - 1)));
+  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Integer::New(kMaxInt32)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            range_of(Integer::New(kMinInt32)));
+
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            range_of(Integer::New(static_cast<int64_t>(kMaxInt32) + 1)));
+  EXPECT_EQ(ICData::kUint32RangeBit, range_of(Integer::New(kMaxUint32)));
+
+  EXPECT_EQ(ICData::kInt64RangeBit,
+            range_of(Integer::New(static_cast<int64_t>(kMaxUint32) + 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit,
+            range_of(Integer::New(static_cast<int64_t>(kMinInt32) - 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMaxInt64)));
+  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMinInt64)));
+
+  EXPECT_EQ(-1, range_of(Bool::True().raw()));
+}
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_IA32
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index 811023d..66dbac3 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
+#include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_MIPS)
 
 #include "vm/assembler.h"
@@ -702,6 +702,49 @@
 }
 
 
+void Assembler::ComputeRange(Register result,
+                             Register value,
+                             Label* miss) {
+  const Register hi = TMP;
+  const Register lo = CMPRES2;
+
+  Label done;
+  srl(result, value, kBitsPerWord - 1);
+  andi(CMPRES1, value, Immediate(kSmiTagMask));
+  beq(CMPRES1, ZR, &done);
+
+  LoadClassId(CMPRES1, value);
+  BranchNotEqual(CMPRES1, Immediate(kMintCid), miss);
+  LoadFieldFromOffset(hi, value, Mint::value_offset() + kWordSize);
+  LoadFieldFromOffset(lo, value, Mint::value_offset());
+  sra(lo, lo, kBitsPerWord - 1);
+
+  LoadImmediate(result, ICData::kInt32RangeBit);
+
+  beq(hi, lo, &done);
+  delay_slot()->subu(result, result, hi);
+
+  beq(hi, ZR, &done);
+  delay_slot()->addiu(result, ZR, Immediate(ICData::kUint32RangeBit));
+  LoadImmediate(result, ICData::kInt64RangeBit);
+  Bind(&done);
+}
+
+
+void Assembler::UpdateRangeFeedback(Register value,
+                                    intptr_t index,
+                                    Register ic_data,
+                                    Register scratch,
+                                    Label* miss) {
+  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
+  ComputeRange(scratch, value, miss);
+  LoadFieldFromOffset(TMP, ic_data, ICData::state_bits_offset());
+  sll(scratch, scratch, ICData::RangeFeedbackShift(index));
+  or_(TMP, TMP, scratch);
+  StoreFieldToOffset(TMP, ic_data, ICData::state_bits_offset());
+}
+
+
 void Assembler::EnterFrame() {
   ASSERT(!in_delay_slot_);
   addiu(SP, SP, Immediate(-2 * kWordSize));
diff --git a/runtime/vm/assembler_mips.h b/runtime/vm/assembler_mips.h
index 6e12f0b..188fea7 100644
--- a/runtime/vm/assembler_mips.h
+++ b/runtime/vm/assembler_mips.h
@@ -561,7 +561,7 @@
 
   void lui(Register rt, const Immediate& imm) {
     ASSERT(Utils::IsUint(kImmBits, imm.value()));
-    uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    const uint16_t imm_value = static_cast<uint16_t>(imm.value());
     EmitIType(LUI, R0, rt, imm_value);
   }
 
@@ -673,7 +673,7 @@
 
   void ori(Register rt, Register rs, const Immediate& imm) {
     ASSERT(Utils::IsUint(kImmBits, imm.value()));
-    uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    const uint16_t imm_value = static_cast<uint16_t>(imm.value());
     EmitIType(ORI, rs, rt, imm_value);
   }
 
@@ -704,13 +704,16 @@
 
   void slti(Register rt, Register rs, const Immediate& imm) {
     ASSERT(Utils::IsInt(kImmBits, imm.value()));
-    int16_t imm_value = static_cast<int16_t>(imm.value());
+    const uint16_t imm_value = static_cast<uint16_t>(imm.value());
     EmitIType(SLTI, rs, rt, imm_value);
   }
 
+  // Although imm argument is int32_t, it is interpreted as an uint32_t.
+  // For example, -1 stands for 0xffffffffUL: it is encoded as 0xffff in the
+  // instruction imm field and is then sign extended back to 0xffffffffUL.
   void sltiu(Register rt, Register rs, const Immediate& imm) {
-    ASSERT(Utils::IsUint(kImmBits, imm.value()));
-    uint16_t imm_value = static_cast<uint16_t>(imm.value());
+    ASSERT(Utils::IsInt(kImmBits, imm.value()));
+    const uint16_t imm_value = static_cast<uint16_t>(imm.value());
     EmitIType(SLTIU, rs, rt, imm_value);
   }
 
@@ -1082,7 +1085,7 @@
   void BranchUnsignedLess(Register rd, const Immediate& imm, Label* l) {
     ASSERT(!in_delay_slot_);
     ASSERT(imm.value() != 0);
-    if (Utils::IsUint(kImmBits, imm.value())) {
+    if (Utils::IsInt(kImmBits, imm.value())) {
       sltiu(CMPRES2, rd, imm);
       bne(CMPRES2, ZR, l);
     } else {
@@ -1178,6 +1181,11 @@
     }
   }
 
+  void StoreFieldToOffset(Register reg, Register base, int32_t offset) {
+    StoreToOffset(reg, base, offset - kHeapObjectTag);
+  }
+
+
   void StoreDToOffset(DRegister reg, Register base, int32_t offset) {
     ASSERT(!in_delay_slot_);
     FRegister lo = static_cast<FRegister>(reg * 2);
@@ -1223,6 +1231,16 @@
   void LoadClass(Register result, Register object);
   void LoadTaggedClassIdMayBeSmi(Register result, Register object);
 
+  void ComputeRange(Register result,
+                    Register value,
+                    Label* miss);
+
+  void UpdateRangeFeedback(Register value,
+                           intptr_t index,
+                           Register ic_data,
+                           Register scratch,
+                           Label* miss);
+
   void StoreIntoObject(Register object,  // Object we are storing into.
                        const Address& dest,  // Where we are storing into.
                        Register value,  // Value we are storing.
diff --git a/runtime/vm/assembler_mips_test.cc b/runtime/vm/assembler_mips_test.cc
index 399b1bb..b49b806 100644
--- a/runtime/vm/assembler_mips_test.cc
+++ b/runtime/vm/assembler_mips_test.cc
@@ -622,7 +622,7 @@
 ASSEMBLER_TEST_GENERATE(Sltu, assembler) {
   __ LoadImmediate(T1, -1);
   __ LoadImmediate(T2, 0);
-  __ sltu(V0, T1, T2);
+  __ sltu(V0, T1, T2);  // 0xffffffffUL < 0 -> 0.
   __ jr(RA);
 }
 
@@ -633,6 +633,40 @@
 }
 
 
+ASSEMBLER_TEST_GENERATE(Slti, assembler) {
+  __ LoadImmediate(T1, -2);
+  __ slti(A0, T1, Immediate(-1));  // -2 < -1 -> 1.
+  __ slti(A1, T1, Immediate(0));  // -2 < 0 -> 1.
+  __ and_(V0, A0, A1);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Slti, test) {
+  typedef int (*SimpleCode)() DART_UNUSED;
+  EXPECT_EQ(1, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Sltiu, assembler) {
+  __ LoadImmediate(T1, -1);
+  __ LoadImmediate(T2, 0x10000);
+  __ sltiu(A0, T1, Immediate(-2));  // 0xffffffffUL < 0xfffffffeUL -> 0.
+  __ sltiu(A1, T1, Immediate(0));  // 0xffffffffUL < 0 -> 0.
+  __ sltiu(A2, T2, Immediate(-2));  // 0x10000UL < 0xfffffffeUL -> 1.
+  __ addiu(A2, A2, Immediate(-1));
+  __ or_(V0, A0, A1);
+  __ or_(V0, V0, A2);
+  __ jr(RA);
+}
+
+
+ASSEMBLER_TEST_RUN(Sltiu, test) {
+  typedef int (*SimpleCode)() DART_UNUSED;
+  EXPECT_EQ(0, EXECUTE_TEST_CODE_INT32(SimpleCode, test->entry()));
+}
+
+
 ASSEMBLER_TEST_GENERATE(Movz, assembler) {
   __ LoadImmediate(T1, 42);
   __ LoadImmediate(T2, 23);
@@ -2066,6 +2100,58 @@
   __ Ret();
 }
 
+
+ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
+  Label miss, done;
+  __ ComputeRange(V0, A0, &miss);
+  __ b(&done);
+
+  __ Bind(&miss);
+  __ LoadImmediate(V0, -1);
+
+  __ Bind(&done);
+  __ Ret();
+}
+
+
+ASSEMBLER_TEST_RUN(ComputeRange, test) {
+  typedef intptr_t (*ComputeRange)(intptr_t value) DART_UNUSED;
+
+#define RANGE_OF(v)                                              \
+  (EXECUTE_TEST_CODE_INTPTR_INTPTR(                              \
+    ComputeRange, test->entry(), reinterpret_cast<intptr_t>(v)))
+
+  EXPECT_EQ(0, RANGE_OF(Smi::New(0)));
+  EXPECT_EQ(0, RANGE_OF(Smi::New(1)));
+  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(-1)));
+  EXPECT_EQ(0, RANGE_OF(Smi::New(Smi::kMaxValue)));
+  EXPECT_EQ(ICData::kSignedRangeBit, RANGE_OF(Smi::New(Smi::kMinValue)));
+
+  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(Smi::kMaxValue + 1)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            RANGE_OF(Integer::New(Smi::kMinValue - 1)));
+  EXPECT_EQ(ICData::kInt32RangeBit, RANGE_OF(Integer::New(kMaxInt32)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            RANGE_OF(Integer::New(kMinInt32)));
+
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxInt32) + 1)));
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            RANGE_OF(Integer::New(kMaxUint32)));
+
+  EXPECT_EQ(ICData::kInt64RangeBit,
+            RANGE_OF(Integer::New(static_cast<int64_t>(kMaxUint32) + 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit,
+            RANGE_OF(Integer::New(static_cast<int64_t>(kMinInt32) - 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMaxInt64)));
+  EXPECT_EQ(ICData::kInt64RangeBit, RANGE_OF(Integer::New(kMinInt64)));
+
+  EXPECT_EQ(-1, RANGE_OF(Bool::True().raw()));
+
+#undef RANGE_OF
+}
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_MIPS
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index d463af6..c14b183 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/globals.h"
+#include "vm/globals.h"  // NOLINT
 #if defined(TARGET_ARCH_X64)
 
 #include "vm/assembler.h"
@@ -1681,6 +1681,14 @@
 }
 
 
+void Assembler::orl(const Address& address, Register reg) {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitOperandREX(reg, address, REX_NONE);
+  EmitUint8(0x09);
+  EmitOperand(reg & 7, address);
+}
+
+
 void Assembler::xorl(Register dst, Register src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   Operand operand(src);
@@ -3780,6 +3788,48 @@
 }
 
 
+void Assembler::ComputeRange(Register result, Register value, Label* not_mint) {
+  Label done, not_smi;
+  testl(value, Immediate(kSmiTagMask));
+  j(NOT_ZERO, &not_smi, Assembler::kNearJump);
+
+  sarq(value, Immediate(32));  // Take the tag into account.
+  movq(result, Immediate(ICData::kUint32RangeBit));  // Uint32
+  cmpq(value, Immediate(1));
+  j(EQUAL, &done, Assembler::kNearJump);
+
+  movq(result, Immediate(ICData::kInt32RangeBit));
+  subq(result, value);  // 10 (positive int32), 11 (negative int32)
+  negq(value);
+  cmpq(value, Immediate(1));
+  j(BELOW_EQUAL, &done);
+
+  // On 64-bit we don't need to track sign of smis outside of the Int32 range.
+  // Just pretend they are all signed.
+  movq(result, Immediate(ICData::kSignedRangeBit));
+  jmp(&done);
+
+  Bind(&not_smi);
+  CompareClassId(value, kMintCid);
+  j(NOT_EQUAL, not_mint);
+  movq(result, Immediate(ICData::kInt64RangeBit));
+
+  Bind(&done);
+}
+
+
+void Assembler::UpdateRangeFeedback(Register value,
+                                    intptr_t index,
+                                    Register ic_data,
+                                    Register scratch,
+                                    Label* miss) {
+  ASSERT(ICData::IsValidRangeFeedbackIndex(index));
+  ComputeRange(scratch, value, miss);
+  shll(scratch, Immediate(ICData::RangeFeedbackShift(index)));
+  orl(FieldAddress(ic_data, ICData::state_bits_offset()), scratch);
+}
+
+
 Address Assembler::ElementAddressForIntIndex(bool is_external,
                                              intptr_t cid,
                                              intptr_t index_scale,
diff --git a/runtime/vm/assembler_x64.h b/runtime/vm/assembler_x64.h
index 44d4596..3fdde8c 100644
--- a/runtime/vm/assembler_x64.h
+++ b/runtime/vm/assembler_x64.h
@@ -526,6 +526,7 @@
 
   void orl(Register dst, Register src);
   void orl(Register dst, const Immediate& imm);
+  void orl(const Address& dst, Register src);
 
   void xorl(Register dst, Register src);
 
@@ -829,6 +830,13 @@
     sarq(reg, Immediate(kSmiTagSize));
   }
 
+  void ComputeRange(Register result, Register value, Label* miss);
+  void UpdateRangeFeedback(Register value,
+                           intptr_t index,
+                           Register ic_data,
+                           Register scratch,
+                           Label* miss);
+
   int PreferredLoopAlignment() { return 16; }
   void Align(int alignment, intptr_t offset);
   void Bind(Label* label);
diff --git a/runtime/vm/assembler_x64_test.cc b/runtime/vm/assembler_x64_test.cc
index 541b1b9..388c00b 100644
--- a/runtime/vm/assembler_x64_test.cc
+++ b/runtime/vm/assembler_x64_test.cc
@@ -1008,6 +1008,9 @@
 
 
 ASSEMBLER_TEST_GENERATE(Bitwise, assembler) {
+  __ movq(R10, Immediate(-1));
+  __ orl(Address(CallingConventions::kArg1Reg, 0), R10);
+  __ orl(Address(CallingConventions::kArg2Reg, 0), R10);
   __ movl(RCX, Immediate(42));
   __ xorl(RCX, RCX);
   __ orl(RCX, Immediate(256));
@@ -1023,8 +1026,13 @@
 
 
 ASSEMBLER_TEST_RUN(Bitwise, test) {
-  typedef int (*Bitwise)();
-  EXPECT_EQ(256 + 1, reinterpret_cast<Bitwise>(test->entry())());
+  uint64_t f1 = 0;
+  uint64_t f2 = 0;
+  typedef int (*Bitwise)(void*, void*);
+  int result = reinterpret_cast<Bitwise>(test->entry())(&f1, &f2);
+  EXPECT_EQ(256 + 1, result);
+  EXPECT_EQ(kMaxUint32, f1);
+  EXPECT_EQ(kMaxUint32, f2);
 }
 
 
@@ -3403,6 +3411,55 @@
   EXPECT_EQ(0, res);
 }
 
+
+ASSEMBLER_TEST_GENERATE(ComputeRange, assembler) {
+  Label miss;
+  __ movq(RDX, CallingConventions::kArg1Reg);
+  __ ComputeRange(RAX, RDX, &miss);
+  __ ret();
+
+  __ Bind(&miss);
+  __ movq(RAX, Immediate(0));
+  __ ret();
+}
+
+
+ASSEMBLER_TEST_RUN(ComputeRange, test) {
+  typedef intptr_t (*ComputeRange)(RawObject*);
+  ComputeRange range_of = reinterpret_cast<ComputeRange>(test->entry());
+
+  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Smi::New(0)));
+  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Smi::New(1)));
+  EXPECT_EQ(ICData::kInt32RangeBit, range_of(Smi::New(kMaxInt32)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            range_of(Smi::New(-1)));
+  EXPECT_EQ(ICData::kInt32RangeBit | ICData::kSignedRangeBit,
+            range_of(Smi::New(kMinInt32)));
+
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            range_of(Smi::New(static_cast<int64_t>(kMaxInt32) + 1)));
+  EXPECT_EQ(ICData::kUint32RangeBit,
+            range_of(Smi::New(kMaxUint32)));
+
+  // On 64-bit platforms we don't track the sign of the smis outside of
+  // int32 range because it is not needed to distinguish kInt32Range from
+  // kUint32Range.
+  EXPECT_EQ(ICData::kSignedRangeBit,
+            range_of(Smi::New(static_cast<int64_t>(kMinInt32) - 1)));
+  EXPECT_EQ(ICData::kSignedRangeBit,
+            range_of(Smi::New(static_cast<int64_t>(kMaxUint32) + 1)));
+  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(Smi::kMaxValue)));
+  EXPECT_EQ(ICData::kSignedRangeBit, range_of(Smi::New(Smi::kMinValue)));
+
+  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(Smi::kMaxValue + 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(Smi::kMinValue - 1)));
+  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMaxInt64)));
+  EXPECT_EQ(ICData::kInt64RangeBit, range_of(Integer::New(kMinInt64)));
+
+  EXPECT_EQ(0, range_of(Bool::True().raw()));
+}
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_X64
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 849c7a1..8db25ad 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1192,7 +1192,15 @@
     isolate->heap()->CollectGarbage(Heap::kNew);
   }
   if ((interrupt_bits & Isolate::kMessageInterrupt) != 0) {
-    isolate->message_handler()->HandleOOBMessages();
+    bool ok = isolate->message_handler()->HandleOOBMessages();
+    if (!ok) {
+      // False result from HandleOOBMessages signals that the isolate should
+      // be terminating.
+      const String& msg = String::Handle(String::New("isolate terminated"));
+      const UnwindError& error = UnwindError::Handle(UnwindError::New(msg));
+      Exceptions::PropagateError(error);
+      UNREACHABLE();
+    }
   }
   if ((interrupt_bits & Isolate::kApiInterrupt) != 0) {
     // Signal isolate interrupt event.
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index f039ecf..3ef6a78 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -639,6 +639,9 @@
         }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
+        DeadCodeElimination::EliminateDeadPhis(flow_graph);
+        DEBUG_ASSERT(flow_graph->VerifyUseLists());
+
         // Ensure that all phis inserted by optimization passes have consistent
         // representations.
         optimizer.SelectRepresentations();
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 06625a6..b599644 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -8,6 +8,7 @@
 #include "vm/cpu.h"
 #include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
+#include "vm/debugger.h"
 #include "vm/flags.h"
 #include "vm/freelist.h"
 #include "vm/handles.h"
@@ -253,7 +254,7 @@
     isolate->class_table()->Print();
   }
 
-
+  isolate->debugger()->NotifyIsolateCreated();
   Service::SendIsolateStartupMessage();
   // Create tag table.
   isolate->set_tag_table(
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 226eeb9..468f13d 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -64,6 +64,7 @@
       end_token_pos_(end_token_pos),
       is_resolved_(false),
       is_enabled_(false),
+      is_one_shot_(false),
       next_(NULL),
       function_(Function::null()),
       line_number_(-1) {
@@ -1138,48 +1139,8 @@
 }
 
 
-RawError* Debugger::SetInternalBreakpoints(const Function& target_function) {
-  if (target_function.is_native()) {
-    // Can't instrument native functions. Fail silently.
-    return Error::null();
-  }
-  Isolate* isolate = Isolate::Current();
-  if (!target_function.HasCode()) {
-    const Error& error = Error::Handle(
-        Compiler::CompileFunction(isolate, target_function));
-    if (!error.IsNull()) {
-      return error.raw();
-    }
-  }
-  // Hang on to the code object before deoptimizing, in case deoptimization
-  // might cause the GC to run.
-  Code& code = Code::Handle(isolate, target_function.unoptimized_code());
-  ASSERT(!code.IsNull());
-  DeoptimizeWorld();
-  ASSERT(!target_function.HasOptimizedCode());
-  PcDescriptors& desc = PcDescriptors::Handle(isolate, code.pc_descriptors());
-  PcDescriptors::Iterator iter(desc, kSafepointKind);
-  while (iter.MoveNext()) {
-    if (iter.TokenPos() != Scanner::kNoSourcePos) {
-      CodeBreakpoint* bpt = GetCodeBreakpoint(iter.Pc());
-      if (bpt != NULL) {
-        // There is already a breakpoint for this address. Make sure
-        // it is enabled.
-        bpt->Enable();
-        continue;
-      }
-      bpt = new CodeBreakpoint(code, iter.TokenPos(),
-                               iter.Pc(), iter.Kind());
-      RegisterCodeBreakpoint(bpt);
-      bpt->Enable();
-    }
-  }
-  return Error::null();
-}
-
-
 void Debugger::SignalBpResolved(SourceBreakpoint* bpt) {
-  if (HasEventHandler()) {
+  if (HasEventHandler() && !bpt->IsOneShot()) {
     DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointResolved);
     event.set_breakpoint(bpt);
     InvokeEventHandler(&event);
@@ -1418,9 +1379,23 @@
 }
 
 
+static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) {
+  TokenStream::Iterator iter(tokens, pos, TokenStream::Iterator::kAllTokens);
+  ASSERT(iter.IsValid());
+  intptr_t last_pos = pos;
+  while ((iter.CurrentTokenKind() != Token::kNEWLINE) &&
+      (iter.CurrentTokenKind() != Token::kEOS)) {
+    last_pos = iter.CurrentPosition();
+    iter.Advance();
+  }
+  return last_pos;
+}
+
+
 // Given a function and a token range, return the best fit
 // token position to set a breakpoint. The best fit is the safe point
-// with the lowest compiled code address within the token range.
+// in the line closest to the beginning of the token range, and within
+// that line, the safe point with the lowest compiled code address.
 intptr_t Debugger::ResolveBreakpointPos(const Function& func,
                                         intptr_t requested_token_pos,
                                         intptr_t last_token_pos) {
@@ -1437,41 +1412,45 @@
   Code& code = Code::Handle(func.unoptimized_code());
   ASSERT(!code.IsNull());
   PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
+
+  // First pass: find the safe point which is closest to the beginning
+  // of the given token range.
   intptr_t best_fit_pos = INT_MAX;
-  uword lowest_pc = kUwordMax;
-  intptr_t lowest_pc_token_pos = INT_MAX;
   PcDescriptors::Iterator iter(desc, kSafepointKind);
   while (iter.MoveNext()) {
     const intptr_t desc_token_pos = iter.TokenPos();
-    ASSERT(desc_token_pos >= 0);
-    if (desc_token_pos != Scanner::kNoSourcePos) {
-      if ((desc_token_pos < requested_token_pos) ||
-          (desc_token_pos > last_token_pos)) {
-        // This descriptor is outside the desired token range.
-        continue;
-      }
-      if (desc_token_pos < best_fit_pos) {
-        // So far, this descriptor has the lowest token position after
-        // the first acceptable token position.
-        best_fit_pos = desc_token_pos;
-      }
-      if (iter.Pc() < lowest_pc) {
-        // This descriptor so far has the lowest code address.
-        lowest_pc = iter.Pc();
-        lowest_pc_token_pos = desc_token_pos;
-      }
+    if ((desc_token_pos != Scanner::kNoSourcePos) &&
+        (desc_token_pos < best_fit_pos) &&
+        (desc_token_pos >= requested_token_pos) &&
+        (desc_token_pos <= last_token_pos)) {
+       best_fit_pos = desc_token_pos;
     }
   }
-  if (lowest_pc_token_pos != INT_MAX) {
-    // We found the pc descriptor that has the lowest execution address.
-    // This is the first possible breakpoint after the requested token
-    // position. We use this instead of the nearest PC descriptor
-    // measured in token index distance.
-    return lowest_pc_token_pos;
-  }
+  // Second pass (if we found a safe point in the first pass):
+  // For all token positions on the same line, select the one
+  // with the lowest compiled code address. E.g., in a line with
+  // the nested function calls f(g(x)), the call g() will have a lower
+  // compiled code address but is not the lowest token position in the
+  // line.
   if (best_fit_pos != INT_MAX) {
+    const Script& script = Script::Handle(func.script());
+    const TokenStream& tokens = TokenStream::Handle(script.tokens());
+    const intptr_t begin_pos = best_fit_pos;
+    const intptr_t end_of_line_pos = LastTokenOnLine(tokens, begin_pos);
+    uword lowest_pc = kUwordMax;
+    PcDescriptors::Iterator iter(desc, kSafepointKind);
+    while (iter.MoveNext()) {
+      const intptr_t pos = iter.TokenPos();
+      if ((pos != Scanner::kNoSourcePos) &&
+          (begin_pos <= pos) && (pos <= end_of_line_pos) &&
+          (iter.Pc() < lowest_pc)) {
+        lowest_pc = iter.Pc();
+        best_fit_pos = pos;
+      }
+    }
     return best_fit_pos;
   }
+
   // We didn't find a safe point in the given token range. Try and find
   // a safe point in the remaining source code of the function.
   if (last_token_pos < func.end_token_pos()) {
@@ -1554,12 +1533,12 @@
           if ((function.token_pos() == start_pos)
               && (function.end_token_pos() == end_pos)
               && (function.script() == script.raw())) {
-            if (function.HasCode()) {
+            if (function.HasCode() && !function.IsAsyncFunction()) {
               function_list->Add(function);
             }
             if (function.HasImplicitClosureFunction()) {
               function = function.ImplicitClosureFunction();
-              if (function.HasCode()) {
+              if (function.HasCode() && !function.IsAsyncFunction()) {
                 function_list->Add(function);
               }
             }
@@ -1575,12 +1554,12 @@
           if ((function.token_pos() == start_pos)
               && (function.end_token_pos() == end_pos)
               && (function.script() == script.raw())) {
-            if (function.HasCode()) {
+            if (function.HasCode() && !function.IsAsyncFunction()) {
               function_list->Add(function);
             }
             if (function.HasImplicitClosureFunction()) {
               function = function.ImplicitClosureFunction();
-              if (function.HasCode()) {
+              if (function.HasCode() && !function.IsAsyncFunction()) {
                 function_list->Add(function);
               }
             }
@@ -1723,7 +1702,7 @@
       if (FLAG_verbose_debug) {
         intptr_t line_number;
         script.GetTokenLocation(breakpoint_pos, &line_number, NULL);
-        OS::Print("Resolved breakpoint for "
+        OS::Print("Resolved BP for "
                   "function '%s' at line %" Pd "\n",
                   func.ToFullyQualifiedCString(),
                   line_number);
@@ -1770,14 +1749,11 @@
 
 
 RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) {
-  Error& err = Error::Handle();
-  err = SetInternalBreakpoints(target_function);
-  if (err.IsNull() && target_function.HasImplicitClosureFunction()) {
-    const Function& closure_func =
-        Function::Handle(target_function.ImplicitClosureFunction());
-    err = SetInternalBreakpoints(closure_func);
+  SourceBreakpoint* bpt = SetBreakpointAtEntry(target_function);
+  if (bpt != NULL) {
+    bpt->SetIsOneShot();
   }
-  return err.raw();
+  return Error::null();
 }
 
 
@@ -2088,12 +2064,20 @@
 void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace) {
   stepping_fp_ = 0;
   if (resume_action_ == kSingleStep) {
+    // When single stepping, we need to deoptimize because we might be
+    // stepping into optimized code.  This happens in particular if
+    // the isolate has been interrupted, but can happen in other cases
+    // as well.  We need to deoptimize the world in case we are about
+    // to call an optimized function.
+    DeoptimizeWorld();
     isolate_->set_single_step(true);
   } else if (resume_action_ == kStepOver) {
+    DeoptimizeWorld();
     isolate_->set_single_step(true);
     ASSERT(stack_trace->Length() > 0);
     stepping_fp_ = stack_trace->FrameAt(0)->fp();
   } else if (resume_action_ == kStepOut) {
+    DeoptimizeWorld();
     isolate_->set_single_step(true);
     // Find topmost caller that is debuggable.
     for (intptr_t i = 1; i < stack_trace->Length(); i++) {
@@ -2128,6 +2112,10 @@
   isolate_->set_single_step(false);
   ASSERT(!IsPaused());
   ASSERT(obj_cache_ == NULL);
+  if ((bpt != NULL) && bpt->IsOneShot()) {
+    RemoveBreakpoint(bpt->id());
+    bpt = NULL;
+  }
   DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached);
   event.set_top_frame(top_frame);
   event.set_breakpoint(bpt);
@@ -2240,7 +2228,10 @@
   // debugger wire protocol messages.
   isolate_id_ = isolate->main_port();
   initialized_ = true;
+}
 
+
+void Debugger::NotifyIsolateCreated() {
   // Signal isolate creation event.
   SignalIsolateEvent(DebuggerEvent::kIsolateCreated);
 }
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index fd83e06..779a634 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -48,6 +48,9 @@
   bool IsEnabled() const { return is_enabled_; }
   bool IsResolved() const { return is_resolved_; }
 
+  bool IsOneShot() const { return is_one_shot_; }
+  void SetIsOneShot() { is_one_shot_ = true; }
+
   void PrintJSON(JSONStream* stream);
 
  private:
@@ -63,6 +66,7 @@
   intptr_t end_token_pos_;
   bool is_resolved_;
   bool is_enabled_;
+  bool is_one_shot_;
   SourceBreakpoint* next_;
 
   // Valid for resolved breakpoints:
@@ -334,6 +338,7 @@
   ~Debugger();
 
   void Initialize(Isolate* isolate);
+  void NotifyIsolateCreated();
   void Shutdown();
 
   void NotifyCompilation(const Function& func);
@@ -452,7 +457,6 @@
                                 intptr_t requested_token_pos,
                                 intptr_t last_token_pos);
   void DeoptimizeWorld();
-  RawError* SetInternalBreakpoints(const Function& target_function);
   SourceBreakpoint* SetBreakpoint(const Script& script,
                                   intptr_t token_pos,
                                   intptr_t last_token_pos);
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index b47aaf2..5bb68fd 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -718,7 +718,7 @@
       break;
     }
     case SLTIU: {
-      Format(instr, "sltu 'rt, 'rs, 'immu");
+      Format(instr, "sltiu 'rt, 'rs, 'imms");
       break;
     }
     case SH: {
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 20c1fa5..0db52a3 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -234,7 +234,9 @@
 
     Instruction* last = block->last_instruction();
     BlockEntryInstr* successor = NULL;
-    while ((last->SuccessorCount() == 1) &&
+    while ((!last->IsIndirectGoto()) &&
+           (last->SuccessorCount() == 1) &&
+           (!last->SuccessorAt(0)->IsIndirectEntry()) &&
            (last->SuccessorAt(0)->PredecessorCount() == 1) &&
            (block->try_index() == last->SuccessorAt(0)->try_index())) {
       successor = last->SuccessorAt(0);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 7e32c7b..5f3bd7e 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -293,6 +293,9 @@
       block->AsTargetEntry()->adjust_edge_weight(scale_factor);
     }
     Instruction* instr = block;
+    if (block->env() != NULL) {
+      call_->env()->DeepCopyToOuter(callee_graph->isolate(), block);
+    }
     for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
       instr = it.Current();
       // TODO(zerny): Avoid creating unnecessary environments. Note that some
@@ -358,7 +361,6 @@
     caller_graph_->set_max_block_id(join_id);
     JoinEntryInstr* join =
         new(I) JoinEntryInstr(join_id, try_index);
-    join->InheritDeoptTargetAfter(isolate(), call_);
 
     // The dominator set of the join is the intersection of the dominator
     // sets of all the predecessors.  If we keep the dominator sets ordered
@@ -430,6 +432,7 @@
         phi->SetInputAt(i, ValueAt(i));
       }
       join->InsertPhi(phi);
+      join->InheritDeoptTargetAfter(caller_graph_, call_, phi);
       return phi;
     } else {
       // In the case that the result is unused, remove the return value uses
@@ -437,6 +440,7 @@
       for (intptr_t i = 0; i < num_exits; ++i) {
         ReturnAt(i)->UnuseAllInputs();
       }
+      join->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
       return NULL;
     }
   }
@@ -462,7 +466,7 @@
     TargetEntryInstr* false_block =
         new(I) TargetEntryInstr(caller_graph_->allocate_block_id(),
                                 call_block->try_index());
-    false_block->InheritDeoptTargetAfter(isolate(), call_);
+    false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
     false_block->LinkTo(call_->next());
     call_block->ReplaceAsPredecessorWith(false_block);
 
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 3c2d60b..9a06e50 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -688,57 +688,11 @@
   //    corresponding spill slot locations.
   for (Environment::DeepIterator it(env); !it.Done(); it.Advance()) {
     Location loc = it.CurrentLocation();
-    if (loc.IsRegister()) {
-      intptr_t index = cpu_reg_slots[loc.reg()];
-      ASSERT(index >= 0);
-      it.SetCurrentLocation(Location::StackSlot(index));
-    } else if (loc.IsFpuRegister()) {
-      intptr_t index = fpu_reg_slots[loc.fpu_reg()];
-      ASSERT(index >= 0);
-      Value* value = it.CurrentValue();
-      switch (value->definition()->representation()) {
-        case kUnboxedDouble:
-          it.SetCurrentLocation(Location::DoubleStackSlot(index));
-          break;
-        case kUnboxedFloat32x4:
-        case kUnboxedInt32x4:
-        case kUnboxedFloat64x2:
-          it.SetCurrentLocation(Location::QuadStackSlot(index));
-          break;
-        default:
-          UNREACHABLE();
-      }
-    } else if (loc.IsPairLocation()) {
-      intptr_t representation =
-          it.CurrentValue()->definition()->representation();
-      ASSERT(representation == kUnboxedMint);
-      PairLocation* value_pair = loc.AsPairLocation();
-      intptr_t index_lo;
-      intptr_t index_hi;
-      if (value_pair->At(0).IsRegister()) {
-        index_lo = cpu_reg_slots[value_pair->At(0).reg()];
-      } else {
-        ASSERT(value_pair->At(0).IsStackSlot());
-        index_lo = value_pair->At(0).stack_index();
-      }
-      if (value_pair->At(1).IsRegister()) {
-        index_hi = cpu_reg_slots[value_pair->At(1).reg()];
-      } else {
-        ASSERT(value_pair->At(1).IsStackSlot());
-        index_hi = value_pair->At(1).stack_index();
-      }
-      it.SetCurrentLocation(Location::Pair(Location::StackSlot(index_lo),
-                                           Location::StackSlot(index_hi)));
-    } else if (loc.IsInvalid()) {
-      Definition* def =
-          it.CurrentValue()->definition();
-      ASSERT(def != NULL);
-      if (def->IsMaterializeObject()) {
-        def->AsMaterializeObject()->RemapRegisters(fpu_reg_slots,
-                                                   cpu_reg_slots);
-      }
-    }
+    Value* value = it.CurrentValue();
+    it.SetCurrentLocation(loc.RemapForSlowPath(
+        value->definition(), cpu_reg_slots, fpu_reg_slots));
   }
+
   return env;
 }
 
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index ae3791f..c62c6b8 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -417,14 +417,14 @@
                        intptr_t token_index,
                        LocationSummary* locs);
 
-  void EmitEqualityRegConstCompare(Register reg,
-                                   const Object& obj,
-                                   bool needs_number_check,
-                                   intptr_t token_pos);
-  void EmitEqualityRegRegCompare(Register left,
-                                 Register right,
-                                 bool needs_number_check,
-                                 intptr_t token_pos);
+  Condition EmitEqualityRegConstCompare(Register reg,
+                                        const Object& obj,
+                                        bool needs_number_check,
+                                        intptr_t token_pos);
+  Condition EmitEqualityRegRegCompare(Register left,
+                                      Register right,
+                                      bool needs_number_check,
+                                      intptr_t token_pos);
 
   void EmitTrySync(Instruction* instr, intptr_t try_index);
 
@@ -481,6 +481,9 @@
 
   void SaveLiveRegisters(LocationSummary* locs);
   void RestoreLiveRegisters(LocationSummary* locs);
+#if defined(DEBUG)
+  void ClobberDeadTempRegisters(LocationSummary* locs);
+#endif
 
   Environment* SlowPathEnvironmentFor(Instruction* instruction);
 
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index d6aa12c..b65fc43 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1381,10 +1381,11 @@
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
-                                                    const Object& obj,
-                                                    bool needs_number_check,
-                                                    intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
+    Register reg,
+    const Object& obj,
+    bool needs_number_check,
+    intptr_t token_pos) {
   if (needs_number_check) {
     StubCode* stub_code = isolate()->stub_code();
     ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
@@ -1402,19 +1403,20 @@
                            Isolate::kNoDeoptId,
                            token_pos);
     }
+    // Stub returns result in flags (result of a cmp, we need Z computed).
     __ Drop(1);  // Discard constant.
     __ Pop(reg);  // Restore 'reg'.
-    return;
+  } else {
+    __ CompareObject(reg, obj);
   }
-
-  __ CompareObject(reg, obj);
+  return EQ;
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                  Register right,
-                                                  bool needs_number_check,
-                                                  intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
+                                                       Register right,
+                                                       bool needs_number_check,
+                                                       intptr_t token_pos) {
   if (needs_number_check) {
     StubCode* stub_code = isolate()->stub_code();
     __ Push(left);
@@ -1438,12 +1440,13 @@
       __ LoadImmediate(R5, kInvalidObjectPointer);
     }
 #endif
-    // Stub returns result in flags (result of a cmpl, we need ZF computed).
+    // Stub returns result in flags (result of a cmp, we need Z computed).
     __ Pop(right);
     __ Pop(left);
   } else {
     __ cmp(left, Operand(right));
   }
+  return EQ;
 }
 
 
@@ -1452,6 +1455,7 @@
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
 #if defined(DEBUG)
   locs->CheckWritableInputs();
+  ClobberDeadTempRegisters(locs);
 #endif
 
   // TODO(vegorov): consider saving only caller save (volatile) registers.
@@ -1490,6 +1494,10 @@
 
 
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
+#if defined(DEBUG)
+  ClobberDeadTempRegisters(locs);
+#endif
+
   // General purpose registers have the highest register number at the
   // lowest address.
   for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
@@ -1520,6 +1528,21 @@
 }
 
 
+#if defined(DEBUG)
+void FlowGraphCompiler::ClobberDeadTempRegisters(LocationSummary* locs) {
+  // Clobber temporaries that have not been manually preserved.
+  for (intptr_t i = 0; i < locs->temp_count(); ++i) {
+    Location tmp = locs->temp(i);
+    // TODO(zerny): clobber non-live temporary FPU registers.
+    if (tmp.IsRegister() &&
+        !locs->live_registers()->ContainsRegister(tmp.reg())) {
+      __ mov(tmp.reg(), Operand(0xf7));
+    }
+  }
+}
+#endif
+
+
 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
                                         Register class_id_reg,
                                         intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 7501c58..4f5c61d 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -1357,10 +1357,11 @@
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
-                                                    const Object& obj,
-                                                    bool needs_number_check,
-                                                    intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
+    Register reg,
+    const Object& obj,
+    bool needs_number_check,
+    intptr_t token_pos) {
   if (needs_number_check) {
     StubCode* stub_code = isolate()->stub_code();
     ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
@@ -1378,19 +1379,20 @@
                            Isolate::kNoDeoptId,
                            token_pos);
     }
+    // Stub returns result in flags (result of a cmp, we need Z computed).
     __ Drop(1);  // Discard constant.
     __ Pop(reg);  // Restore 'reg'.
-    return;
+  } else {
+    __ CompareObject(reg, obj, PP);
   }
-
-  __ CompareObject(reg, obj, PP);
+  return EQ;
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                  Register right,
-                                                  bool needs_number_check,
-                                                  intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
+                                                       Register right,
+                                                       bool needs_number_check,
+                                                       intptr_t token_pos) {
   if (needs_number_check) {
     StubCode* stub_code = isolate()->stub_code();
     __ Push(left);
@@ -1414,12 +1416,13 @@
       __ LoadImmediate(R5, kInvalidObjectPointer, kNoPP);
     }
 #endif
-    // Stub returns result in flags (result of a cmpl, we need ZF computed).
+    // Stub returns result in flags (result of a cmp, we need Z computed).
     __ Pop(right);
     __ Pop(left);
   } else {
     __ CompareRegisters(left, right);
   }
+  return EQ;
 }
 
 
@@ -1428,6 +1431,7 @@
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
 #if defined(DEBUG)
   locs->CheckWritableInputs();
+  ClobberDeadTempRegisters(locs);
 #endif
 
   // TODO(vegorov): consider saving only caller save (volatile) registers.
@@ -1457,6 +1461,9 @@
 
 
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
+#if defined(DEBUG)
+  ClobberDeadTempRegisters(locs);
+#endif
   // General purpose registers have the highest register number at the
   // lowest address.
   for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
@@ -1479,6 +1486,21 @@
 }
 
 
+#if defined(DEBUG)
+void FlowGraphCompiler::ClobberDeadTempRegisters(LocationSummary* locs) {
+  // Clobber temporaries that have not been manually preserved.
+  for (intptr_t i = 0; i < locs->temp_count(); ++i) {
+    Location tmp = locs->temp(i);
+    // TODO(zerny): clobber non-live temporary FPU registers.
+    if (tmp.IsRegister() &&
+        !locs->live_registers()->ContainsRegister(tmp.reg())) {
+      __ movz(tmp.reg(), Immediate(0xf7), 0);
+    }
+  }
+}
+#endif
+
+
 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
                                         Register class_id_reg,
                                         intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 78d7683..a3d4416 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1375,17 +1375,18 @@
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
-                                                    const Object& obj,
-                                                    bool needs_number_check,
-                                                    intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
+    Register reg,
+    const Object& obj,
+    bool needs_number_check,
+    intptr_t token_pos) {
   ASSERT(!needs_number_check ||
          (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
 
   if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
     ASSERT(!needs_number_check);
     __ testl(reg, reg);
-    return;
+    return EQUAL;
   }
 
   if (needs_number_check) {
@@ -1402,19 +1403,20 @@
                            Isolate::kNoDeoptId,
                            token_pos);
     }
+    // Stub returns result in flags (result of a cmpl, we need ZF computed).
     __ popl(reg);  // Discard constant.
     __ popl(reg);  // Restore 'reg'.
-    return;
-  }
-
+  } else {
   __ CompareObject(reg, obj);
+  }
+  return EQUAL;
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                  Register right,
-                                                  bool needs_number_check,
-                                                  intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
+                                                       Register right,
+                                                       bool needs_number_check,
+                                                       intptr_t token_pos) {
   if (needs_number_check) {
     StubCode* stub_code = isolate()->stub_code();
     __ pushl(left);
@@ -1442,6 +1444,7 @@
   } else {
     __ cmpl(left, right);
   }
+  return EQUAL;
 }
 
 
@@ -1450,6 +1453,7 @@
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
 #if defined(DEBUG)
   locs->CheckWritableInputs();
+  ClobberDeadTempRegisters(locs);
 #endif
 
   // TODO(vegorov): consider saving only caller save (volatile) registers.
@@ -1482,6 +1486,10 @@
 
 
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
+#if defined(DEBUG)
+  ClobberDeadTempRegisters(locs);
+#endif
+
   // General purpose registers have the highest register number at the
   // lowest address.
   for (intptr_t reg_idx = kNumberOfCpuRegisters - 1; reg_idx >= 0; --reg_idx) {
@@ -1508,6 +1516,21 @@
 }
 
 
+#if defined(DEBUG)
+void FlowGraphCompiler::ClobberDeadTempRegisters(LocationSummary* locs) {
+  // Clobber temporaries that have not been manually preserved.
+  for (intptr_t i = 0; i < locs->temp_count(); ++i) {
+    Location tmp = locs->temp(i);
+    // TODO(zerny): clobber non-live temporary FPU registers.
+    if (tmp.IsRegister() &&
+        !locs->live_registers()->ContainsRegister(tmp.reg())) {
+      __ movl(tmp.reg(), Immediate(0xf7));
+    }
+  }
+}
+#endif
+
+
 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
                                         Register class_id_reg,
                                         intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 3434984..b3143cc 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1389,10 +1389,11 @@
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
-                                                    const Object& obj,
-                                                    bool needs_number_check,
-                                                    intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
+    Register reg,
+    const Object& obj,
+    bool needs_number_check,
+    intptr_t token_pos) {
   __ TraceSimMsg("EqualityRegConstCompare");
   if (needs_number_check) {
     StubCode* stub_code = isolate()->stub_code();
@@ -1414,18 +1415,21 @@
                            token_pos);
     }
     __ TraceSimMsg("EqualityRegConstCompare return");
+    // Stub returns result in CMPRES1 (if it is 0, then reg and obj are
+    // equal) and always sets CMPRES2 to 0.
     __ lw(reg, Address(SP, 1 * kWordSize));  // Restore 'reg'.
     __ addiu(SP, SP, Immediate(2 * kWordSize));  // Discard constant.
-    return;
+  } else {
+    __ CompareObject(CMPRES1, CMPRES2, reg, obj);
   }
-  __ CompareObject(CMPRES1, CMPRES2, reg, obj);
+  return EQ;
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                  Register right,
-                                                  bool needs_number_check,
-                                                  intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
+                                                       Register right,
+                                                       bool needs_number_check,
+                                                       intptr_t token_pos) {
   __ TraceSimMsg("EqualityRegRegCompare");
   __ Comment("EqualityRegRegCompare");
   if (needs_number_check) {
@@ -1453,8 +1457,8 @@
     }
 #endif
     __ TraceSimMsg("EqualityRegRegCompare return");
-    // Stub returns result in CMPRES1. If it is 0, then left and right are
-    // equal.
+    // Stub returns result in CMPRES1 (if it is 0, then left and right are
+    // equal) and always sets CMPRES2 to 0.
     __ lw(right, Address(SP, 0 * kWordSize));
     __ lw(left, Address(SP, 1 * kWordSize));
     __ addiu(SP, SP, Immediate(2 * kWordSize));
@@ -1462,6 +1466,7 @@
     __ slt(CMPRES1, left, right);
     __ slt(CMPRES2, right, left);
   }
+  return EQ;
 }
 
 
@@ -1470,11 +1475,12 @@
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
 #if defined(DEBUG)
   locs->CheckWritableInputs();
+  ClobberDeadTempRegisters(locs);
 #endif
 
   __ TraceSimMsg("SaveLiveRegisters");
   // TODO(vegorov): consider saving only caller save (volatile) registers.
-  const intptr_t fpu_regs_count= locs->live_registers()->FpuRegisterCount();
+  const intptr_t fpu_regs_count = locs->live_registers()->FpuRegisterCount();
   if (fpu_regs_count > 0) {
     __ AddImmediate(SP, -(fpu_regs_count * kFpuRegisterSize));
     // Store fpu registers with the lowest register number at the lowest
@@ -1512,6 +1518,9 @@
 
 
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
+#if defined(DEBUG)
+  ClobberDeadTempRegisters(locs);
+#endif
   // General purpose registers have the highest register number at the
   // lowest address.
   __ TraceSimMsg("RestoreLiveRegisters");
@@ -1548,6 +1557,21 @@
 }
 
 
+#if defined(DEBUG)
+void FlowGraphCompiler::ClobberDeadTempRegisters(LocationSummary* locs) {
+  // Clobber temporaries that have not been manually preserved.
+  for (intptr_t i = 0; i < locs->temp_count(); ++i) {
+    Location tmp = locs->temp(i);
+    // TODO(zerny): clobber non-live temporary FPU registers.
+    if (tmp.IsRegister() &&
+        !locs->live_registers()->ContainsRegister(tmp.reg())) {
+      __ LoadImmediate(tmp.reg(), 0xf7);
+    }
+  }
+}
+#endif
+
+
 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
                                         Register class_id_reg,
                                         intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index aff288c..7fc89ce 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1417,17 +1417,18 @@
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegConstCompare(Register reg,
-                                                    const Object& obj,
-                                                    bool needs_number_check,
-                                                    intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegConstCompare(
+    Register reg,
+    const Object& obj,
+    bool needs_number_check,
+    intptr_t token_pos) {
   ASSERT(!needs_number_check ||
          (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
 
   if (obj.IsSmi() && (Smi::Cast(obj).Value() == 0)) {
     ASSERT(!needs_number_check);
     __ testq(reg, reg);
-    return;
+    return EQUAL;
   }
 
   if (needs_number_check) {
@@ -1444,19 +1445,20 @@
                            Isolate::kNoDeoptId,
                            token_pos);
     }
+    // Stub returns result in flags (result of a cmpq, we need ZF computed).
     __ popq(reg);  // Discard constant.
     __ popq(reg);  // Restore 'reg'.
-    return;
+  } else {
+    __ CompareObject(reg, obj, PP);
   }
-
-  __ CompareObject(reg, obj, PP);
+  return EQUAL;
 }
 
 
-void FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                  Register right,
-                                                  bool needs_number_check,
-                                                  intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
+                                                       Register right,
+                                                       bool needs_number_check,
+                                                       intptr_t token_pos) {
   if (needs_number_check) {
     StubCode* stub_code = isolate()->stub_code();
     __ pushq(left);
@@ -1478,12 +1480,13 @@
       __ movq(RBX, Immediate(kInvalidObjectPointer));
     }
 #endif
-    // Stub returns result in flags (result of a cmpl, we need ZF computed).
+    // Stub returns result in flags (result of a cmpq, we need ZF computed).
     __ popq(right);
     __ popq(left);
   } else {
     __ cmpl(left, right);
   }
+  return EQUAL;
 }
 
 
@@ -1492,6 +1495,7 @@
 void FlowGraphCompiler::SaveLiveRegisters(LocationSummary* locs) {
 #if defined(DEBUG)
   locs->CheckWritableInputs();
+  ClobberDeadTempRegisters(locs);
 #endif
 
   // TODO(vegorov): avoid saving non-volatile registers.
@@ -1501,11 +1505,29 @@
 
 
 void FlowGraphCompiler::RestoreLiveRegisters(LocationSummary* locs) {
+#if defined(DEBUG)
+  ClobberDeadTempRegisters(locs);
+#endif
   __ PopRegisters(locs->live_registers()->cpu_registers(),
                   locs->live_registers()->fpu_registers());
 }
 
 
+#if defined(DEBUG)
+void FlowGraphCompiler::ClobberDeadTempRegisters(LocationSummary* locs) {
+  // Clobber temporaries that have not been manually preserved.
+  for (intptr_t i = 0; i < locs->temp_count(); ++i) {
+    Location tmp = locs->temp(i);
+    // TODO(zerny): clobber non-live temporary FPU registers.
+    if (tmp.IsRegister() &&
+        !locs->live_registers()->ContainsRegister(tmp.reg())) {
+      __ movq(tmp.reg(), Immediate(0xf7));
+    }
+  }
+}
+#endif
+
+
 void FlowGraphCompiler::EmitTestAndCall(const ICData& ic_data,
                                         Register class_id_reg,
                                         intptr_t argument_count,
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 207582a..5bbfc9a 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -1653,7 +1653,10 @@
     ReturnInstr* fallback_return =
         new ReturnInstr(call_->instance_call()->token_pos(),
                         new Value(fallback_call));
-    fallback_return->InheritDeoptTargetAfter(isolate(), call_);
+    fallback_return->InheritDeoptTargetAfter(
+        owner_->caller_graph(),
+        call_,
+        fallback_call);
     AppendInstruction(AppendInstruction(cursor, fallback_call),
                       fallback_return);
     exit_collector_->AddExit(fallback_return);
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 6997014..cf75b91 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -887,9 +887,9 @@
   }
   Function& target = Function::Handle();
   const intptr_t len = ic_data.NumberOfChecks();
+  GrowableArray<intptr_t> class_ids;
   for (intptr_t i = 0; i < len; i++) {
     if (ic_data.IsUsedAt(i)) {
-      GrowableArray<intptr_t> class_ids;
       ic_data.GetCheckAt(i, &class_ids, &target);
       ASSERT(class_ids.length() == 2);
       if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) ||
@@ -2150,7 +2150,7 @@
         // Left shift may overflow from smi into mint or big ints.
         // Don't generate smi code if the IC data is marked because
         // of an overflow.
-        if (ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) {
+        if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
           return false;
         }
         operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp)
@@ -2161,7 +2161,7 @@
                      ic_data.AsUnaryClassChecksForArgNr(1)))) {
         // Don't generate mint code if the IC data is marked because of an
         // overflow.
-        if (ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) {
+        if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
           return false;
         }
         // Check for smi/mint << smi or smi/mint >> smi.
@@ -3163,7 +3163,7 @@
     Definition* count = call->ArgumentAt(1);
     Definition* int32_mask = call->ArgumentAt(2);
     if (HasOnlyTwoOf(ic_data, kSmiCid)) {
-      if (ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) {
+      if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
         return false;
       }
       // We cannot overflow. The input value must be a Smi
@@ -3203,7 +3203,7 @@
         HasOnlyOneSmi(ICData::Handle(I,
                                      ic_data.AsUnaryClassChecksForArgNr(1)))) {
       if (!FlowGraphCompiler::SupportsUnboxedMints() ||
-          ic_data.HasDeoptReason(ICData::kDeoptShiftMintOp)) {
+          ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
         return false;
       }
       ShiftMintOpInstr* left_shift =
@@ -4298,7 +4298,7 @@
       TryReplaceWithBinaryOp(instr, op_kind)) {
     return;
   }
-  if (Token::IsPrefixOperator(op_kind) &&
+  if (Token::IsUnaryOperator(op_kind) &&
       TryReplaceWithUnaryOp(instr, op_kind)) {
     return;
   }
@@ -5003,7 +5003,7 @@
   GotoInstr* last = pre_header->last_instruction()->AsGoto();
   // Using kind kEffect will not assign a fresh ssa temporary index.
   flow_graph()->InsertBefore(last, current, last->env(), FlowGraph::kEffect);
-  current->deopt_id_ = last->GetDeoptId();
+  current->CopyDeoptIdFrom(*last);
 }
 
 
@@ -7303,6 +7303,20 @@
 }
 
 
+// Returns true iff this definition is used in a non-phi instruction.
+static bool HasRealUse(Definition* def) {
+  // Environment uses are real (non-phi) uses.
+  if (def->env_use_list() != NULL) return true;
+
+  for (Value::Iterator it(def->input_use_list());
+       !it.Done();
+       it.Advance()) {
+    if (!it.Current()->instruction()->IsPhi()) return true;
+  }
+  return false;
+}
+
+
 void DeadCodeElimination::EliminateDeadPhis(FlowGraph* flow_graph) {
   GrowableArray<PhiInstr*> live_phis;
   for (BlockIterator b = flow_graph->postorder_iterator();
@@ -7314,7 +7328,7 @@
         PhiInstr* phi = it.Current();
         // Phis that have uses and phis inside try blocks are
         // marked as live.
-        if (phi->HasUses() || join->InsideTryBlock()) {
+        if (HasRealUse(phi) || join->InsideTryBlock()) {
           live_phis.Add(phi);
           phi->mark_alive();
         } else {
@@ -9247,7 +9261,7 @@
           // InheritDeoptTarget gave the new branch's comparison the same
           // deopt id that it gave the new branch.  The id should be the
           // deopt id of the original comparison.
-          new_branch->comparison()->SetDeoptId(comparison->GetDeoptId());
+          new_branch->comparison()->SetDeoptId(*comparison);
           // The phi can be used in the branch's environment.  Rename such
           // uses.
           for (Environment::DeepIterator it(new_branch->env());
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 0233d55..f62b524 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -958,7 +958,7 @@
                               last->env(),
                               instr->IsDefinition() ? FlowGraph::kValue
                                                     : FlowGraph::kEffect);
-    instr->deopt_id_ = last->GetDeoptId();
+    instr->CopyDeoptIdFrom(*last);
     instr->env()->set_deopt_id(instr->deopt_id_);
 
     map_.Insert(instr);
@@ -2423,8 +2423,7 @@
     return;
   }
 
-  *result_min = RangeBoundary::MinConstant(RangeBoundary::kRangeBoundaryInt64);
-  *result_max = RangeBoundary::MaxConstant(RangeBoundary::kRangeBoundaryInt64);
+  BitwiseOp(left_range, right_range, result_min, result_max);
 }
 
 
@@ -2435,10 +2434,10 @@
 }
 
 
-void Range::Xor(const Range* left_range,
-                const Range* right_range,
-                RangeBoundary* result_min,
-                RangeBoundary* result_max) {
+void Range::BitwiseOp(const Range* left_range,
+                      const Range* right_range,
+                      RangeBoundary* result_min,
+                      RangeBoundary* result_max) {
   const int bitsize =
       Utils::Maximum(BitSize(left_range), BitSize(right_range));
 
@@ -2627,12 +2626,9 @@
       break;
 
     case Token::kBIT_XOR:
-      Range::Xor(left_range, right_range, &min, &max);
-      break;
-
     case Token::kBIT_OR:
-      *result = Range::Full(RangeBoundary::kRangeBoundaryInt64);
-      return;
+      Range::BitwiseOp(left_range, right_range, &min, &max);
+      break;
 
     default:
       *result = Range(RangeBoundary::NegativeInfinity(),
diff --git a/runtime/vm/flow_graph_range_analysis.h b/runtime/vm/flow_graph_range_analysis.h
index 3b39ba2..948a2ba 100644
--- a/runtime/vm/flow_graph_range_analysis.h
+++ b/runtime/vm/flow_graph_range_analysis.h
@@ -459,10 +459,10 @@
                   RangeBoundary* min,
                   RangeBoundary* max);
 
-  static void Xor(const Range* left_range,
-                  const Range* right_range,
-                  RangeBoundary* min,
-                  RangeBoundary* max);
+  static void BitwiseOp(const Range* left_range,
+                        const Range* right_range,
+                        RangeBoundary* min,
+                        RangeBoundary* max);
 
   // Both the a and b ranges are >= 0.
   static bool OnlyPositiveOrZero(const Range& a, const Range& b);
diff --git a/runtime/vm/flow_graph_range_analysis_test.cc b/runtime/vm/flow_graph_range_analysis_test.cc
index 4b38b44..308b1ce 100644
--- a/runtime/vm/flow_graph_range_analysis_test.cc
+++ b/runtime/vm/flow_graph_range_analysis_test.cc
@@ -526,14 +526,13 @@
                  RangeBoundary(0),
                  RangeBoundary(static_cast<int64_t>(0xffffffff)));
 
-  // Test that [-20, 20] & [-20, 20] = [Unknown, Unknown].
+  // Test that [-20, 20] & [-20, 20] = [-32, 31].
   TEST_RANGE_AND(static_cast<int64_t>(-20),
                  static_cast<int64_t>(20),
                  static_cast<int64_t>(-20),
                  static_cast<int64_t>(20),
-                 RangeBoundary::MinConstant(RangeBoundary::kRangeBoundaryInt64),
-                 RangeBoundary::MaxConstant(
-                    RangeBoundary::kRangeBoundaryInt64));
+                 RangeBoundary(-32),
+                 RangeBoundary(31));
 
 #undef TEST_RANGE_AND
 }
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index abb728b..b692d0d 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -158,7 +158,7 @@
       ASSERT(raw_key->IsWatched());
     } else {
       ASSERT(!raw_key->IsWatched());
-      raw_key->SetWatchedBit();
+      raw_key->SetWatchedBitUnsynchronized();
     }
     delay_set_.insert(std::make_pair(raw_key, raw_weak));
   }
@@ -187,9 +187,11 @@
 
     // Mark the object and push it on the marking stack.
     ASSERT(!raw_obj->IsMarked());
-    raw_obj->SetMarkBit();
-    raw_obj->ClearRememberedBit();
-    if (raw_obj->IsWatched()) {
+    const bool is_watched = raw_obj->IsWatched();
+    raw_obj->SetMarkBitUnsynchronized();
+    raw_obj->ClearRememberedBitUnsynchronized();
+    raw_obj->ClearWatchedBitUnsynchronized();
+    if (is_watched) {
       std::pair<DelaySet::iterator, DelaySet::iterator> ret;
       // Visit all elements with a key equal to raw_obj.
       ret = delay_set_.equal_range(raw_obj);
@@ -201,7 +203,6 @@
            it != temp_copy.end(); ++it) {
         it->second->VisitPointers(this);
       }
-      raw_obj->ClearWatchedBit();
     }
     marking_stack_->Push(raw_obj);
   }
@@ -223,7 +224,7 @@
       if ((visiting_old_object_ != NULL) &&
           !visiting_old_object_->IsRemembered()) {
         ASSERT(p != NULL);
-        visiting_old_object_->SetRememberedBit();
+        visiting_old_object_->SetRememberedBitUnsynchronized();
         isolate()->store_buffer()->AddObjectGC(visiting_old_object_);
       }
       return;
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index b9cd6d4..c81ac93 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -80,7 +80,7 @@
   if (FLAG_print_environments && (instr->env() != NULL)) {
     instr->env()->PrintTo(&f);
   }
-  if (print_locations && (instr->locs_ != NULL)) {
+  if (print_locations && (instr->HasLocs())) {
     instr->locs()->PrintTo(&f);
   }
   if (instr->lifetime_position() != -1) {
@@ -137,7 +137,18 @@
 
 
 static void PrintICDataHelper(BufferFormatter* f, const ICData& ic_data) {
-  f->Print(" IC[%" Pd ": ", ic_data.NumberOfChecks());
+  f->Print(" IC[");
+  if (ic_data.HasRangeFeedback()) {
+    f->Print("{%s",
+        ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(0)));
+    if (ic_data.NumArgsTested() == 2) {
+      f->Print(" x %s",
+          ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(1)));
+    }
+    f->Print("->%s} ",
+        ICData::RangeFeedbackToString(ic_data.DecodeRangeFeedbackAt(2)));
+  }
+  f->Print("%" Pd ": ", ic_data.NumberOfChecks());
   Function& target = Function::Handle();
   for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) {
     GrowableArray<intptr_t> class_ids;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 8476a7c..dacba99 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -31,6 +31,9 @@
     "Propagate IC data from unoptimized to optimized IC calls.");
 DEFINE_FLAG(bool, two_args_smi_icd, true,
     "Generate special IC stubs for two args Smi operations");
+DEFINE_FLAG(bool, ic_range_profiling, true,
+    "Generate special IC stubs collecting range information "
+    "for binary and unary arithmetic operations");
 DEFINE_FLAG(bool, unbox_numeric_fields, true,
     "Support unboxed double and float32x4 fields.");
 DECLARE_FLAG(bool, enable_type_checks);
@@ -739,18 +742,24 @@
 }
 
 
-void Instruction::InheritDeoptTargetAfter(Isolate* isolate,
-                                          Instruction* other) {
-  ASSERT(other->env() != NULL);
-  deopt_id_ = Isolate::ToDeoptAfter(other->deopt_id_);
-  other->env()->DeepCopyTo(isolate, this);
+void Instruction::InheritDeoptTargetAfter(FlowGraph* flow_graph,
+                                          Definition* call,
+                                          Definition* result) {
+  ASSERT(call->env() != NULL);
+  deopt_id_ = Isolate::ToDeoptAfter(call->deopt_id_);
+  call->env()->DeepCopyAfterTo(flow_graph->isolate(),
+                               this,
+                               call->ArgumentCount(),
+                               flow_graph->constant_dead(),
+                               result != NULL ? result
+                                              : flow_graph->constant_dead());
   env()->set_deopt_id(deopt_id_);
 }
 
 
 void Instruction::InheritDeoptTarget(Isolate* isolate, Instruction* other) {
   ASSERT(other->env() != NULL);
-  deopt_id_ = other->deopt_id_;
+  CopyDeoptIdFrom(*other);
   other->env()->DeepCopyTo(isolate, this);
   env()->set_deopt_id(deopt_id_);
 }
@@ -759,7 +768,7 @@
 void BranchInstr::InheritDeoptTarget(Isolate* isolate, Instruction* other) {
   ASSERT(env() == NULL);
   Instruction::InheritDeoptTarget(isolate, other);
-  comparison()->SetDeoptId(GetDeoptId());
+  comparison()->SetDeoptId(*this);
 }
 
 
@@ -813,7 +822,7 @@
   // Take other's environment from this definition.
   ASSERT(other->env() == NULL);
   other->SetEnvironment(env());
-  env_ = NULL;
+  ClearEnv();
   // Replace all uses of this definition with other.
   ReplaceUsesWith(other);
   // Reuse this instruction's SSA name for other.
@@ -947,7 +956,7 @@
       ASSERT(instr->previous() == this);
 
       GotoInstr* goto_join = new GotoInstr(AsJoinEntry());
-      goto_join->deopt_id_ = parent->deopt_id_;
+      goto_join->CopyDeoptIdFrom(*parent);
       graph_entry->normal_entry()->LinkTo(goto_join);
       return true;
     }
@@ -1202,6 +1211,8 @@
     return !is_truncating() &&
         !RangeUtils::Fits(value()->definition()->range(),
                           RangeBoundary::kRangeBoundaryInt32);
+  } else if (is_truncating() && value()->definition()->IsBoxInteger()) {
+    return false;
   } else if ((kSmiBits < 32) && value()->Type()->IsInt()) {
     // Note: we don't support truncation of Bigint values.
     return !RangeUtils::Fits(value()->definition()->range(),
@@ -2057,7 +2068,13 @@
           box_defn->value()->CopyWithType(),
           (representation() == kUnboxedInt32) ?
               GetDeoptId() : Isolate::kNoDeoptId);
-      if ((representation() == kUnboxedInt32) && !CanDeoptimize()) {
+      // TODO(vegorov): marking resulting converter as truncating when
+      // unboxing can't deoptimize is a workaround for the missing
+      // deoptimization environment when we insert converter after
+      // EliminateEnvironments and there is a mismatch between predicates
+      // UnboxIntConverterInstr::CanDeoptimize and UnboxInt32::CanDeoptimize.
+      if ((representation() == kUnboxedInt32) &&
+          (is_truncating() || !CanDeoptimize())) {
         converter->mark_truncating();
       }
       flow_graph->InsertBefore(this, converter, env(), FlowGraph::kValue);
@@ -2687,42 +2704,16 @@
 
 // This function should be kept in sync with
 // FlowGraphCompiler::SlowPathEnvironmentFor().
-void MaterializeObjectInstr::RemapRegisters(intptr_t* fpu_reg_slots,
-                                            intptr_t* cpu_reg_slots) {
+void MaterializeObjectInstr::RemapRegisters(intptr_t* cpu_reg_slots,
+                                            intptr_t* fpu_reg_slots) {
   if (registers_remapped_) {
     return;
   }
   registers_remapped_ = true;
 
   for (intptr_t i = 0; i < InputCount(); i++) {
-    Location loc = LocationAt(i);
-    if (loc.IsRegister()) {
-      intptr_t index = cpu_reg_slots[loc.reg()];
-      ASSERT(index >= 0);
-      locations_[i] = Location::StackSlot(index);
-    } else if (loc.IsFpuRegister()) {
-      intptr_t index = fpu_reg_slots[loc.fpu_reg()];
-      ASSERT(index >= 0);
-      Value* value = InputAt(i);
-      switch (value->definition()->representation()) {
-        case kUnboxedDouble:
-          locations_[i] = Location::DoubleStackSlot(index);
-          break;
-        case kUnboxedFloat32x4:
-        case kUnboxedInt32x4:
-        case kUnboxedFloat64x2:
-          locations_[i] = Location::QuadStackSlot(index);
-          break;
-        default:
-          UNREACHABLE();
-      }
-    } else if (loc.IsPairLocation()) {
-      UNREACHABLE();
-    } else if (loc.IsInvalid() &&
-               InputAt(i)->definition()->IsMaterializeObject()) {
-      InputAt(i)->definition()->AsMaterializeObject()->RemapRegisters(
-          fpu_reg_slots, cpu_reg_slots);
-    }
+    locations_[i] = LocationAt(i).RemapForSlowPath(
+        InputAt(i)->definition(), cpu_reg_slots, fpu_reg_slots);
   }
 }
 
@@ -2880,6 +2871,19 @@
       ExternalLabel target_label(label_address);
       compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(),
                                  deopt_id(), token_pos(), locs());
+    } else if (FLAG_ic_range_profiling &&
+               (Token::IsBinaryArithmeticOperator(token_kind()) ||
+                Token::IsUnaryArithmeticOperator(token_kind()))) {
+      ASSERT(Token::IsUnaryArithmeticOperator(token_kind()) ==
+                 (ArgumentCount() == 1));
+      ASSERT(Token::IsBinaryArithmeticOperator(token_kind()) ==
+                 (ArgumentCount() == 2));
+      StubCode* stub_code = isolate->stub_code();
+      ExternalLabel target_label((ArgumentCount() == 1) ?
+          stub_code->UnaryRangeCollectingInlineCacheEntryPoint() :
+          stub_code->BinaryRangeCollectingInlineCacheEntryPoint());
+      compiler->EmitInstanceCall(&target_label, *call_ic_data, ArgumentCount(),
+                                 deopt_id(), token_pos(), locs());
     } else {
       compiler->GenerateInstanceCall(deopt_id(),
                                      token_pos(),
@@ -3027,6 +3031,29 @@
 }
 
 
+void Environment::DeepCopyAfterTo(Isolate* isolate,
+                                  Instruction* instr,
+                                  intptr_t argc,
+                                  Definition* dead,
+                                  Definition* result) const {
+  for (Environment::DeepIterator it(instr->env()); !it.Done(); it.Advance()) {
+    it.CurrentValue()->RemoveFromUseList();
+  }
+
+  Environment* copy = DeepCopy(isolate, values_.length() - argc);
+  for (intptr_t i = 0; i < argc; i++) {
+    copy->values_.Add(new(isolate) Value(dead));
+  }
+  copy->values_.Add(new(isolate) Value(result));
+
+  instr->SetEnvironment(copy);
+  for (Environment::DeepIterator it(copy); !it.Done(); it.Advance()) {
+    Value* value = it.CurrentValue();
+    value->definition()->AddEnvUse(value);
+  }
+}
+
+
 // Copies the environment as outer on an inlined instruction and updates the
 // environment use lists.
 void Environment::DeepCopyToOuter(Isolate* isolate, Instruction* instr) const {
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 5d5b537..c47680e 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -619,7 +619,7 @@
 
   intptr_t deopt_id() const {
     ASSERT(CanDeoptimize() || CanBecomeDeoptimizationTarget());
-    return deopt_id_;
+    return GetDeoptId();
   }
 
   const ICData* GetICData(
@@ -717,11 +717,13 @@
 
   // Returns structure describing location constraints required
   // to emit native code for this instruction.
-  virtual LocationSummary* locs() {
+  LocationSummary* locs() {
     ASSERT(locs_ != NULL);
     return locs_;
   }
 
+  bool HasLocs() const { return locs_ != NULL; }
+
   virtual LocationSummary* MakeLocationSummary(Isolate* isolate,
                                                bool is_optimizing) const = 0;
 
@@ -840,30 +842,34 @@
     return false;
   }
 
-  void InheritDeoptTargetAfter(Isolate* isolate, Instruction* other);
+  void InheritDeoptTargetAfter(FlowGraph* flow_graph,
+                               Definition* call,
+                               Definition* result);
 
   virtual bool MayThrow() const = 0;
 
   bool IsDominatedBy(Instruction* dom);
 
+  void ClearEnv() { env_ = NULL; }
+
  protected:
+  // GetDeoptId and/or CopyDeoptIdFrom.
+  friend class CallSiteInliner;
+  friend class LICM;
+  friend class ComparisonInstr;
+  friend class Scheduler;
+  friend class BlockEntryInstr;
+
   // Fetch deopt id without checking if this computation can deoptimize.
   intptr_t GetDeoptId() const {
     return deopt_id_;
   }
 
+  void CopyDeoptIdFrom(const Instruction& instr) {
+    deopt_id_ = instr.deopt_id_;
+  }
+
  private:
-  friend class FlowGraphPrinter;
-  friend class Definition;  // Needed for InsertBefore, InsertAfter.
-  friend class CallSiteInliner;
-
-  // deopt_id_ write access.
-  friend class ComparisonInstr;
-  friend class LICM;
-  friend class Scheduler;
-  friend class BlockEntryInstr;
-  friend class BranchSimplifier;
-
   virtual void RawSetInputAt(intptr_t i, Value* value) = 0;
 
   enum {
@@ -2238,8 +2244,8 @@
   virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
                                        BranchLabels labels) = 0;
 
-  void SetDeoptId(intptr_t deopt_id) {
-    deopt_id_ = deopt_id;
+  void SetDeoptId(const Instruction& instr) {
+    CopyDeoptIdFrom(instr);
   }
 
   // Operation class id is computed from collected ICData.
@@ -2707,7 +2713,7 @@
     ASSERT(Token::IsBinaryOperator(token_kind) ||
            Token::IsEqualityOperator(token_kind) ||
            Token::IsRelationalOperator(token_kind) ||
-           Token::IsPrefixOperator(token_kind) ||
+           Token::IsUnaryOperator(token_kind) ||
            Token::IsIndexOperator(token_kind) ||
            Token::IsTypeTestOperator(token_kind) ||
            Token::IsTypeCastOperator(token_kind) ||
@@ -3708,6 +3714,15 @@
   DECLARE_INSTRUCTION(LoadCodeUnits)
   virtual CompileType ComputeType() const;
 
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const {
+    if (idx == 0) {
+      // The string may be tagged or untagged (for external strings).
+      return kNoRepresentation;
+    }
+    ASSERT(idx == 1);
+    return kTagged;
+  }
+
   bool IsExternal() const {
     return array()->definition()->representation() == kUntagged;
   }
@@ -4131,8 +4146,8 @@
 
   virtual bool MayThrow() const { return false; }
 
-  void RemapRegisters(intptr_t* fpu_reg_slots,
-                      intptr_t* cpu_reg_slots);
+  void RemapRegisters(intptr_t* cpu_reg_slots,
+                      intptr_t* fpu_reg_slots);
 
   bool was_visited_for_liveness() const { return visited_for_liveness_; }
   void mark_visited_for_liveness() {
@@ -7910,6 +7925,12 @@
   void DeepCopyTo(Isolate* isolate, Instruction* instr) const;
   void DeepCopyToOuter(Isolate* isolate, Instruction* instr) const;
 
+  void DeepCopyAfterTo(Isolate* isolate,
+                       Instruction* instr,
+                       intptr_t argc,
+                       Definition* dead,
+                       Definition* result) const;
+
   void PrintTo(BufferFormatter* f) const;
   const char* ToCString() const;
 
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index e8649f4..cc62653 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -1962,6 +1962,9 @@
       // If the value cannot fit in a smi then allocate a mint box for it.
       Register value = locs()->temp(0).reg();
       Register temp = locs()->temp(1).reg();
+      // Value register needs to be manually preserved on allocation slow-path.
+      locs()->live_registers()->Add(locs()->temp(0), kUnboxedInt32);
+
       ASSERT(result != value);
       __ MoveRegister(value, result);
       __ SmiTag(result);
@@ -6303,7 +6306,7 @@
 
   Label* deopt = NULL;
   if (CanDeoptimize()) {
-    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
   }
   if (locs()->in(1).IsConstant()) {
     // Code for a constant shift amount.
@@ -6534,7 +6537,7 @@
 
   ASSERT(left != out);
 
-  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
 
   if (locs()->in(1).IsConstant()) {
     // Shifter is constant.
@@ -6828,23 +6831,27 @@
   Location left = locs()->in(0);
   Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
+  Condition true_condition;
   if (left.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(right.reg(),
-                                          left.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(right.reg(),
+                                                           left.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else if (right.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(left.reg(),
-                                          right.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(left.reg(),
+                                                           right.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else {
-    compiler->EmitEqualityRegRegCompare(left.reg(),
-                                       right.reg(),
-                                       needs_number_check(),
-                                       token_pos());
+    true_condition = compiler->EmitEqualityRegRegCompare(left.reg(),
+                                                         right.reg(),
+                                                         needs_number_check(),
+                                                         token_pos());
   }
-  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
+  if (kind() != Token::kEQ_STRICT) {
+    ASSERT(kind() == Token::kNE_STRICT);
+    true_condition = NegateCondition(true_condition);
+  }
   return true_condition;
 }
 
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 99c35bc..2080ef2 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -5501,23 +5501,27 @@
   Location left = locs()->in(0);
   Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
+  Condition true_condition;
   if (left.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(right.reg(),
-                                          left.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(right.reg(),
+                                                           left.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else if (right.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(left.reg(),
-                                          right.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(left.reg(),
+                                                           right.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else {
-    compiler->EmitEqualityRegRegCompare(left.reg(),
-                                       right.reg(),
-                                       needs_number_check(),
-                                       token_pos());
+    true_condition = compiler->EmitEqualityRegRegCompare(left.reg(),
+                                                         right.reg(),
+                                                         needs_number_check(),
+                                                         token_pos());
   }
-  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
+  if (kind() != Token::kEQ_STRICT) {
+    ASSERT(kind() == Token::kNE_STRICT);
+    true_condition = NegateCondition(true_condition);
+  }
   return true_condition;
 }
 
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 3b4fe76..dd6ae5c 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -1184,26 +1184,6 @@
       __ movzxw(result, element_address);
       __ SmiTag(result);
       break;
-    case kTypedDataInt32ArrayCid: {
-        Label* deopt = compiler->AddDeoptStub(deopt_id(),
-                                              ICData::kDeoptInt32Load);
-        __ movl(result, element_address);
-        // Verify that the signed value in 'result' can fit inside a Smi.
-        __ cmpl(result, Immediate(0xC0000000));
-        __ j(NEGATIVE, deopt);
-        __ SmiTag(result);
-      }
-      break;
-    case kTypedDataUint32ArrayCid: {
-        Label* deopt = compiler->AddDeoptStub(deopt_id(),
-                                              ICData::kDeoptUint32Load);
-        __ movl(result, element_address);
-        // Verify that the unsigned value in 'result' can fit inside a Smi.
-        __ testl(result, Immediate(0xC0000000));
-        __ j(NOT_ZERO, deopt);
-        __ SmiTag(result);
-      }
-      break;
     default:
       ASSERT((class_id() == kArrayCid) || (class_id() == kImmutableArrayCid));
       __ movl(result, element_address);
@@ -3809,6 +3789,9 @@
     } else {
       // If the value cannot fit in a smi then allocate a mint box for it.
       Register temp = locs()->temp(0).reg();
+      // Temp register needs to be manually preserved on allocation slow-path.
+      locs()->live_registers()->Add(locs()->temp(0), kUnboxedInt32);
+
       ASSERT(temp != result);
       __ MoveRegister(temp, result);
       __ SmiTag(result);
@@ -6061,7 +6044,7 @@
 
   Label* deopt = NULL;
   if (CanDeoptimize()) {
-    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
   }
   if (locs()->in(1).IsConstant()) {
     // Code for a constant shift amount.
@@ -6300,7 +6283,7 @@
   ASSERT(left == out);
 
 
-  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
 
   if (locs()->in(1).IsConstant()) {
     // Shifter is constant.
@@ -6605,23 +6588,27 @@
   Location left = locs()->in(0);
   Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
+  Condition true_condition;
   if (left.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(right.reg(),
-                                          left.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(right.reg(),
+                                                           left.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else if (right.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(left.reg(),
-                                          right.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(left.reg(),
+                                                           right.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else {
-    compiler->EmitEqualityRegRegCompare(left.reg(),
-                                        right.reg(),
-                                        needs_number_check(),
-                                        token_pos());
+    true_condition = compiler->EmitEqualityRegRegCompare(left.reg(),
+                                                         right.reg(),
+                                                         needs_number_check(),
+                                                         token_pos());
   }
-  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+  if (kind() != Token::kEQ_STRICT) {
+    ASSERT(kind() == Token::kNE_STRICT);
+    true_condition = NegateCondition(true_condition);
+  }
   return true_condition;
 }
 
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 4f51f63..4a80255 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -4930,7 +4930,7 @@
 
   Label* deopt = NULL;
   if (CanDeoptimize()) {
-    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
   }
   if (locs()->in(1).IsConstant()) {
     // Code for a constant shift amount.
@@ -5180,7 +5180,7 @@
 
   ASSERT(left != out);
 
-  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
 
   if (locs()->in(1).IsConstant()) {
     // Shifter is constant.
@@ -5462,23 +5462,27 @@
   Location left = locs()->in(0);
   Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
+  Condition true_condition;
   if (left.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(right.reg(),
-                                          left.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(right.reg(),
+                                                           left.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else if (right.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(left.reg(),
-                                          right.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(left.reg(),
+                                                           right.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else {
-    compiler->EmitEqualityRegRegCompare(left.reg(),
-                                       right.reg(),
-                                       needs_number_check(),
-                                       token_pos());
+    true_condition = compiler->EmitEqualityRegRegCompare(left.reg(),
+                                                         right.reg(),
+                                                         needs_number_check(),
+                                                         token_pos());
   }
-  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQ : NE;
+  if (kind() != Token::kEQ_STRICT) {
+    ASSERT(kind() == Token::kNE_STRICT);
+    true_condition = NegateCondition(true_condition);
+  }
   return true_condition;
 }
 
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 9045aca..a12001c 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -5777,7 +5777,7 @@
 
   Label* deopt = NULL;
   if (CanDeoptimize()) {
-    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+    deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
   }
   if (locs()->in(1).IsConstant()) {
     // Code for a constant shift amount.
@@ -5946,7 +5946,7 @@
   ASSERT(left == out);
 
 
-  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptShiftMintOp);
+  Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptBinaryMintOp);
 
   if (locs()->in(1).IsConstant()) {
     // Shifter is constant.
@@ -6245,24 +6245,27 @@
   Location left = locs()->in(0);
   Location right = locs()->in(1);
   ASSERT(!left.IsConstant() || !right.IsConstant());
+  Condition true_condition;
   if (left.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(right.reg(),
-                                          left.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(right.reg(),
+                                                           left.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else if (right.IsConstant()) {
-    compiler->EmitEqualityRegConstCompare(left.reg(),
-                                          right.constant(),
-                                          needs_number_check(),
-                                          token_pos());
+    true_condition = compiler->EmitEqualityRegConstCompare(left.reg(),
+                                                           right.constant(),
+                                                           needs_number_check(),
+                                                           token_pos());
   } else {
-    compiler->EmitEqualityRegRegCompare(left.reg(),
-                                        right.reg(),
-                                        needs_number_check(),
-                                        token_pos());
+    true_condition = compiler->EmitEqualityRegRegCompare(left.reg(),
+                                                         right.reg(),
+                                                         needs_number_check(),
+                                                         token_pos());
   }
-
-  Condition true_condition = (kind() == Token::kEQ_STRICT) ? EQUAL : NOT_EQUAL;
+  if (kind() != Token::kEQ_STRICT) {
+    ASSERT(kind() == Token::kNE_STRICT);
+    true_condition = NegateCondition(true_condition);
+  }
   return true_condition;
 }
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 7aa282d..5335516 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -106,13 +106,17 @@
     kPauseMsg = 1,
     kResumeMsg = 2,
     kPingMsg = 3,
+    kKillMsg = 4,
 
     kImmediateAction = 0,
     kBeforeNextEventAction = 1,
     kAsEventAction = 2
   };
 
-  void HandleLibMessage(const Array& message);
+  // A result of false indicates that the isolate should terminate the
+  // processing of further events.
+  bool HandleLibMessage(const Array& message);
+
   bool ProcessUnhandledException(const Object& message, const Error& result);
   RawFunction* ResolveCallbackFunction();
   Isolate* isolate_;
@@ -135,20 +139,19 @@
 // Isolate library OOB messages are fixed sized arrays which have the
 // following format:
 // [ OOB dispatch, Isolate library dispatch, <message specific data> ]
-void IsolateMessageHandler::HandleLibMessage(const Array& message) {
-  if (message.Length() < 2) return;
+bool IsolateMessageHandler::HandleLibMessage(const Array& message) {
+  if (message.Length() < 2) return true;
   const Object& type = Object::Handle(I, message.At(1));
-  if (!type.IsSmi()) return;
+  if (!type.IsSmi()) return true;
   const Smi& msg_type = Smi::Cast(type);
   switch (msg_type.Value()) {
     case kPauseMsg: {
       // [ OOB, kPauseMsg, pause capability, resume capability ]
-      if (message.Length() != 4) return;
+      if (message.Length() != 4) return true;
       Object& obj = Object::Handle(I, message.At(2));
-      if (!obj.IsCapability()) return;
-      if (!I->VerifyPauseCapability(Capability::Cast(obj))) return;
+      if (!I->VerifyPauseCapability(obj)) return true;
       obj = message.At(3);
-      if (!obj.IsCapability()) return;
+      if (!obj.IsCapability()) return true;
       if (I->AddResumeCapability(Capability::Cast(obj))) {
         increment_paused();
       }
@@ -156,34 +159,35 @@
     }
     case kResumeMsg: {
       // [ OOB, kResumeMsg, pause capability, resume capability ]
-      if (message.Length() != 4) return;
+      if (message.Length() != 4) return true;
       Object& obj = Object::Handle(I, message.At(2));
-      if (!obj.IsCapability()) return;
-      if (!I->VerifyPauseCapability(Capability::Cast(obj))) return;
+      if (!I->VerifyPauseCapability(obj)) return true;
       obj = message.At(3);
-      if (!obj.IsCapability()) return;
+      if (!obj.IsCapability()) return true;
       if (I->RemoveResumeCapability(Capability::Cast(obj))) {
         decrement_paused();
       }
       break;
     }
     case kPingMsg: {
-      // [ OOB, kPingMsg, responsePort, pingType ]
-      if (message.Length() != 4) return;
+      // [ OOB, kPingMsg, responsePort, priority ]
+      if (message.Length() != 4) return true;
       const Object& obj2 = Object::Handle(I, message.At(2));
-      if (!obj2.IsSendPort()) return;
+      if (!obj2.IsSendPort()) return true;
       const SendPort& send_port = SendPort::Cast(obj2);
       const Object& obj3 = Object::Handle(I, message.At(3));
-      if (!obj3.IsSmi()) return;
-      const intptr_t ping_type = Smi::Cast(obj3).Value();
-      if (ping_type == kImmediateAction) {
+      if (!obj3.IsSmi()) return true;
+      const intptr_t priority = Smi::Cast(obj3).Value();
+      if (priority == kImmediateAction) {
         uint8_t* data = NULL;
         intptr_t len = 0;
         SerializeObject(Object::null_instance(), &data, &len);
         PortMap::PostMessage(new Message(send_port.Id(),
                                          data, len,
                                          Message::kNormalPriority));
-      } else if (ping_type == kBeforeNextEventAction) {
+      } else {
+        ASSERT((priority == kBeforeNextEventAction) ||
+               (priority == kAsEventAction));
         // Update the message so that it will be handled immediately when it
         // is picked up from the message queue the next time.
         message.SetAt(
@@ -195,8 +199,23 @@
         this->PostMessage(new Message(Message::kIllegalPort,
                                       data, len,
                                       Message::kNormalPriority),
-                          true /* at_head */);
-      } else if (ping_type == kAsEventAction) {
+                          priority == kBeforeNextEventAction /* at_head */);
+      }
+      break;
+    }
+    case kKillMsg: {
+      // [ OOB, kKillMsg, terminate capability, priority ]
+      if (message.Length() != 4) return true;
+      Object& obj = Object::Handle(I, message.At(3));
+      if (!obj.IsSmi()) return true;
+      const intptr_t priority = Smi::Cast(obj).Value();
+      if (priority == kImmediateAction) {
+        obj = message.At(2);
+        // Signal that the isolate should stop execution.
+        return !I->VerifyTerminateCapability(obj);
+      } else {
+        ASSERT((priority == kBeforeNextEventAction) ||
+               (priority == kAsEventAction));
         // Update the message so that it will be handled immediately when it
         // is picked up from the message queue the next time.
         message.SetAt(
@@ -207,7 +226,8 @@
         SerializeObject(message, &data, &len);
         this->PostMessage(new Message(Message::kIllegalPort,
                                       data, len,
-                                      Message::kNormalPriority));
+                                      Message::kNormalPriority),
+                          priority == kBeforeNextEventAction /* at_head */);
       }
       break;
     }
@@ -218,6 +238,7 @@
       break;
 #endif  // defined(DEBUG)
   }
+  return true;
 }
 
 
@@ -303,7 +324,7 @@
               break;
             }
             case Message::kIsolateLibOOBMsg: {
-              HandleLibMessage(oob_msg);
+              success = HandleLibMessage(oob_msg);
               break;
             }
 #if defined(DEBUG)
@@ -327,7 +348,7 @@
         const Object& oob_tag = Object::Handle(I, msg_arr.At(0));
         if (oob_tag.IsSmi() &&
             (Smi::Cast(oob_tag).Value() == Message::kDelayedIsolateLibOOBMsg)) {
-          HandleLibMessage(Array::Cast(msg_arr));
+          success = HandleLibMessage(Array::Cast(msg_arr));
         }
       }
     }
@@ -821,8 +842,17 @@
 }
 
 
-bool Isolate::VerifyPauseCapability(const Capability& capability) const {
-  return !capability.IsNull() && (pause_capability() == capability.Id());
+bool Isolate::VerifyPauseCapability(const Object& capability) const {
+  return !capability.IsNull() &&
+      capability.IsCapability() &&
+      (pause_capability() == Capability::Cast(capability).Id());
+}
+
+
+bool Isolate::VerifyTerminateCapability(const Object& capability) const {
+  return !capability.IsNull() &&
+      capability.IsCapability() &&
+      (terminate_capability() == Capability::Cast(capability).Id());
 }
 
 
@@ -974,7 +1004,7 @@
     HandleScope handle_scope(isolate);
     Error& error = Error::Handle();
     error = isolate->object_store()->sticky_error();
-    if (!error.IsNull()) {
+    if (!error.IsNull() && !error.IsUnwindError()) {
       OS::PrintErr("in ShutdownIsolate: %s\n", error.ToErrorCString());
     }
     Dart::RunShutdownCallback();
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index e0bbf42..d8c0227 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -362,8 +362,11 @@
     return resume_request;
   }
 
-  // Verify that the sender has the capability to pause this isolate.
-  bool VerifyPauseCapability(const Capability& capability) const;
+  // Verify that the sender has the capability to pause or terminate the
+  // isolate.
+  bool VerifyPauseCapability(const Object& capability) const;
+  bool VerifyTerminateCapability(const Object& capability) const;
+
   // Returns true if the capability was added or removed from this isolate's
   // list of pause events.
   bool AddResumeCapability(const Capability& capability);
diff --git a/runtime/vm/locations.cc b/runtime/vm/locations.cc
index 0951aa9..2419594 100644
--- a/runtime/vm/locations.cc
+++ b/runtime/vm/locations.cc
@@ -244,6 +244,59 @@
 }
 
 
+Location Location::RemapForSlowPath(Definition* def,
+                                    intptr_t* cpu_reg_slots,
+                                    intptr_t* fpu_reg_slots) const {
+  if (IsRegister()) {
+    intptr_t index = cpu_reg_slots[reg()];
+    ASSERT(index >= 0);
+    return Location::StackSlot(index);
+  } else if (IsFpuRegister()) {
+    intptr_t index = fpu_reg_slots[fpu_reg()];
+    ASSERT(index >= 0);
+    switch (def->representation()) {
+      case kUnboxedDouble:
+        return Location::DoubleStackSlot(index);
+
+      case kUnboxedFloat32x4:
+      case kUnboxedInt32x4:
+      case kUnboxedFloat64x2:
+        return Location::QuadStackSlot(index);
+
+      default:
+        UNREACHABLE();
+    }
+  } else if (IsPairLocation()) {
+    ASSERT(def->representation() == kUnboxedMint);
+    PairLocation* value_pair = AsPairLocation();
+    intptr_t index_lo;
+    intptr_t index_hi;
+
+    if (value_pair->At(0).IsRegister()) {
+      index_lo = cpu_reg_slots[value_pair->At(0).reg()];
+    } else {
+      ASSERT(value_pair->At(0).IsStackSlot());
+      index_lo = value_pair->At(0).stack_index();
+    }
+
+    if (value_pair->At(1).IsRegister()) {
+      index_hi = cpu_reg_slots[value_pair->At(1).reg()];
+    } else {
+      ASSERT(value_pair->At(1).IsStackSlot());
+      index_hi = value_pair->At(1).stack_index();
+    }
+
+    return Location::Pair(Location::StackSlot(index_lo),
+                          Location::StackSlot(index_hi));
+  } else if (IsInvalid() && def->IsMaterializeObject()) {
+    def->AsMaterializeObject()->RemapRegisters(cpu_reg_slots, fpu_reg_slots);
+    return *this;
+  }
+
+  return *this;
+}
+
+
 void LocationSummary::PrintTo(BufferFormatter* f) const {
   if (input_count() > 0) {
     f->Print(" (");
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
index e4bf340..0b9bf50 100644
--- a/runtime/vm/locations.h
+++ b/runtime/vm/locations.h
@@ -11,10 +11,12 @@
 
 namespace dart {
 
+
 class BufferFormatter;
-class Value;
-class PairLocation;
 class ConstantInstr;
+class Definition;
+class PairLocation;
+class Value;
 
 
 enum Representation {
@@ -370,6 +372,10 @@
 
   Location Copy() const;
 
+  Location RemapForSlowPath(Definition* def,
+                            intptr_t* cpu_reg_slots,
+                            intptr_t* fpu_reg_slots) const;
+
  private:
   explicit Location(uword value) : value_(value) { }
 
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index bbcb076..78e10287 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -855,7 +855,7 @@
   void VisitObject(RawObject* obj) {
     // RawInstruction objects are premarked on allocation.
     if (!obj->IsMarked()) {
-      obj->SetMarkBit();
+      obj->SetMarkBitUnsynchronized();
     }
   }
 };
@@ -11434,12 +11434,15 @@
 
 
 bool ICData::HasDeoptReason(DeoptReasonId reason) const {
+  ASSERT(reason <= kLastRecordedDeoptReason);
   return (DeoptReasons() & (1 << reason)) != 0;
 }
 
 
 void ICData::AddDeoptReason(DeoptReasonId reason) const {
-  SetDeoptReasons(DeoptReasons() | (1 << reason));
+  if (reason <= kLastRecordedDeoptReason) {
+    SetDeoptReasons(DeoptReasons() | (1 << reason));
+  }
 }
 
 
@@ -11943,6 +11946,96 @@
 }
 
 
+static Token::Kind RecognizeArithmeticOp(const String& name) {
+  ASSERT(name.IsSymbol());
+  if (name.raw() == Symbols::Plus().raw()) {
+    return Token::kADD;
+  } else if (name.raw() == Symbols::Minus().raw()) {
+    return Token::kSUB;
+  } else if (name.raw() == Symbols::Star().raw()) {
+    return Token::kMUL;
+  } else if (name.raw() == Symbols::Slash().raw()) {
+    return Token::kDIV;
+  } else if (name.raw() == Symbols::TruncDivOperator().raw()) {
+    return Token::kTRUNCDIV;
+  } else if (name.raw() == Symbols::Percent().raw()) {
+    return Token::kMOD;
+  } else if (name.raw() == Symbols::BitOr().raw()) {
+    return Token::kBIT_OR;
+  } else if (name.raw() == Symbols::Ampersand().raw()) {
+    return Token::kBIT_AND;
+  } else if (name.raw() == Symbols::Caret().raw()) {
+    return Token::kBIT_XOR;
+  } else if (name.raw() == Symbols::LeftShiftOperator().raw()) {
+    return Token::kSHL;
+  } else if (name.raw() == Symbols::RightShiftOperator().raw()) {
+    return Token::kSHR;
+  } else if (name.raw() == Symbols::Tilde().raw()) {
+    return Token::kBIT_NOT;
+  } else if (name.raw() == Symbols::UnaryMinus().raw()) {
+    return Token::kNEGATE;
+  }
+  return Token::kILLEGAL;
+}
+
+
+bool ICData::HasRangeFeedback() const {
+  const String& target = String::Handle(target_name());
+  const Token::Kind token_kind = RecognizeArithmeticOp(target);
+  if (!Token::IsBinaryArithmeticOperator(token_kind) &&
+      !Token::IsUnaryArithmeticOperator(token_kind)) {
+    return false;
+  }
+
+  bool initialized = false;
+  Function& t = Function::Handle();
+  const intptr_t len = NumberOfChecks();
+  GrowableArray<intptr_t> class_ids;
+  for (intptr_t i = 0; i < len; i++) {
+    if (IsUsedAt(i)) {
+      initialized = true;
+      GetCheckAt(i, &class_ids, &t);
+      for (intptr_t j = 0; j < class_ids.length(); j++) {
+        const intptr_t cid = class_ids[j];
+        if ((cid != kSmiCid) && (cid != kMintCid)) {
+          return false;
+        }
+      }
+    }
+  }
+
+  return initialized;
+}
+
+
+ICData::RangeFeedback ICData::DecodeRangeFeedbackAt(intptr_t idx) const {
+  ASSERT((0 <= idx) && (idx < 3));
+  const uint32_t raw_feedback =
+      RangeFeedbackBits::decode(raw_ptr()->state_bits_);
+  const uint32_t feedback =
+      (raw_feedback >> (idx * kBitsPerRangeFeedback)) & kRangeFeedbackMask;
+  if ((feedback & kInt64RangeBit) != 0) {
+    return kInt64Range;
+  }
+
+  if ((feedback & kUint32RangeBit) != 0) {
+    if ((feedback & kSignedRangeBit) == 0) {
+      return kUint32Range;
+    }
+
+    // Check if Smi is large enough to accomodate Int33: a mixture of Uint32
+    // and negative Int32 values.
+    return (kSmiBits < 33) ? kInt64Range : kSmiRange;
+  }
+
+  if ((feedback & kInt32RangeBit) != 0) {
+    return kInt32Range;
+  }
+
+  return kSmiRange;
+}
+
+
 Code::Comments& Code::Comments::New(intptr_t count) {
   Comments* comments;
   if (count < 0 || count > (kIntptrMax / kNumberOfEntries)) {
@@ -18326,9 +18419,10 @@
 
 RawOneByteString* OneByteString::New(intptr_t len,
                                      Heap::Space space) {
-  ASSERT(Isolate::Current() == Dart::vm_isolate() ||
-         Isolate::Current()->object_store()->one_byte_string_class() !=
-         Class::null());
+  ASSERT((Isolate::Current() == Dart::vm_isolate()) ||
+         ((Isolate::Current()->object_store() != NULL) &&
+          (Isolate::Current()->object_store()->one_byte_string_class() !=
+           Class::null())));
   if (len < 0 || len > kMaxElements) {
     // This should be caught before we reach here.
     FATAL1("Fatal error in OneByteString::New: invalid len %" Pd "\n", len);
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index cdf9ddb..9d8be39 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3547,16 +3547,19 @@
     return raw_ptr()->deopt_id_;
   }
 
+  // Note: only deopts with reasons before Unknown in this list are recorded in
+  // the ICData. All other reasons are used purely for informational messages
+  // printed during deoptimization itself.
   #define DEOPT_REASONS(V)                                                     \
+    V(BinarySmiOp)                                                             \
+    V(BinaryMintOp)                                                            \
+    V(DoubleToSmi)                                                             \
     V(Unknown)                                                                 \
     V(InstanceGetter)                                                          \
     V(PolymorphicInstanceCallTestFail)                                         \
     V(InstanceCallNoICData)                                                    \
     V(IntegerToDouble)                                                         \
-    V(BinarySmiOp)                                                             \
-    V(BinaryMintOp)                                                            \
     V(UnaryMintOp)                                                             \
-    V(ShiftMintOp)                                                             \
     V(BinaryDoubleOp)                                                          \
     V(InstanceSetter)                                                          \
     V(Equality)                                                                \
@@ -3569,7 +3572,6 @@
     V(CheckSmi)                                                                \
     V(CheckArrayBound)                                                         \
     V(AtCall)                                                                  \
-    V(DoubleToSmi)                                                             \
     V(Int32Load)                                                               \
     V(Uint32Load)                                                              \
     V(GuardField)                                                              \
@@ -3582,6 +3584,8 @@
   #undef DEFINE_ENUM_LIST
   };
 
+  static const intptr_t kLastRecordedDeoptReason = kDeoptUnknown - 1;
+
   enum DeoptFlags {
     // Deoptimization is caused by an optimistically hoisted instruction.
     kHoisted = 1 << 0,
@@ -3715,6 +3719,78 @@
   void GetUsedCidsForTwoArgs(GrowableArray<intptr_t>* first,
                              GrowableArray<intptr_t>* second) const;
 
+  // Range feedback tracking functionality.
+
+  // For arithmetic operations we store range information for inputs and the
+  // result. The goal is to discover:
+  //
+  //    - on 32-bit platforms:
+  //         - when Mint operation is actually a int32/uint32 operation;
+  //         - when Smi operation produces non-smi results;
+  //
+  //    - on 64-bit platforms:
+  //         - when Smi operation is actually int32/uint32 operation;
+  //         - when Mint operation produces non-smi results;
+  //
+  enum RangeFeedback {
+    kSmiRange,
+    kInt32Range,
+    kUint32Range,
+    kInt64Range
+  };
+
+  // We use 4 bits per operand/result feedback. Our lattice allows us to
+  // express the following states:
+  //
+  //   - usmi   0000 [used only on 32bit platforms]
+  //   - smi    0001
+  //   - uint31 0010
+  //   - int32  0011
+  //   - uint32 0100
+  //   - int33  x1x1
+  //   - int64  1xxx
+  //
+  // DecodeRangeFeedbackAt() helper maps these states into the RangeFeedback
+  // enumeration.
+  enum RangeFeedbackLatticeBits {
+    kSignedRangeBit = 1 << 0,
+    kInt32RangeBit = 1 << 1,
+    kUint32RangeBit = 1 << 2,
+    kInt64RangeBit = 1 << 3,
+    kBitsPerRangeFeedback = 4,
+    kRangeFeedbackMask = (1 << kBitsPerRangeFeedback) - 1,
+    kRangeFeedbackSlots = 3
+  };
+
+  static bool IsValidRangeFeedbackIndex(intptr_t index) {
+    return (0 <= index) && (index < kRangeFeedbackSlots);
+  }
+
+  static intptr_t RangeFeedbackShift(intptr_t index) {
+    return (index * kBitsPerRangeFeedback) + kRangeFeedbackPos;
+  }
+
+  static const char* RangeFeedbackToString(RangeFeedback feedback) {
+    switch (feedback) {
+      case kSmiRange:
+        return "smi";
+      case kInt32Range:
+        return "int32";
+      case kUint32Range:
+        return "uint32";
+      case kInt64Range:
+        return "int64";
+      default:
+        UNREACHABLE();
+        return "?";
+    }
+  }
+
+  // It is only meaningful to interptret range feedback stored in the ICData
+  // when all checks are Mint or Smi.
+  bool HasRangeFeedback() const;
+  RangeFeedback DecodeRangeFeedbackAt(intptr_t idx) const;
+
  private:
   RawArray* ic_data() const {
     return raw_ptr()->ic_data_;
@@ -3732,8 +3808,10 @@
     kNumArgsTestedPos = 0,
     kNumArgsTestedSize = 2,
     kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize,
-    kDeoptReasonSize = kDeoptNumReasons,
+    kDeoptReasonSize = kLastRecordedDeoptReason + 1,
     kIssuedJSWarningBit = kDeoptReasonPos + kDeoptReasonSize,
+    kRangeFeedbackPos = kIssuedJSWarningBit + 1,
+    kRangeFeedbackSize = kBitsPerRangeFeedback * kRangeFeedbackSlots
   };
 
   class NumArgsTestedBits : public BitField<uint32_t,
@@ -3741,6 +3819,8 @@
   class DeoptReasonBits : public BitField<uint32_t,
       ICData::kDeoptReasonPos, ICData::kDeoptReasonSize> {};  // NOLINT
   class IssuedJSWarningBit : public BitField<bool, kIssuedJSWarningBit, 1> {};
+  class RangeFeedbackBits : public BitField<uint32_t,
+      ICData::kRangeFeedbackPos, ICData::kRangeFeedbackSize> {};  // NOLINT
 
 #if defined(DEBUG)
   // Used in asserts to verify that a check is not added twice.
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 4b08bae..8392d9a 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -61,6 +61,10 @@
 HeapPage* HeapPage::Allocate(intptr_t size_in_words, PageType type) {
   VirtualMemory* memory =
       VerifiedMemory::Reserve(size_in_words << kWordSizeLog2);
+  if (memory == NULL) {
+    FATAL1("Out of memory while allocating %" Pd " words.\n",
+           size_in_words);
+  }
   return Initialize(memory, type);
 }
 
@@ -1001,8 +1005,8 @@
     return 0;
   } else {
     ASSERT(total_time >= gc_time);
-    int result= static_cast<int>((static_cast<double>(gc_time) /
-                             static_cast<double>(total_time)) * 100);
+    int result = static_cast<int>((static_cast<double>(gc_time) /
+                                   static_cast<double>(total_time)) * 100);
     return result;
   }
 }
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 7623f33..38fa944 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -852,7 +852,7 @@
     case RawFunction::kConstructor:
       // The call to a redirecting factory is redirected.
       ASSERT(!func.IsRedirectingFactory());
-      if (!func.IsImplicitConstructor() && !func.is_async_closure()) {
+      if (!func.IsImplicitConstructor()) {
         parser.SkipFunctionPreamble();
       }
       node_sequence = parser.ParseFunc(func, &default_parameter_values);
@@ -3001,9 +3001,6 @@
   intptr_t saved_try_index = last_used_try_index_;
   last_used_try_index_ = 0;
 
-  intptr_t formal_params_pos = TokenPos();
-  // TODO(12455) : Need better validation mechanism.
-
   // In case of nested async functions we also need to save the currently saved
   // try context, the corresponding stack variable, and the scope where
   // temporaries are added.
@@ -3077,8 +3074,8 @@
     ASSERT(AbstractType::Handle(I, func.result_type()).IsResolved());
     ASSERT(func.NumParameters() == params.parameters->length());
     if (!Function::Handle(func.parent_function()).IsGetterFunction()) {
-      // Parse away any formal parameters, as they are accessed as as context
-      // variables.
+      // Parse and discard any formal parameters. They are accessed as
+      // context variables.
       ParamList parse_away;
       ParseFormalParameterList(allow_explicit_default_values,
                                false,
@@ -3131,7 +3128,7 @@
 
   Function& async_closure = Function::ZoneHandle(I);
   if (func.IsAsyncFunction() && !func.is_async_closure()) {
-    async_closure = OpenAsyncFunction(formal_params_pos);
+    async_closure = OpenAsyncFunction(func.token_pos());
   } else if (func.is_async_closure()) {
     OpenAsyncClosure();
   }
@@ -5993,7 +5990,7 @@
 }
 
 
-RawFunction* Parser::OpenAsyncFunction(intptr_t formal_param_pos) {
+RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) {
   TRACE_PARSER("OpenAsyncFunction");
   AddAsyncClosureVariables();
   Function& closure = Function::Handle(I);
@@ -6003,9 +6000,9 @@
   // this async function has already been created by a previous
   // compilation of this function.
   const Function& found_func = Function::Handle(
-      I, current_class().LookupClosureFunction(formal_param_pos));
+      I, current_class().LookupClosureFunction(async_func_pos));
   if (!found_func.IsNull() &&
-      (found_func.token_pos() == formal_param_pos) &&
+      (found_func.token_pos() == async_func_pos) &&
       (found_func.script() == innermost_function().script()) &&
       (found_func.parent_function() == innermost_function().raw())) {
     ASSERT(found_func.is_async_closure());
@@ -6019,7 +6016,7 @@
     closure = Function::NewClosureFunction(
         String::Handle(I, Symbols::New(closure_name)),
         innermost_function(),
-        formal_param_pos);
+        async_func_pos);
     closure.set_is_async_closure(true);
     closure.set_result_type(AbstractType::Handle(Type::DynamicType()));
     is_new_closure = true;
@@ -6028,7 +6025,7 @@
   ParamList closure_params;
   const Type& dynamic_type = Type::ZoneHandle(I, Type::DynamicType());
   closure_params.AddFinalParameter(
-      formal_param_pos, &Symbols::ClosureParameter(), &dynamic_type);
+      async_func_pos, &Symbols::ClosureParameter(), &dynamic_type);
   ParamDesc result_param;
   result_param.name = &Symbols::AsyncOperationParam();
   result_param.default_value = &Object::null_instance();
@@ -6051,7 +6048,7 @@
     Class& sig_cls = Class::Handle(I, library_.LookupLocalClass(sig));
     if (sig_cls.IsNull()) {
       sig_cls =
-          Class::NewSignatureClass(sig, closure, script_, formal_param_pos);
+          Class::NewSignatureClass(sig, closure, script_, closure.token_pos());
       library_.AddClass(sig_cls);
     }
     closure.set_signature_class(sig_cls);
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 5c0f9a9..520ddf5 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -319,26 +319,29 @@
   }
   void SetMarkBit() {
     ASSERT(!IsMarked());
+    UpdateTagBit<MarkBit>(true);
+  }
+  void SetMarkBitUnsynchronized() {
+    ASSERT(!IsMarked());
     uword tags = ptr()->tags_;
     ptr()->tags_ = MarkBit::update(true, tags);
   }
   void ClearMarkBit() {
     ASSERT(IsMarked());
-    uword tags = ptr()->tags_;
-    ptr()->tags_ = MarkBit::update(false, tags);
+    UpdateTagBit<MarkBit>(false);
   }
 
   // Support for GC watched bit.
+  // TODO(iposva): Get rid of this.
   bool IsWatched() const {
     return WatchedBit::decode(ptr()->tags_);
   }
-  void SetWatchedBit() {
+  void SetWatchedBitUnsynchronized() {
     ASSERT(!IsWatched());
     uword tags = ptr()->tags_;
     ptr()->tags_ = WatchedBit::update(true, tags);
   }
-  void ClearWatchedBit() {
-    ASSERT(IsWatched());
+  void ClearWatchedBitUnsynchronized() {
     uword tags = ptr()->tags_;
     ptr()->tags_ = WatchedBit::update(false, tags);
   }
@@ -348,27 +351,13 @@
     return CanonicalObjectTag::decode(ptr()->tags_);
   }
   void SetCanonical() {
-    uword tags = ptr()->tags_;
-    uword old_tags;
-    do {
-      old_tags = tags;
-      uword new_tags = CanonicalObjectTag::update(true, old_tags);
-      tags = AtomicOperations::CompareAndSwapWord(
-          &ptr()->tags_, old_tags, new_tags);
-    } while (tags != old_tags);
+    UpdateTagBit<CanonicalObjectTag>(true);
   }
   bool IsCreatedFromSnapshot() const {
     return CreatedFromSnapshotTag::decode(ptr()->tags_);
   }
   void SetCreatedFromSnapshot() {
-    uword tags = ptr()->tags_;
-    uword old_tags;
-    do {
-      old_tags = tags;
-      uword new_tags = CreatedFromSnapshotTag::update(true, old_tags);
-      tags = AtomicOperations::CompareAndSwapWord(
-          &ptr()->tags_, old_tags, new_tags);
-    } while (tags != old_tags);
+    UpdateTagBit<CreatedFromSnapshotTag>(true);
   }
 
   // Support for GC remembered bit.
@@ -377,10 +366,17 @@
   }
   void SetRememberedBit() {
     ASSERT(!IsRemembered());
+    UpdateTagBit<RememberedBit>(true);
+  }
+  void SetRememberedBitUnsynchronized() {
+    ASSERT(!IsRemembered());
     uword tags = ptr()->tags_;
     ptr()->tags_ = RememberedBit::update(true, tags);
   }
   void ClearRememberedBit() {
+    UpdateTagBit<RememberedBit>(false);
+  }
+  void ClearRememberedBitUnsynchronized() {
     uword tags = ptr()->tags_;
     ptr()->tags_ = RememberedBit::update(false, tags);
   }
@@ -480,6 +476,18 @@
     return ClassIdTag::decode(tags);
   }
 
+  template<class TagBitField>
+  void UpdateTagBit(bool value) {
+    uword tags = ptr()->tags_;
+    uword old_tags;
+    do {
+      old_tags = tags;
+      uword new_tags = TagBitField::update(value, old_tags);
+      tags = AtomicOperations::CompareAndSwapWord(
+          &ptr()->tags_, old_tags, new_tags);
+    } while (tags != old_tags);
+  }
+
   // All writes to heap objects should ultimately pass through one of the
   // methods below or their counterparts in Object, to ensure that the
   // write barrier is correctly applied.
@@ -1281,7 +1289,7 @@
   }
   int32_t deopt_id_;     // Deoptimization id corresponding to this IC.
   uint32_t state_bits_;  // Number of arguments tested in IC, deopt reasons,
-                         // is closure call, JS warning issued.
+                         // is closure call, JS warning issued, range feedback.
 };
 
 
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 51f6863..c02d6de 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -113,7 +113,7 @@
       ASSERT(raw_key->IsWatched());
     } else {
       ASSERT(!raw_key->IsWatched());
-      raw_key->SetWatchedBit();
+      raw_key->SetWatchedBitUnsynchronized();
     }
     delay_set_.insert(std::make_pair(raw_key, raw_weak));
   }
@@ -178,7 +178,7 @@
       new_addr = ForwardedAddr(header);
     } else {
       if (raw_obj->IsWatched()) {
-        raw_obj->ClearWatchedBit();
+        raw_obj->ClearWatchedBitUnsynchronized();
         std::pair<DelaySet::iterator, DelaySet::iterator> ret;
         // Visit all elements with a key equal to this raw_obj.
         ret = delay_set_.equal_range(raw_obj);
@@ -377,7 +377,9 @@
 void SemiSpace::Delete() {
 #ifdef DEBUG
   if (reserved_ != NULL) {
-    memset(reserved_->address(), kZapValue, size_in_words() << kWordSizeLog2);
+    const intptr_t size_in_bytes = size_in_words() << kWordSizeLog2;
+    memset(reserved_->address(), kZapValue, size_in_bytes);
+    VerifiedMemory::Accept(reserved_->start(), size_in_bytes);
   }
 #endif
   SemiSpace* old_cache = NULL;
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 900349a..fae2bfb 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2357,13 +2357,14 @@
     PrintError(js, "Must specify address: address/" Px ".", kExampleAddr);
     return true;
   }
+  bool ref = js->HasOption("ref") && js->OptionIs("ref", "true");
   Object& object = Object::Handle(isolate);
   {
     NoGCScope no_gc;
     ContainsAddressVisitor visitor(isolate, addr);
     object = isolate->heap()->FindObject(&visitor);
   }
-  object.PrintJSON(js, false);
+  object.PrintJSON(js, ref);
   return true;
 }
 
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index 519c2db..e77eded 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -2155,12 +2155,17 @@
   for (int offset = 0; offset < kObjectAlignment; ++offset) {
     uword addr = start_addr + offset;
     char buf[1024];
+    bool ref = offset % 2 == 0;
     OS::SNPrint(buf, sizeof(buf),
-                "[0, port, ['address', '%" Px "'], [], []]", addr);
+                ref ? "[0, port, ['address', '%" Px "'], ['ref'], ['true']]" :
+                      "[0, port, ['address', '%" Px "', ], [], []]",
+                addr);
     service_msg = Eval(lib, buf);
     Service::HandleIsolateMessage(isolate, service_msg);
     handler.HandleNextMessage();
-    EXPECT_SUBSTRING("\"type\":\"String\"", handler.msg());
+    EXPECT_SUBSTRING(ref ? "\"type\":\"@String\"" :
+                           "\"type\":\"String\"",
+                     handler.msg());
     EXPECT_SUBSTRING("foobar", handler.msg());
   }
   // Expect null when no object is found.
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index dc8ed3f..ef4ef18 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -2183,10 +2183,11 @@
       break;
     }
     case SLTIU: {
-      // Format(instr, "slti 'rt, 'rs, 'immu");
+      // Format(instr, "sltiu 'rt, 'rs, 'imms");
       uint32_t rs_val = get_register(instr->RsField());
-      uint32_t imm_val = instr->UImmField();
-      set_register(instr->RtField(), rs_val < imm_val ? 1 : 0);
+      int32_t imm_val = instr->SImmField();  // Sign extend to 32-bit.
+      uint32_t immu_val = static_cast<uint32_t>(imm_val);  // Treat as unsigned.
+      set_register(instr->RtField(), rs_val < immu_val ? 1 : 0);
       break;
     }
     case SDC1: {
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index 5e382c1..f058a29 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -54,6 +54,8 @@
   V(SmiAddInlineCache)                                                         \
   V(SmiSubInlineCache)                                                         \
   V(SmiEqualInlineCache)                                                       \
+  V(UnaryRangeCollectingInlineCache)                                           \
+  V(BinaryRangeCollectingInlineCache)                                          \
   V(OneArgOptimizedCheckInlineCache)                                           \
   V(TwoArgsOptimizedCheckInlineCache)                                          \
   V(ThreeArgsOptimizedCheckInlineCache)                                        \
@@ -206,6 +208,11 @@
 #undef STUB_CODE_ENTRY
   Isolate* isolate_;
 
+  enum RangeCollectionMode {
+    kCollectRanges,
+    kIgnoreRanges
+  };
+
   // Generate the stub and finalize the generated code into the stub
   // code executable area.
   static RawCode* Generate(const char* name,
@@ -221,7 +228,8 @@
       Assembler* assembler,
       intptr_t num_args,
       const RuntimeEntry& handle_ic_miss,
-      Token::Kind kind);
+      Token::Kind kind,
+      RangeCollectionMode range_collection_mode);
   static void GenerateUsageCounterIncrement(Assembler* assembler,
                                             Register temp_reg);
   static void GenerateOptimizedUsageCounterIncrement(Assembler* assembler);
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 9c85374..48bcd48 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -1316,7 +1316,8 @@
     Assembler* assembler,
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind) {
+    Token::Kind kind,
+    RangeCollectionMode range_collection_mode) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
   { Label ok;
@@ -1341,11 +1342,21 @@
   __ b(&stepping, NE);
   __ Bind(&done_stepping);
 
-  if (kind != Token::kILLEGAL) {
-    Label not_smi_or_overflow;
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-    __ Bind(&not_smi_or_overflow);
+  Label not_smi_or_overflow;
+  if (range_collection_mode == kCollectRanges) {
+    ASSERT((num_args == 1) || (num_args == 2));
+    if (num_args == 2) {
+      __ ldr(R0, Address(SP, 1 * kWordSize));
+      __ UpdateRangeFeedback(R0, 0, R5, R1, R4, &not_smi_or_overflow);
+    }
+
+    __ ldr(R0, Address(SP, 0 * kWordSize));
+    __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow);
   }
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
+  }
+  __ Bind(&not_smi_or_overflow);
 
   // Load arguments descriptor into R4.
   __ ldr(R4, FieldAddress(R5, ICData::arguments_descriptor_offset()));
@@ -1447,7 +1458,28 @@
   // R0: target function.
   __ ldr(R2, FieldAddress(R0, Function::instructions_offset()));
   __ AddImmediate(R2, Instructions::HeaderSize() - kHeapObjectTag);
-  __ bx(R2);
+  if (range_collection_mode == kCollectRanges) {
+    __ ldr(R1, Address(SP, 0 * kWordSize));
+    if (num_args == 2) {
+      __ ldr(R3, Address(SP, 1 * kWordSize));
+    }
+    __ EnterStubFrame();
+    if (num_args == 2) {
+      __ PushList((1 << R1) | (1 << R3) | (1 << R5));
+    } else {
+      __ PushList((1 << R1) | (1 << R5));
+    }
+    __ blx(R2);
+
+    Label done;
+    __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize));
+    __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done);
+    __ Bind(&done);
+    __ LeaveStubFrame();
+    __ Ret();
+  } else {
+    __ bx(R2);
+  }
 
   __ Bind(&stepping);
   __ EnterStubFrame();
@@ -1471,43 +1503,77 @@
 //   - 1 target function.
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+  GenerateNArgsCheckInlineCacheStub(assembler,
+      1,
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+  GenerateNArgsCheckInlineCacheStub(assembler,
+      2,
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+  GenerateNArgsCheckInlineCacheStub(assembler,
+      3,
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+  GenerateNArgsCheckInlineCacheStub(assembler,
+      2,
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kADD,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
+      kIgnoreRanges);
+}
+
+
+void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
+}
+
+
+void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
 }
 
 
@@ -1515,7 +1581,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1523,7 +1590,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1531,7 +1599,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1601,14 +1670,16 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 4228a7f..bbedec9 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -1277,7 +1277,8 @@
 static void EmitFastSmiOp(Assembler* assembler,
                           Token::Kind kind,
                           intptr_t num_args,
-                          Label* not_smi_or_overflow) {
+                          Label* not_smi_or_overflow,
+                          bool should_update_result_range) {
   if (FLAG_throw_on_javascript_int_overflow) {
     // The overflow check is more complex than implemented below.
     return;
@@ -1308,6 +1309,12 @@
     default: UNIMPLEMENTED();
   }
 
+  if (should_update_result_range) {
+    Label done;
+    __ UpdateRangeFeedback(R0, 2, R5, R1, R6, &done);
+    __ Bind(&done);
+  }
+
   // R5: IC data object (preserved).
   __ LoadFieldFromOffset(R6, R5, ICData::ic_data_offset(), kNoPP);
   // R6: ic_data_array with check entries: classes and target functions.
@@ -1353,7 +1360,8 @@
     Assembler* assembler,
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind) {
+    Token::Kind kind,
+    RangeCollectionMode range_collection_mode) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
   { Label ok;
@@ -1379,11 +1387,25 @@
   __ b(&stepping, NE);
   __ Bind(&done_stepping);
 
-  if (kind != Token::kILLEGAL) {
-    Label not_smi_or_overflow;
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-    __ Bind(&not_smi_or_overflow);
+  Label not_smi_or_overflow;
+  if (range_collection_mode == kCollectRanges) {
+    ASSERT((num_args == 1) || (num_args == 2));
+    if (num_args == 2) {
+      __ ldr(R0, Address(SP, 1 * kWordSize));
+      __ UpdateRangeFeedback(R0, 0, R5, R1, R4, &not_smi_or_overflow);
+    }
+
+    __ ldr(R0, Address(SP, 0 * kWordSize));
+    __ UpdateRangeFeedback(R0, num_args - 1, R5, R1, R4, &not_smi_or_overflow);
   }
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler,
+                  kind,
+                  num_args,
+                  &not_smi_or_overflow,
+                  (range_collection_mode == kCollectRanges));
+  }
+  __ Bind(&not_smi_or_overflow);
 
   // Load arguments descriptor into R4.
   __ LoadFieldFromOffset(R4, R5, ICData::arguments_descriptor_offset(), kNoPP);
@@ -1497,7 +1519,28 @@
   __ LoadFieldFromOffset(R2, R0, Function::instructions_offset(), kNoPP);
   __ AddImmediate(
       R2, R2, Instructions::HeaderSize() - kHeapObjectTag, kNoPP);
-  __ br(R2);
+  if (range_collection_mode == kCollectRanges) {
+    __ ldr(R1, Address(SP, 0 * kWordSize));
+    if (num_args == 2) {
+      __ ldr(R3, Address(SP, 1 * kWordSize));
+    }
+    __ EnterStubFrame();
+    __ Push(R5);
+    if (num_args == 2) {
+      __ Push(R3);
+    }
+    __ Push(R1);
+    __ blr(R2);
+
+    Label done;
+    __ ldr(R5, Address(FP, kFirstLocalSlotFromFp * kWordSize));
+    __ UpdateRangeFeedback(R0, 2, R5, R1, R4, &done);
+    __ Bind(&done);
+    __ LeaveStubFrame();
+    __ ret();
+  } else {
+    __ br(R2);
+  }
 
   __ Bind(&stepping);
   __ EnterStubFrame();
@@ -1522,42 +1565,68 @@
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
+      kIgnoreRanges);
+}
+
+
+void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
+}
+
+
+void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, R6);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
 }
 
 
@@ -1565,7 +1634,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1573,7 +1643,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1581,7 +1652,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1652,14 +1724,16 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, R6);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 331c300..a728133 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -1208,6 +1208,12 @@
       __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
       break;
     }
+    case Token::kMUL: {
+      __ SmiUntag(EAX);
+      __ imull(EAX, EDI);
+      __ j(OVERFLOW, not_smi_or_overflow, Assembler::kNearJump);
+      break;
+    }
     case Token::kEQ: {
       Label done, is_true;
       __ cmpl(EAX, EDI);
@@ -1265,7 +1271,8 @@
     Assembler* assembler,
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind) {
+    Token::Kind kind,
+    RangeCollectionMode range_collection_mode) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
   { Label ok;
@@ -1289,11 +1296,22 @@
   __ j(NOT_EQUAL, &stepping);
   __ Bind(&done_stepping);
 
-  if (kind != Token::kILLEGAL) {
-    Label not_smi_or_overflow;
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-    __ Bind(&not_smi_or_overflow);
+  Label not_smi_or_overflow;
+  if (range_collection_mode == kCollectRanges) {
+    ASSERT((num_args == 1) || (num_args == 2));
+    if (num_args == 2) {
+      __ movl(EAX, Address(ESP, + 2 * kWordSize));
+      __ UpdateRangeFeedback(EAX, 0, ECX, EBX, EDI, ESI, &not_smi_or_overflow);
+    }
+
+    __ movl(EAX, Address(ESP, + 1 * kWordSize));
+    __ UpdateRangeFeedback(EAX, (num_args - 1), ECX, EBX, EDI, ESI,
+                           &not_smi_or_overflow);
   }
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
+  }
+  __ Bind(&not_smi_or_overflow);
 
   // ECX: IC data object (preserved).
   // Load arguments descriptor into EDX.
@@ -1400,8 +1418,28 @@
   // EAX: Target function.
   __ movl(EBX, FieldAddress(EAX, Function::instructions_offset()));
   __ addl(EBX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
-  __ jmp(EBX);
-  __ int3();
+  if (range_collection_mode == kCollectRanges) {
+    __ movl(EDI, Address(ESP, + 1 * kWordSize));
+    if (num_args == 2) {
+      __ movl(ESI, Address(ESP, + 2 * kWordSize));
+    }
+    __ EnterStubFrame();
+    __ pushl(ECX);
+    if (num_args == 2) {
+      __ pushl(ESI);
+    }
+    __ pushl(EDI);
+    __ call(EBX);
+
+    __ movl(ECX, Address(EBP, kFirstLocalSlotFromFp * kWordSize));
+    Label done;
+    __ UpdateRangeFeedback(EAX, 2, ECX, EBX, EDI, ESI, &done);
+    __ Bind(&done);
+    __ LeaveFrame();
+    __ ret();
+  } else {
+    __ jmp(EBX);
+  }
 
   __ Bind(&stepping);
   __ EnterStubFrame();
@@ -1426,42 +1464,74 @@
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kADD,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kSUB,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kEQ,
+      kIgnoreRanges);
+}
+
+
+void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
+}
+
+
+void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, EBX);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
 }
 
 
@@ -1480,7 +1550,9 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1488,7 +1560,9 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-     kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+     kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+     Token::kILLEGAL,
+     kIgnoreRanges);
 }
 
 
@@ -1496,7 +1570,9 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1566,14 +1642,18 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, EBX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kStaticCallMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 55f533f..3c65795 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -1424,7 +1424,8 @@
     Assembler* assembler,
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind) {
+    Token::Kind kind,
+    RangeCollectionMode range_collection_mode) {
   __ TraceSimMsg("NArgsCheckInlineCacheStub");
   ASSERT(num_args > 0);
 #if defined(DEBUG)
@@ -1448,11 +1449,21 @@
   __ BranchNotEqual(T0, Immediate(0), &stepping);
   __ Bind(&done_stepping);
 
-  if (kind != Token::kILLEGAL) {
-    Label not_smi_or_overflow;
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-    __ Bind(&not_smi_or_overflow);
+  Label not_smi_or_overflow;
+  if (range_collection_mode == kCollectRanges) {
+    ASSERT((num_args == 1) || (num_args == 2));
+    if (num_args == 2) {
+      __ lw(T0, Address(SP, 1 * kWordSize));
+      __ UpdateRangeFeedback(T0, 0, S5, T1, &not_smi_or_overflow);
+    }
+
+    __ lw(T0, Address(SP, 0 * kWordSize));
+    __ UpdateRangeFeedback(T0, num_args - 1, S5, T1, &not_smi_or_overflow);
   }
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
+  }
+  __ Bind(&not_smi_or_overflow);
 
   // Load argument descriptor into S4.
   __ lw(S4, FieldAddress(S5, ICData::arguments_descriptor_offset()));
@@ -1585,7 +1596,32 @@
   Label is_compiled;
   __ lw(T4, FieldAddress(T0, Function::instructions_offset()));
   __ AddImmediate(T4, Instructions::HeaderSize() - kHeapObjectTag);
-  __ jr(T4);
+  if (range_collection_mode == kCollectRanges) {
+    const intptr_t frame_size = num_args + 2;
+    __ lw(T3, Address(SP, 0 * kWordSize));
+    if (num_args == 2) {
+      __ lw(T1, Address(SP, 1 * kWordSize));
+    }
+    __ EnterStubFrame();
+    __ addiu(SP, SP, Immediate(- frame_size * kWordSize));
+    __ sw(RA, Address(SP, (frame_size - 1) * kWordSize));  // Return address.
+    __ sw(S5, Address(SP, (frame_size - 2) * kWordSize));  // Preserve IC data.
+    __ sw(T3, Address(SP, 0 * kWordSize));
+    if (num_args == 2) {
+      __ sw(T1, Address(SP, 1 * kWordSize));
+    }
+    __ jalr(T4);
+    __ lw(S5, Address(SP, (frame_size - 2) * kWordSize));
+    __ lw(RA, Address(SP, (frame_size - 1) * kWordSize));
+    Label done;
+    __ UpdateRangeFeedback(V0, 2, S5, T1, &done);
+    __ Bind(&done);
+    __ addiu(SP, SP, Immediate(frame_size * kWordSize));
+    __ LeaveStubFrame();
+    __ Ret();
+  } else {
+    __ jr(T4);
+  }
 
   // Call single step callback in debugger.
   __ Bind(&stepping);
@@ -1615,42 +1651,68 @@
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ,
+      kIgnoreRanges);
+}
+
+
+void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, T0);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
+}
+
+
+void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, T0);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
 }
 
 
@@ -1658,7 +1720,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1666,7 +1729,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1674,7 +1738,8 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1749,14 +1814,16 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, T0);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 6f01264..24dada0 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -1204,7 +1204,8 @@
 static void EmitFastSmiOp(Assembler* assembler,
                           Token::Kind kind,
                           intptr_t num_args,
-                          Label* not_smi_or_overflow) {
+                          Label* not_smi_or_overflow,
+                          bool should_update_result_range) {
   if (FLAG_throw_on_javascript_int_overflow) {
     // The overflow check is more complex than implemented below.
     return;
@@ -1215,21 +1216,16 @@
   __ movq(R12, RCX);
   __ orq(R12, RAX);
   __ testq(R12, Immediate(kSmiTagMask));
-#if defined(DEBUG)
-  const bool jump_length = Assembler::kFarJump;
-#else
-  const bool jump_length = Assembler::kNearJump;
-#endif
-  __ j(NOT_ZERO, not_smi_or_overflow, jump_length);
+  __ j(NOT_ZERO, not_smi_or_overflow);
   switch (kind) {
     case Token::kADD: {
       __ addq(RAX, RCX);
-      __ j(OVERFLOW, not_smi_or_overflow, jump_length);
+      __ j(OVERFLOW, not_smi_or_overflow);
       break;
     }
     case Token::kSUB: {
       __ subq(RAX, RCX);
-      __ j(OVERFLOW, not_smi_or_overflow, jump_length);
+      __ j(OVERFLOW, not_smi_or_overflow);
       break;
     }
     case Token::kEQ: {
@@ -1246,6 +1242,14 @@
     default: UNIMPLEMENTED();
   }
 
+
+  if (should_update_result_range) {
+    Label done;
+    __ movq(RSI, RAX);
+    __ UpdateRangeFeedback(RSI, 2, RBX, RCX, &done);
+    __ Bind(&done);
+  }
+
   // RBX: IC data object (preserved).
   __ movq(R12, FieldAddress(RBX, ICData::ic_data_offset()));
   // R12: ic_data_array with check entries: classes and target functions.
@@ -1291,7 +1295,8 @@
     Assembler* assembler,
     intptr_t num_args,
     const RuntimeEntry& handle_ic_miss,
-    Token::Kind kind) {
+    Token::Kind kind,
+    RangeCollectionMode range_collection_mode) {
   ASSERT(num_args > 0);
 #if defined(DEBUG)
   { Label ok;
@@ -1314,11 +1319,26 @@
   __ j(NOT_EQUAL, &stepping);
   __ Bind(&done_stepping);
 
-  if (kind != Token::kILLEGAL) {
-    Label not_smi_or_overflow;
-    EmitFastSmiOp(assembler, kind, num_args, &not_smi_or_overflow);
-    __ Bind(&not_smi_or_overflow);
+  Label not_smi_or_overflow;
+  if (range_collection_mode == kCollectRanges) {
+    ASSERT((num_args == 1) || (num_args == 2));
+    if (num_args == 2) {
+      __ movq(RAX, Address(RSP, + 2 * kWordSize));
+      __ UpdateRangeFeedback(RAX, 0, RBX, RCX, &not_smi_or_overflow);
+    }
+
+    __ movq(RAX, Address(RSP, + 1 * kWordSize));
+    __ UpdateRangeFeedback(RAX, (num_args - 1), RBX, RCX, &not_smi_or_overflow);
   }
+  if (kind != Token::kILLEGAL) {
+    EmitFastSmiOp(
+        assembler,
+        kind,
+        num_args,
+        &not_smi_or_overflow,
+        range_collection_mode == kCollectRanges);
+  }
+  __ Bind(&not_smi_or_overflow);
 
   // Load arguments descriptor into R10.
   __ movq(R10, FieldAddress(RBX, ICData::arguments_descriptor_offset()));
@@ -1420,7 +1440,29 @@
   Label is_compiled;
   __ movq(RCX, FieldAddress(RAX, Function::instructions_offset()));
   __ addq(RCX, Immediate(Instructions::HeaderSize() - kHeapObjectTag));
-  __ jmp(RCX);
+  if (range_collection_mode == kCollectRanges) {
+    __ movq(R8, Address(RSP, + 1 * kWordSize));
+    if (num_args == 2) {
+      __ movq(R9, Address(RSP, + 2 * kWordSize));
+    }
+    __ EnterStubFrame();
+    __ pushq(RBX);
+    if (num_args == 2) {
+      __ pushq(R9);
+    }
+    __ pushq(R8);
+    __ call(RCX);
+
+    Label done;
+    __ movq(RDX, RAX);
+    __ movq(RBX, Address(RBP, kFirstLocalSlotFromFp * kWordSize));
+    __ UpdateRangeFeedback(RDX, 2, RBX, RCX, &done);
+    __ Bind(&done);
+    __ LeaveFrame();
+    __ ret();
+  } else {
+    __ jmp(RCX);
+  }
 
   __ Bind(&stepping);
   __ EnterStubFrame();
@@ -1445,42 +1487,74 @@
 void StubCode::GenerateOneArgCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateThreeArgsCheckInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateSmiAddInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kADD);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kADD,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiSubInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kSUB);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kSUB,
+      kCollectRanges);
 }
 
 
 void StubCode::GenerateSmiEqualInlineCacheStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kEQ);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kEQ,
+      kIgnoreRanges);
+}
+
+
+void StubCode::GenerateUnaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(assembler, 1,
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
+}
+
+
+void StubCode::GenerateBinaryRangeCollectingInlineCacheStub(
+    Assembler* assembler) {
+  GenerateUsageCounterIncrement(assembler, RCX);
+  GenerateNArgsCheckInlineCacheStub(assembler, 2,
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kCollectRanges);
 }
 
 
@@ -1499,7 +1573,9 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 1,
-      kInlineCacheMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1507,7 +1583,9 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kInlineCacheMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1515,7 +1593,9 @@
     Assembler* assembler) {
   GenerateOptimizedUsageCounterIncrement(assembler);
   GenerateNArgsCheckInlineCacheStub(assembler, 3,
-      kInlineCacheMissHandlerThreeArgsRuntimeEntry, Token::kILLEGAL);
+      kInlineCacheMissHandlerThreeArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
@@ -1584,14 +1664,21 @@
 void StubCode::GenerateOneArgUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
   GenerateNArgsCheckInlineCacheStub(
-      assembler, 1, kStaticCallMissHandlerOneArgRuntimeEntry, Token::kILLEGAL);
+      assembler,
+      1,
+      kStaticCallMissHandlerOneArgRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
 void StubCode::GenerateTwoArgsUnoptimizedStaticCallStub(Assembler* assembler) {
   GenerateUsageCounterIncrement(assembler, RCX);
-  GenerateNArgsCheckInlineCacheStub(assembler, 2,
-      kStaticCallMissHandlerTwoArgsRuntimeEntry, Token::kILLEGAL);
+  GenerateNArgsCheckInlineCacheStub(assembler,
+      2,
+      kStaticCallMissHandlerTwoArgsRuntimeEntry,
+      Token::kILLEGAL,
+      kIgnoreRanges);
 }
 
 
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 22a4ba9..de7c318 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -20,6 +20,9 @@
   V(EqualOperator, "==")                                                       \
   V(GreaterEqualOperator, ">=")                                                \
   V(LessEqualOperator, "<=")                                                   \
+  V(LeftShiftOperator, "<<")                                                   \
+  V(RightShiftOperator, ">>")                                                  \
+  V(TruncDivOperator, "~/")                                                    \
   V(UnaryMinus, "unary-")                                                      \
   V(Identical, "identical")                                                    \
   V(Length, "length")                                                          \
@@ -470,6 +473,18 @@
   static const String& Semicolon() {
     return *(symbol_handles_[kNullCharId + ';']);
   }
+  static const String& Star() {
+    return *(symbol_handles_[kNullCharId + '*']);
+  }
+  static const String& Percent() {
+    return *(symbol_handles_[kNullCharId + '%']);
+  }
+  static const String& Caret() {
+    return *(symbol_handles_[kNullCharId + '^']);
+  }
+  static const String& Tilde() {
+    return *(symbol_handles_[kNullCharId + '~']);
+  }
 
   // Access methods for symbol handles stored in the vm isolate.
 #define DEFINE_SYMBOL_HANDLE_ACCESSOR(symbol, literal)                         \
diff --git a/runtime/vm/token.cc b/runtime/vm/token.cc
index 2289718..75872e5 100644
--- a/runtime/vm/token.cc
+++ b/runtime/vm/token.cc
@@ -39,6 +39,22 @@
 
 bool Token::IsBinaryOperator(Token::Kind token) {
   switch (token) {
+    case Token::kOR:
+    case Token::kAND:
+      return true;
+    default:
+      return IsBinaryArithmeticOperator(token);
+  }
+}
+
+
+bool Token::IsUnaryOperator(Token::Kind token) {
+  return (token == kNOT) || IsUnaryArithmeticOperator(token);
+}
+
+
+bool Token::IsBinaryArithmeticOperator(Token::Kind token) {
+  switch (token) {
     case Token::kADD:
     case Token::kSUB:
     case Token::kMUL:
@@ -48,8 +64,6 @@
     case Token::kBIT_OR:
     case Token::kBIT_XOR:
     case Token::kBIT_AND:
-    case Token::kOR:
-    case Token::kAND:
     case Token::kSHL:
     case Token::kSHR:
       return true;
@@ -59,8 +73,9 @@
 }
 
 
-bool Token::IsPrefixOperator(Token::Kind token) {
-  return (token == kNOT) || (token == kBIT_NOT) || (token == kNEGATE);
+bool Token::IsUnaryArithmeticOperator(Token::Kind token) {
+  return (token == kBIT_NOT) || (token == kNEGATE);
 }
 
+
 }  // namespace dart
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index f633894..d22a6c0 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -291,7 +291,10 @@
   }
 
   static bool IsBinaryOperator(Token::Kind token);
-  static bool IsPrefixOperator(Token::Kind token);
+  static bool IsUnaryOperator(Token::Kind token);
+
+  static bool IsBinaryArithmeticOperator(Token::Kind token);
+  static bool IsUnaryArithmeticOperator(Token::Kind token);
 
   // For a comparison operation return an operation for the negated comparison:
   // !(a (op) b) === a (op') b
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index ea4bdd7..01aac9d 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -149,6 +149,8 @@
     reinterpret_cast<name>(entry)(float_arg)
 #define EXECUTE_TEST_CODE_INT32_D(name, entry, double_arg)                     \
     reinterpret_cast<name>(entry)(double_arg)
+#define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg)              \
+    reinterpret_cast<name>(entry)(pointer_arg)
 #else
 // Not running on ARM or MIPS hardware, call simulator to execute code.
 #if defined(ARCH_IS_64_BIT)
@@ -159,6 +161,11 @@
 #define EXECUTE_TEST_CODE_DOUBLE(name, entry)                                  \
   bit_cast<double, int64_t>(Simulator::Current()->Call(                        \
       bit_cast<int64_t, uword>(entry), 0, 0, 0, 0, true))
+#define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg)              \
+  static_cast<intptr_t>(Simulator::Current()->Call(                            \
+      bit_cast<int64_t, uword>(entry),                                         \
+      bit_cast<int64_t, intptr_t>(pointer_arg),                                \
+      0, 0, 0))
 #else
 #define EXECUTE_TEST_CODE_INT32(name, entry)                                   \
   static_cast<int32_t>(Simulator::Current()->Call(                             \
@@ -166,6 +173,11 @@
 #define EXECUTE_TEST_CODE_DOUBLE(name, entry)                                  \
   bit_cast<double, int64_t>(Simulator::Current()->Call(                        \
       bit_cast<int32_t, uword>(entry), 0, 0, 0, 0, true))
+#define EXECUTE_TEST_CODE_INTPTR_INTPTR(name, entry, pointer_arg)              \
+  static_cast<intptr_t>(Simulator::Current()->Call(                            \
+      bit_cast<int32_t, uword>(entry),                                         \
+      bit_cast<int32_t, intptr_t>(pointer_arg),                                \
+      0, 0, 0))
 #endif
 #define EXECUTE_TEST_CODE_INT64_LL(name, entry, long_arg0, long_arg1)          \
   static_cast<int64_t>(Simulator::Current()->Call(                             \
diff --git a/sdk/lib/_internal/compiler/js_lib/convert_patch.dart b/sdk/lib/_internal/compiler/js_lib/convert_patch.dart
index bd8816f..f7eb2bd 100644
--- a/sdk/lib/_internal/compiler/js_lib/convert_patch.dart
+++ b/sdk/lib/_internal/compiler/js_lib/convert_patch.dart
@@ -7,7 +7,7 @@
 import 'dart:_js_helper' show patch;
 import 'dart:_foreign_helper' show JS;
 import 'dart:_interceptors' show JSExtendableArray;
-import 'dart:_internal' show MappedIterable;
+import 'dart:_internal' show MappedIterable, ListIterable;
 import 'dart:collection' show Maps, LinkedHashMap;
 
 /**
@@ -161,7 +161,7 @@
 
   Iterable get keys {
     if (_isUpgraded) return _upgradedMap.keys;
-    return _computeKeys().skip(0);
+    return new _JsonMapKeyIterable(this);
   }
 
   Iterable get values {
@@ -338,6 +338,31 @@
       => JS('=Object', 'Object.create(null)');
 }
 
+class _JsonMapKeyIterable extends ListIterable {
+  final _JsonMap _parent;
+
+  _JsonMapKeyIterable(this._parent);
+
+  int get length => _parent.length;
+
+  String elementAt(int index) {
+    return _parent._isUpgraded ? _parent.keys.elementAt(index)
+                               : _parent._computeKeys()[index];
+  }
+
+  /// Although [ListIterable] defines its own iterator, we return the iterator
+  /// of the underlying list [_keys] in order to propagate
+  /// [ConcurrentModificationError]s.
+  Iterator get iterator {
+    return _parent._isUpgraded ? _parent.keys.iterator
+                               : _parent._computeKeys().iterator;
+  }
+
+  /// Delegate to [parent.containsKey] to ensure the performance expected
+  /// from [Map.keys.containsKey].
+  bool contains(Object key) => _parent.containsKey(key);
+}
+
 @patch class JsonDecoder {
   @patch
   StringConversionSink startChunkedConversion(Sink<Object> sink) {
diff --git a/sdk/lib/_internal/compiler/js_lib/core_patch.dart b/sdk/lib/_internal/compiler/js_lib/core_patch.dart
index 9f5bf1c..c0180d8 100644
--- a/sdk/lib/_internal/compiler/js_lib/core_patch.dart
+++ b/sdk/lib/_internal/compiler/js_lib/core_patch.dart
@@ -373,13 +373,16 @@
 
   @patch
   void write(Object obj) {
-    String str = obj is String ? obj : "$obj";
-    _contents = Primitives.stringConcatUnchecked(_contents, str);
+    _writeString('$obj');
   }
 
   @patch
   void writeCharCode(int charCode) {
-    write(new String.fromCharCode(charCode));
+    _writeString(new String.fromCharCode(charCode));
+  }
+
+  void _writeString(str) {
+    _contents = Primitives.stringConcatUnchecked(_contents, str);
   }
 
   @patch
diff --git a/sdk/lib/_internal/compiler/js_lib/interceptors.dart b/sdk/lib/_internal/compiler/js_lib/interceptors.dart
index e70b106..22e2e91 100644
--- a/sdk/lib/_internal/compiler/js_lib/interceptors.dart
+++ b/sdk/lib/_internal/compiler/js_lib/interceptors.dart
@@ -4,7 +4,7 @@
 
 library _interceptors;
 
-import 'shared/embedded_names.dart' show
+import 'dart:_js_embedded_names' show
     DISPATCH_PROPERTY_NAME;
 
 import 'dart:collection';
diff --git a/sdk/lib/_internal/compiler/js_lib/isolate_helper.dart b/sdk/lib/_internal/compiler/js_lib/isolate_helper.dart
index deebe80..3d16eeb 100644
--- a/sdk/lib/_internal/compiler/js_lib/isolate_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/isolate_helper.dart
@@ -4,7 +4,7 @@
 
 library _isolate_helper;
 
-import 'shared/embedded_names.dart' show
+import 'dart:_js_embedded_names' show
     CLASS_ID_EXTRACTOR,
     CLASS_FIELDS_EXTRACTOR,
     CURRENT_SCRIPT,
diff --git a/sdk/lib/_internal/compiler/js_lib/js_helper.dart b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
index cca4e0e..376b043 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_helper.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_helper.dart
@@ -4,7 +4,7 @@
 
 library _js_helper;
 
-import 'shared/embedded_names.dart' show
+import 'dart:_js_embedded_names' show
     ALL_CLASSES,
     GET_ISOLATE_TAG,
     INTERCEPTED_NAMES,
@@ -1034,57 +1034,20 @@
   static applyFunction(Function function,
                        List positionalArguments,
                        Map<String, dynamic> namedArguments) {
-    if (namedArguments != null && !namedArguments.isEmpty) {
-      // TODO(ahe): The following code can be shared with
-      // JsInstanceMirror.invoke.
-      var interceptor = getInterceptor(function);
-      var jsFunction = JS('', '#["call*"]', interceptor);
+    // Dispatch on presence of named arguments to improve tree-shaking.
+    //
+    // This dispatch is as simple as possible to help the compiler detect the
+    // common case of `null` namedArguments, either via inlining or
+    // specialization.
+    return namedArguments == null
+        ? applyFunctionWithPositionalArguments(
+            function, positionalArguments)
+        : applyFunctionWithNamedArguments(
+            function, positionalArguments, namedArguments);
+  }
 
-      if (jsFunction == null) {
-        return functionNoSuchMethod(
-            function, positionalArguments, namedArguments);
-      }
-      ReflectionInfo info = new ReflectionInfo(jsFunction);
-      if (info == null || !info.areOptionalParametersNamed) {
-        return functionNoSuchMethod(
-            function, positionalArguments, namedArguments);
-      }
-
-      if (positionalArguments != null) {
-        positionalArguments = new List.from(positionalArguments);
-      } else {
-        positionalArguments = [];
-      }
-      // Check the number of positional arguments is valid.
-      if (info.requiredParameterCount != positionalArguments.length) {
-        return functionNoSuchMethod(
-            function, positionalArguments, namedArguments);
-      }
-      var defaultArguments = new Map();
-      for (int i = 0; i < info.optionalParameterCount; i++) {
-        int index = i + info.requiredParameterCount;
-        var parameterName = info.parameterNameInOrder(index);
-        var value = info.defaultValueInOrder(index);
-        var defaultValue = getMetadata(value);
-        defaultArguments[parameterName] = defaultValue;
-      }
-      bool bad = false;
-      namedArguments.forEach((String parameter, value) {
-        if (defaultArguments.containsKey(parameter)) {
-          defaultArguments[parameter] = value;
-        } else {
-          // Extraneous named argument.
-          bad = true;
-        }
-      });
-      if (bad) {
-        return functionNoSuchMethod(
-            function, positionalArguments, namedArguments);
-      }
-      positionalArguments.addAll(defaultArguments.values);
-      return JS('', '#.apply(#, #)', jsFunction, function, positionalArguments);
-    }
-
+  static applyFunctionWithPositionalArguments(Function function,
+                                              List positionalArguments) {
     int argumentCount = 0;
     List arguments;
 
@@ -1106,8 +1069,7 @@
       // TODO(ahe): This might occur for optional arguments if there is no call
       // selector with that many arguments.
 
-      return
-          functionNoSuchMethod(function, positionalArguments, namedArguments);
+      return functionNoSuchMethod(function, positionalArguments, null);
     }
     // We bound 'this' to [function] because of how we compile
     // closures: escaped local variables are stored and accessed through
@@ -1115,6 +1077,63 @@
     return JS('var', '#.apply(#, #)', jsFunction, function, arguments);
   }
 
+  static applyFunctionWithNamedArguments(Function function,
+                                         List positionalArguments,
+                                         Map<String, dynamic> namedArguments) {
+    if (namedArguments.isEmpty) {
+      return applyFunctionWithPositionalArguments(
+          function, positionalArguments);
+    }
+    // TODO(ahe): The following code can be shared with
+    // JsInstanceMirror.invoke.
+    var interceptor = getInterceptor(function);
+    var jsFunction = JS('', '#["call*"]', interceptor);
+
+    if (jsFunction == null) {
+      return functionNoSuchMethod(
+          function, positionalArguments, namedArguments);
+    }
+    ReflectionInfo info = new ReflectionInfo(jsFunction);
+    if (info == null || !info.areOptionalParametersNamed) {
+      return functionNoSuchMethod(
+          function, positionalArguments, namedArguments);
+    }
+
+    if (positionalArguments != null) {
+      positionalArguments = new List.from(positionalArguments);
+    } else {
+      positionalArguments = [];
+    }
+    // Check the number of positional arguments is valid.
+    if (info.requiredParameterCount != positionalArguments.length) {
+      return functionNoSuchMethod(
+          function, positionalArguments, namedArguments);
+    }
+    var defaultArguments = new Map();
+    for (int i = 0; i < info.optionalParameterCount; i++) {
+      int index = i + info.requiredParameterCount;
+      var parameterName = info.parameterNameInOrder(index);
+      var value = info.defaultValueInOrder(index);
+      var defaultValue = getMetadata(value);
+      defaultArguments[parameterName] = defaultValue;
+    }
+    bool bad = false;
+    namedArguments.forEach((String parameter, value) {
+      if (defaultArguments.containsKey(parameter)) {
+        defaultArguments[parameter] = value;
+      } else {
+        // Extraneous named argument.
+        bad = true;
+      }
+    });
+    if (bad) {
+      return functionNoSuchMethod(
+          function, positionalArguments, namedArguments);
+    }
+    positionalArguments.addAll(defaultArguments.values);
+    return JS('', '#.apply(#, #)', jsFunction, function, positionalArguments);
+  }
+
   static _mangledNameMatchesType(String mangledName, TypeImpl type) {
     return JS('bool', '# == #', mangledName, type._typeName);
   }
@@ -3293,15 +3312,17 @@
   // The indices into `uris` and `hashes` that we want to load.
   List<int> indices = new List.generate(uris.length, (i) => i);
   var isHunkLoaded = JS_EMBEDDED_GLOBAL('', IS_HUNK_LOADED);
-  return Future.wait(indices
-      // Filter away indices for hunks that have already been loaded.
+  // Filter away indices for hunks that have already been loaded.
+  List<int> indicesToLoad = indices
       .where((int i) => !JS('bool','#(#)', isHunkLoaded, hashes[i]))
-      // Load the rest.
+      .toList();
+  // Load the needed hunks.
+  return Future.wait(indicesToLoad
       .map((int i) => _loadHunk(uris[i]))).then((_) {
-    // Now all hunks have been loaded, we call all their initializers
-    for (String hash in hashes) {
+    // Now all hunks have been loaded, we run the needed initializers.
+    for (int i in indicesToLoad) {
       var initializer = JS_EMBEDDED_GLOBAL('', INITIALIZE_LOADED_HUNK);
-      JS('void', '#(#)', initializer, hash);
+      JS('void', '#(#)', initializer, hashes[i]);
     }
     bool updated = _loadedLibraries.add(loadId);
     if (updated && deferredLoadHook != null) {
diff --git a/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart b/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
index d634385..9d55eed 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_mirrors.dart
@@ -4,13 +4,14 @@
 
 library dart._js_mirrors;
 
-import 'shared/runtime_data.dart' as encoding;
-import 'shared/embedded_names.dart' show
+import 'dart:_js_embedded_names' show
     ALL_CLASSES,
     LAZIES,
     LIBRARIES,
     STATICS,
-    TYPE_INFORMATION;
+    TYPE_INFORMATION,
+    TYPEDEF_PREDICATE_PROPERTY_NAME,
+    TYPEDEF_TYPE_PROPERTY_NAME;
 
 import 'dart:collection' show
     UnmodifiableListView,
@@ -634,6 +635,19 @@
   if (descriptor == null) {
     // This is a native class, or an intercepted class.
     // TODO(ahe): Preserve descriptor for such classes.
+  } else if (JS('bool', '# in #',
+                TYPEDEF_PREDICATE_PROPERTY_NAME, descriptor)) {
+    // Typedefs are represented as normal classes with two special properties:
+    //   TYPEDEF_PREDICATE_PROPERTY_NAME and TYPEDEF_TYPE_PROPERTY_NAME.
+    // For example:
+    //  MyTypedef: {
+    //     "^": "Object;",
+    //     $typedefType: 58,
+    //     $$isTypedef: true
+    //  }
+    //  The typedefType is the index into the metadata table.
+    int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME);
+    mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index));
   } else {
     fields = JS('', '#[#]', descriptor,
         JS_GET_NAME('CLASS_DESCRIPTOR_PROPERTY'));
@@ -648,10 +662,7 @@
     }
   }
 
-  if (encoding.isTypedefDescriptor(fields)) {
-    int index = encoding.getTypeFromTypedef(fields);
-    mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index));
-  } else {
+  if (mirror == null) {
     var superclassName = fields.split(';')[0];
     var mixins = superclassName.split('+');
     if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) {
diff --git a/sdk/lib/_internal/compiler/js_lib/js_names.dart b/sdk/lib/_internal/compiler/js_lib/js_names.dart
index f30edfd..3933e78 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_names.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_names.dart
@@ -4,7 +4,7 @@
 
 library dart._js_names;
 
-import 'shared/embedded_names.dart' show
+import 'dart:_js_embedded_names' show
     MANGLED_GLOBAL_NAMES,
     MANGLED_NAMES;
 
diff --git a/sdk/lib/_internal/compiler/js_lib/js_rti.dart b/sdk/lib/_internal/compiler/js_lib/js_rti.dart
index 2cf4b48..08c52dd 100644
--- a/sdk/lib/_internal/compiler/js_lib/js_rti.dart
+++ b/sdk/lib/_internal/compiler/js_lib/js_rti.dart
@@ -83,10 +83,10 @@
 /**
  * Sets the runtime type information on [target]. [typeInfo] is a type
  * representation of type 4 or 5, that is, either a JavaScript array or
- * [:null:].
+ * `null`.
  */
 Object setRuntimeTypeInfo(Object target, var typeInfo) {
-  assert(isNull(typeInfo) || isJsArray(typeInfo));
+  assert(typeInfo == null || isJsArray(typeInfo));
   // We have to check for null because factories may return null.
   if (target != null) JS('var', r'#.$builtinTypeInfo = #', target, typeInfo);
   return target;
@@ -117,13 +117,13 @@
 @NoThrows() @NoSideEffects() @NoInline()
 getRuntimeTypeArgument(Object target, String substitutionName, int index) {
   var arguments = getRuntimeTypeArguments(target, substitutionName);
-  return isNull(arguments) ? null : getIndex(arguments, index);
+  return arguments == null ? null : getIndex(arguments, index);
 }
 
 @NoThrows() @NoSideEffects() @NoInline()
 getTypeArgumentByIndex(Object target, int index) {
   var rti = getRuntimeTypeInfo(target);
-  return isNull(rti) ? null : getIndex(rti, index);
+  return rti == null ? null : getIndex(rti, index);
 }
 
 void copyTypeArguments(Object source, Object target) {
@@ -160,7 +160,7 @@
  * Returns a human-readable representation of the type representation [type].
  */
 String runtimeTypeToString(var type, {String onTypeVariable(int i)}) {
-  if (isNull(type)) {
+  if (type == null) {
     return 'dynamic';
   } else if (isJsArray(type)) {
     // A list representing a type with arguments.
@@ -187,7 +187,7 @@
  */
 String joinArguments(var types, int startIndex,
                      {String onTypeVariable(int i)}) {
-  if (isNull(types)) return '';
+  if (types == null) return '';
   assert(isJsArray(types));
   bool firstArgument = true;
   bool allDynamic = true;
@@ -231,9 +231,9 @@
  * possible values for [substitution].
  */
 substitute(var substitution, var arguments) {
-  assert(isNull(substitution) ||
+  assert(substitution == null ||
          isJsFunction(substitution));
-  assert(isNull(arguments) || isJsArray(arguments));
+  assert(arguments == null || isJsArray(arguments));
   if (isJsFunction(substitution)) {
     substitution = invoke(substitution, arguments);
     if (isJsArray(substitution)) {
@@ -267,8 +267,8 @@
   // TODO(9586): Move type info for static functions onto an interceptor.
   var interceptor = getInterceptor(object);
   var isSubclass = getField(interceptor, isField);
-  // When we read the field and it is not there, [isSubclass] will be [:null:].
-  if (isNull(isSubclass)) return false;
+  // When we read the field and it is not there, [isSubclass] will be `null`.
+  if (isSubclass == null) return false;
   // Should the asField function be passed the receiver?
   var substitution = getField(interceptor, asField);
   return checkArguments(substitution, arguments, checks);
@@ -332,17 +332,17 @@
 /**
  * Checks whether the types of [s] are all subtypes of the types of [t].
  *
- * [s] and [t] are either [:null:] or JavaScript arrays of type representations,
- * A [:null:] argument is interpreted as the arguments of a raw type, that is a
- * list of [:dynamic:]. If [s] and [t] are JavaScript arrays they must be of the
+ * [s] and [t] are either `null` or JavaScript arrays of type representations,
+ * A `null` argument is interpreted as the arguments of a raw type, that is a
+ * list of `dynamic`. If [s] and [t] are JavaScript arrays they must be of the
  * same length.
  *
  * See the comment in the beginning of this file for a description of type
  * representations.
  */
 bool areSubtypes(var s, var t) {
-  // [:null:] means a raw type.
-  if (isNull(s) || isNull(t)) return true;
+  // `null` means a raw type.
+  if (s == null || t == null) return true;
 
   assert(isJsArray(s));
   assert(isJsArray(t));
@@ -367,12 +367,12 @@
 }
 
 /**
- * Returns [:true:] if the runtime type representation [type] is a supertype of
- * [:Null:].
+ * Returns `true` if the runtime type representation [type] is a supertype of
+ * [Null].
  */
 bool isSupertypeOfNull(var type) {
   // `null` means `dynamic`.
-  return isNull(type) || getConstructorName(type) == JS_OBJECT_CLASS_NAME()
+  return type == null || getConstructorName(type) == JS_OBJECT_CLASS_NAME()
                       || getConstructorName(type) == JS_NULL_CLASS_NAME();
 }
 
@@ -384,25 +384,30 @@
  * representations.
  */
 bool checkSubtypeOfRuntimeType(o, t) {
-  if (isNull(o)) return isSupertypeOfNull(t);
-  if (isNull(t)) return true;
+  if (o == null) return isSupertypeOfNull(t);
+  if (t == null) return true;
   // Get the runtime type information from the object here, because we may
   // overwrite o with the interceptor below.
   var rti = getRuntimeTypeInfo(o);
   o = getInterceptor(o);
-  // We can use the object as its own type representation because we install
-  // the subtype flags and the substitution on the prototype, so they are
-  // properties of the object in JS.
-  var type;
-  if (isNotNull(rti)) {
-    // If the type has type variables (that is, [:rti != null:]), make a copy of
+  var type = JS('', '#.constructor', o);
+  if (rti != null) {
+    // If the type has type variables (that is, `rti != null`), make a copy of
     // the type arguments and insert [o] in the first position to create a
     // compound type representation.
-    type = JS('JSExtendableArray', '#.slice()', rti);
-    JS('', '#.splice(0, 0, #)', type, o);
-  } else {
-    // Use the object as representation of the raw type.
-    type = o;
+    rti = JS('JSExtendableArray', '#.slice()', rti);  // Make a copy.
+    JS('', '#.splice(0, 0, #)', rti, type);  // Insert type at position 0.
+    type = rti;
+  } else if (hasField(t, '${JS_FUNCTION_TYPE_TAG()}')) {
+    // Functions are treated specially and have their type information stored
+    // directly in the instance.
+    var signatureName =
+        '${JS_OPERATOR_IS_PREFIX()}_${getField(t, JS_FUNCTION_TYPE_TAG())}';
+    if (hasField(o, signatureName)) return true;
+    var targetSignatureFunction = getField(o, '${JS_SIGNATURE_NAME()}');
+    if (targetSignatureFunction == null) return false;
+    type = invokeOn(targetSignatureFunction, o, null);
+    return isFunctionSubtype(type, t);
   }
   return isSubtype(type, t);
 }
@@ -424,7 +429,7 @@
 
 /**
  * Extracts the type arguments from a type representation. The result is a
- * JavaScript array or [:null:].
+ * JavaScript array or `null`.
  */
 getArguments(var type) {
   return isJsArray(type) ? JS('var', r'#.slice(1)', type) : null;
@@ -436,28 +441,23 @@
  *
  * See the comment in the beginning of this file for a description of type
  * representations.
+ *
+ * The arguments [s] and [t] must be types, usually represented by the
+ * constructor of the class, or an array (for generic types).
  */
 bool isSubtype(var s, var t) {
   // Subtyping is reflexive.
   if (isIdentical(s, t)) return true;
   // If either type is dynamic, [s] is a subtype of [t].
-  if (isNull(s) || isNull(t)) return true;
+  if (s == null || t == null) return true;
   if (hasField(t, '${JS_FUNCTION_TYPE_TAG()}')) {
-    if (hasNoField(s, '${JS_FUNCTION_TYPE_TAG()}')) {
-      var signatureName =
-          '${JS_OPERATOR_IS_PREFIX()}_${getField(t, JS_FUNCTION_TYPE_TAG())}';
-      if (hasField(s, signatureName)) return true;
-      var targetSignatureFunction = getField(s, '${JS_SIGNATURE_NAME()}');
-      if (isNull(targetSignatureFunction)) return false;
-      s = invokeOn(targetSignatureFunction, s, null);
-    }
     return isFunctionSubtype(s, t);
   }
   // Check function types against the Function class.
-  if (getConstructorName(t) == JS_FUNCTION_CLASS_NAME() &&
-      hasField(s, '${JS_FUNCTION_TYPE_TAG()}')) {
-    return true;
+  if (hasField(s, '${JS_FUNCTION_TYPE_TAG()}')) {
+    return getConstructorName(t) == JS_FUNCTION_CLASS_NAME();
   }
+
   // Get the object describing the class and check for the subtyping flag
   // constructed from the type of [t].
   var typeOfS = isJsArray(s) ? getIndex(s, 0) : s;
@@ -468,15 +468,16 @@
   var substitution;
   if (isNotIdentical(typeOfT, typeOfS)) {
     var test = '${JS_OPERATOR_IS_PREFIX()}${name}';
-    if (hasNoField(typeOfS, test)) return false;
+    var typeOfSPrototype = JS('', '#.prototype', typeOfS);
+    if (hasNoField(typeOfSPrototype, test)) return false;
     var field = '${JS_OPERATOR_AS_PREFIX()}${runtimeTypeToString(typeOfT)}';
-    substitution = getField(typeOfS, field);
+    substitution = getField(typeOfSPrototype, field);
   }
   // The class of [s] is a subclass of the class of [t].  If [s] has no type
   // arguments and no substitution, it is used as raw type.  If [t] has no
   // type arguments, it used as a raw type.  In both cases, [s] is a subtype
   // of [t].
-  if ((!isJsArray(s) && isNull(substitution)) || !isJsArray(t)) {
+  if ((!isJsArray(s) && substitution == null) || !isJsArray(t)) {
     return true;
   }
   // Recursively check the type arguments.
@@ -488,15 +489,15 @@
 }
 
 /**
- * If [allowShorter] is [:true:], [t] is allowed to be shorter than [s].
+ * If [allowShorter] is `true`, [t] is allowed to be shorter than [s].
  */
 bool areAssignable(List s, List t, bool allowShorter) {
   // Both lists are empty and thus equal.
-  if (isNull(t) && isNull(s)) return true;
+  if (t ==null && s == null) return true;
   // [t] is empty (and [s] is not) => only OK if [allowShorter].
-  if (isNull(t)) return allowShorter;
+  if (t == null) return allowShorter;
   // [s] is empty (and [t] is not) => [s] is not longer or equal to [t].
-  if (isNull(s)) return false;
+  if (s == null) return false;
 
   assert(isJsArray(s));
   assert(isJsArray(t));
@@ -518,8 +519,8 @@
 }
 
 bool areAssignableMaps(var s, var t) {
-  if (isNull(t)) return true;
-  if (isNull(s)) return false;
+  if (t == null) return true;
+  if (s == null) return false;
 
   assert(isJsObject(s));
   assert(isJsObject(t));
@@ -561,15 +562,13 @@
   var tOptionalParameterTypes =
       getField(t, '${JS_FUNCTION_TYPE_OPTIONAL_PARAMETERS_TAG()}');
 
-  int sParametersLen =
-      isNotNull(sParameterTypes) ? getLength(sParameterTypes) : 0;
-  int tParametersLen =
-      isNotNull(tParameterTypes) ? getLength(tParameterTypes) : 0;
+  int sParametersLen = sParameterTypes != null ? getLength(sParameterTypes) : 0;
+  int tParametersLen = tParameterTypes != null ? getLength(tParameterTypes) : 0;
 
-  int sOptionalParametersLen = isNotNull(sOptionalParameterTypes)
-      ? getLength(sOptionalParameterTypes) : 0;
-  int tOptionalParametersLen = isNotNull(tOptionalParameterTypes)
-      ? getLength(tOptionalParameterTypes) : 0;
+  int sOptionalParametersLen =
+      sOptionalParameterTypes != null ? getLength(sOptionalParameterTypes) : 0;
+  int tOptionalParametersLen =
+      tOptionalParameterTypes != null ? getLength(tOptionalParameterTypes) : 0;
 
   if (sParametersLen > tParametersLen) {
     // Too many required parameters in [s].
@@ -627,17 +626,17 @@
 
 /**
  * Calls the JavaScript [function] with the [arguments] with the global scope
- * as the [:this:] context.
+ * as the `this` context.
  */
 invoke(var function, var arguments) => invokeOn(function, null, arguments);
 
 /**
  * Calls the JavaScript [function] with the [arguments] with [receiver] as the
- * [:this:] context.
+ * `this` context.
  */
 Object invokeOn(function, receiver, arguments) {
   assert(isJsFunction(function));
-  assert(isNull(arguments) || isJsArray(arguments));
+  assert(arguments == null || isJsArray(arguments));
   return JS('var', r'#.apply(#, #)', function, receiver, arguments);
 }
 
@@ -668,36 +667,22 @@
 
 hasNoField(var object, var name) => !hasField(object, name);
 
-/// Returns [:true:] if [o] is a JavaScript function.
+/// Returns `true` if [o] is a JavaScript function.
 bool isJsFunction(var o) => JS('bool', r'typeof # == "function"', o);
 
-/// Returns [:true:] if [o] is a JavaScript object.
+/// Returns `true` if [o] is a JavaScript object.
 bool isJsObject(var o) => JS('bool', r"typeof # == 'object'", o);
 
 /**
- * Returns [:true:] if [o] is equal to [:null:], that is either [:null:] or
- * [:undefined:]. We use this helper to avoid generating code under the invalid
- * assumption that [o] is a Dart value.
- */
-bool isNull(var o) => JS('bool', '# == null', o);
-
-/**
- * Returns [:true:] if [o] is not equal to [:null:], that is neither [:null:]
- * nor [:undefined:].  We use this helper to avoid generating code under the
- * invalid assumption that [o] is a Dart value.
- */
-bool isNotNull(var o) => JS('bool', '# != null', o);
-
-/**
- * Returns [:true:] if the JavaScript values [s] and [t] are identical. We use
- * this helper to avoid generating code under the invalid assumption that [s]
- * and [t] are Dart values.
+ * Returns `true` if the JavaScript values [s] and [t] are identical. We use
+ * this helper instead of [identical] because `identical` needs to merge
+ * `null` and `undefined` (which we can avoid).
  */
 bool isIdentical(var s, var t) => JS('bool', '# === #', s, t);
 
 /**
- * Returns [:true:] if the JavaScript values [s] and [t] are not identical. We
- * use this helper to avoid generating code under the invalid assumption that
- * [s] and [t] are Dart values.
+ * Returns `true` if the JavaScript values [s] and [t] are not identical. We use
+ * this helper instead of [identical] because `identical` needs to merge
+ * `null` and `undefined` (which we can avoid).
  */
 bool isNotIdentical(var s, var t) => JS('bool', '# !== #', s, t);
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart b/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
index 3cc1835..d9a1e3a 100644
--- a/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/compiler/js_lib/shared/embedded_names.dart
@@ -36,3 +36,5 @@
 const CLASS_FIELDS_EXTRACTOR = 'classFieldsExtractor';
 const INSTANCE_FROM_CLASS_ID = "instanceFromClassId";
 const INITIALIZE_EMPTY_INSTANCE = "initializeEmptyInstance";
+const TYPEDEF_TYPE_PROPERTY_NAME = r"$typedefType";
+const TYPEDEF_PREDICATE_PROPERTY_NAME = r"$$isTypedef";
diff --git a/sdk/lib/_internal/compiler/js_lib/shared/runtime_data.dart b/sdk/lib/_internal/compiler/js_lib/shared/runtime_data.dart
deleted file mode 100644
index 545aa72..0000000
--- a/sdk/lib/_internal/compiler/js_lib/shared/runtime_data.dart
+++ /dev/null
@@ -1,22 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Contains encoding, decoding and detection functionality for the
-/// representation of program data at runtime.
-///
-/// This library is shared between the compiler and the runtime system.
-library dart2js.runtime_data;
-
-
-String encodeTypedefFieldDescriptor(int typeIndex) {
-  return ":$typeIndex;";
-}
-
-bool isTypedefDescriptor(String descriptor) {
-  return descriptor.startsWith(':');
-}
-
-int getTypeFromTypedef(String descriptor) {
-  return int.parse(descriptor.substring(1, descriptor.length - 1));
-}
\ No newline at end of file
diff --git a/sdk/lib/_internal/libraries.dart b/sdk/lib/_internal/libraries.dart
index 78f2060..7594c93 100644
--- a/sdk/lib/_internal/libraries.dart
+++ b/sdk/lib/_internal/libraries.dart
@@ -203,7 +203,19 @@
       "_internal/compiler/js_lib/mirror_helper.dart",
       category: "Internal",
       documented: false,
-      platforms: DART2JS_PLATFORM)
+      platforms: DART2JS_PLATFORM),
+
+  "_js_embedded_names": const LibraryInfo(
+      "_internal/compiler/js_lib/shared/embedded_names.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
+
+  "_metadata": const LibraryInfo(
+      "html/html_common/metadata.dart",
+      category: "Internal",
+      documented: false,
+      platforms: DART2JS_PLATFORM),
 };
 
 /**
diff --git a/sdk/lib/_internal/pub/lib/src/barback/barback_server.dart b/sdk/lib/_internal/pub/lib/src/barback/barback_server.dart
index 2f1b4f8..f825bd8 100644
--- a/sdk/lib/_internal/pub/lib/src/barback/barback_server.dart
+++ b/sdk/lib/_internal/pub/lib/src/barback/barback_server.dart
@@ -143,6 +143,13 @@
 
       addResult(new BarbackServerResult._failure(request.url, id, error));
       return notFound(request, asset: id);
+    }).then((response) {
+      // Allow requests of any origin to access "pub serve". This is useful for
+      // running "pub serve" in parallel with another development server. Since
+      // "pub serve" is only used as a development server and doesn't require
+      // any sort of credentials anyway, this is secure.
+      return response.change(
+          headers: const {"Access-Control-Allow-Origin": "*"});
     });
   }
 
diff --git a/sdk/lib/_internal/pub/lib/src/entrypoint.dart b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
index 5c2c845..811ae0b 100644
--- a/sdk/lib/_internal/pub/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub/lib/src/entrypoint.dart
@@ -183,6 +183,22 @@
           changed);
     }).map((package) => package.name).toSet();
 
+    if (dirExists(depsDir)) {
+      // Delete any cached dependencies that are going to be recached.
+      for (var package in dependenciesToPrecompile) {
+        deleteEntry(path.join(depsDir, package));
+      }
+
+      // Also delete any cached dependencies that should no longer be cached.
+      for (var subdir in listDir(depsDir)) {
+        var package = graph.packages[path.basename(subdir)];
+        if (package == null || package.pubspec.transformers.isEmpty ||
+            graph.isPackageMutable(package.name)) {
+          deleteEntry(subdir);
+        }
+      }
+    }
+
     if (dependenciesToPrecompile.isEmpty) return;
 
     await log.progress("Precompiling dependencies", () async {
@@ -190,11 +206,6 @@
           unionAll(dependenciesToPrecompile.map(graph.transitiveDependencies))
           .map((package) => package.name).toSet();
 
-      // TODO(nweiz): Use for/in here when
-      // https://github.com/dart-lang/async_await/issues/68 is fixed.
-      dependenciesToPrecompile.forEach((package) =>
-          deleteEntry(path.join(depsDir, package)));
-
       var environment = await AssetEnvironment.create(this, BarbackMode.DEBUG,
           packages: packagesToLoad, useDart2JS: false);
 
diff --git a/sdk/lib/_internal/pub/lib/src/global_packages.dart b/sdk/lib/_internal/pub/lib/src/global_packages.dart
index 2c06069..2a20aca 100644
--- a/sdk/lib/_internal/pub/lib/src/global_packages.dart
+++ b/sdk/lib/_internal/pub/lib/src/global_packages.dart
@@ -694,7 +694,7 @@
 # The VM exits with code 255 if the snapshot version is out-of-date.
 # If it is, we need to delete it and run "pub global" manually.
 exit_code=\$?
-if [[ \$exit_code != 255 ]]; then
+if [ \$exit_code != 255 ]; then
   exit \$exit_code
 fi
 
diff --git a/sdk/lib/_internal/pub/test/get/cache_transformed_dependency_test.dart b/sdk/lib/_internal/pub/test/get/cache_transformed_dependency_test.dart
index 613d9cb..f197805 100644
--- a/sdk/lib/_internal/pub/test/get/cache_transformed_dependency_test.dart
+++ b/sdk/lib/_internal/pub/test/get/cache_transformed_dependency_test.dart
@@ -376,6 +376,51 @@
         "lib/foo.dart: true, lib/does/not/exist.dart: false");
     endPubServe();
   });
+
+  // Regression test for issue 21810.
+  integration("decaches when the dependency is updated to something "
+      "untransformed", () {
+    servePackages((builder) {
+      builder.serveRepoPackage('barback');
+
+      builder.serve("foo", "1.2.3",
+          deps: {'barback': 'any'},
+          pubspec: {'transformers': ['foo']},
+          contents: [
+        d.dir("lib", [
+          d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")),
+          d.file("foo.dart", "final message = 'Hello!';")
+        ])
+      ]);
+
+      builder.serve("foo", "1.2.4",
+          deps: {'barback': 'any'},
+          contents: [
+        d.dir("lib", [
+          d.file("foo.dart", "final message = 'Hello!';")
+        ])
+      ]);
+    });
+
+    d.appDir({"foo": "1.2.3"}).create();
+
+    pubGet(output: contains("Precompiled foo."));
+
+    d.dir(appPath, [
+      d.dir(".pub/deps/debug/foo/lib", [
+        d.file("foo.dart", "final message = 'Goodbye!';")
+      ])
+    ]).validate();
+
+    // Upgrade to the new version of foo.
+    d.appDir({"foo": "1.2.4"}).create();
+
+    pubGet(output: isNot(contains("Precompiled foo.")));
+
+    d.dir(appPath, [
+      d.nothing(".pub/deps/debug/foo")
+    ]).validate();
+  });
 }
 
 String replaceTransformer(String input, String output) {
diff --git a/sdk/lib/_internal/pub/test/serve/supports_cross_origin_header_test.dart b/sdk/lib/_internal/pub/test/serve/supports_cross_origin_header_test.dart
new file mode 100644
index 0000000..66b7dda
--- /dev/null
+++ b/sdk/lib/_internal/pub/test/serve/supports_cross_origin_header_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.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 pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import 'utils.dart';
+
+main() {
+  initConfig();
+  integration("sends responses that allow cross-origin requests", () {
+    d.dir(appPath, [
+      d.appPubspec(),
+      d.dir("web", [d.file("index.html", "<body>")])
+    ]).create();
+
+    pubServe();
+    requestShouldSucceed("index.html", "<body>",
+        headers: containsPair("access-control-allow-origin", "*"));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/_internal/pub_generated/lib/src/barback/barback_server.dart b/sdk/lib/_internal/pub_generated/lib/src/barback/barback_server.dart
index 49bea93..24658e2 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/barback/barback_server.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/barback/barback_server.dart
@@ -144,6 +144,14 @@
 
       addResult(new BarbackServerResult._failure(request.url, id, error));
       return notFound(request, asset: id);
+    }).then((response) {
+      // Allow requests of any origin to access "pub serve". This is useful for
+      // running "pub serve" in parallel with another development server. Since
+      // "pub serve" is only used as a development server and doesn't require
+      // any sort of credentials anyway, this is secure.
+      return response.change(headers: const {
+        "Access-Control-Allow-Origin": "*"
+      });
     });
   }
 
diff --git a/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart b/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
index b9fd11f..4927ec0 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/entrypoint.dart
@@ -221,99 +221,145 @@
                 return package.name;
               })).toSet();
               join1() {
-                log.progress("Precompiling dependencies", (() {
-                  final completer0 = new Completer();
-                  scheduleMicrotask(() {
-                    try {
-                      var packagesToLoad = unionAll(
-                          dependenciesToPrecompile.map(graph.transitiveDependencies)).map(((package) {
-                        return package.name;
-                      })).toSet();
-                      dependenciesToPrecompile.forEach(((package) {
-                        return deleteEntry(path.join(depsDir, package));
-                      }));
-                      AssetEnvironment.create(
-                          this,
-                          BarbackMode.DEBUG,
-                          packages: packagesToLoad,
-                          useDart2JS: false).then((x0) {
-                        try {
-                          var environment = x0;
-                          environment.barback.errors.listen(((_) {
-                          }));
-                          environment.barback.getAllAssets().then((x1) {
-                            try {
-                              var assets = x1;
-                              waitAndPrintErrors(assets.map(((asset) {
-                                final completer0 = new Completer();
-                                scheduleMicrotask(() {
+                join2() {
+                  log.progress("Precompiling dependencies", (() {
+                    final completer0 = new Completer();
+                    scheduleMicrotask(() {
+                      try {
+                        var packagesToLoad = unionAll(
+                            dependenciesToPrecompile.map(graph.transitiveDependencies)).map(((package) {
+                          return package.name;
+                        })).toSet();
+                        AssetEnvironment.create(
+                            this,
+                            BarbackMode.DEBUG,
+                            packages: packagesToLoad,
+                            useDart2JS: false).then((x0) {
+                          try {
+                            var environment = x0;
+                            environment.barback.errors.listen(((_) {
+                            }));
+                            environment.barback.getAllAssets().then((x1) {
+                              try {
+                                var assets = x1;
+                                waitAndPrintErrors(assets.map(((asset) {
+                                  final completer0 = new Completer();
+                                  scheduleMicrotask(() {
+                                    try {
+                                      join0() {
+                                        var destPath =
+                                            path.join(depsDir, asset.id.package, path.fromUri(asset.id.path));
+                                        ensureDir(path.dirname(destPath));
+                                        createFileFromStream(
+                                            asset.read(),
+                                            destPath).then((x0) {
+                                          try {
+                                            x0;
+                                            completer0.complete();
+                                          } catch (e0, s0) {
+                                            completer0.completeError(e0, s0);
+                                          }
+                                        }, onError: completer0.completeError);
+                                      }
+                                      if (!dependenciesToPrecompile.contains(
+                                          asset.id.package)) {
+                                        completer0.complete(null);
+                                      } else {
+                                        join0();
+                                      }
+                                    } catch (e, s) {
+                                      completer0.completeError(e, s);
+                                    }
+                                  });
+                                  return completer0.future;
+                                }))).then((x2) {
                                   try {
-                                    join0() {
-                                      var destPath =
-                                          path.join(depsDir, asset.id.package, path.fromUri(asset.id.path));
-                                      ensureDir(path.dirname(destPath));
-                                      createFileFromStream(
-                                          asset.read(),
-                                          destPath).then((x0) {
-                                        try {
-                                          x0;
-                                          completer0.complete();
-                                        } catch (e0, s0) {
-                                          completer0.completeError(e0, s0);
-                                        }
-                                      }, onError: completer0.completeError);
-                                    }
-                                    if (!dependenciesToPrecompile.contains(
-                                        asset.id.package)) {
-                                      completer0.complete(null);
-                                    } else {
-                                      join0();
-                                    }
-                                  } catch (e, s) {
-                                    completer0.completeError(e, s);
+                                    x2;
+                                    log.message(
+                                        "Precompiled " +
+                                            toSentence(ordered(dependenciesToPrecompile).map(log.bold)) +
+                                            ".");
+                                    completer0.complete();
+                                  } catch (e0, s0) {
+                                    completer0.completeError(e0, s0);
                                   }
-                                });
-                                return completer0.future;
-                              }))).then((x2) {
-                                try {
-                                  x2;
-                                  log.message(
-                                      "Precompiled " +
-                                          toSentence(ordered(dependenciesToPrecompile).map(log.bold)) +
-                                          ".");
-                                  completer0.complete();
-                                } catch (e0, s0) {
-                                  completer0.completeError(e0, s0);
-                                }
-                              }, onError: completer0.completeError);
-                            } catch (e1, s1) {
-                              completer0.completeError(e1, s1);
-                            }
-                          }, onError: completer0.completeError);
-                        } catch (e2, s2) {
-                          completer0.completeError(e2, s2);
-                        }
-                      }, onError: completer0.completeError);
-                    } catch (e, s) {
-                      completer0.completeError(e, s);
+                                }, onError: completer0.completeError);
+                              } catch (e1, s1) {
+                                completer0.completeError(e1, s1);
+                              }
+                            }, onError: completer0.completeError);
+                          } catch (e2, s2) {
+                            completer0.completeError(e2, s2);
+                          }
+                        }, onError: completer0.completeError);
+                      } catch (e, s) {
+                        completer0.completeError(e, s);
+                      }
+                    });
+                    return completer0.future;
+                  })).catchError(((error) {
+                    dependenciesToPrecompile.forEach(
+                        (package) => deleteEntry(path.join(depsDir, package)));
+                    throw error;
+                  })).then((x1) {
+                    try {
+                      x1;
+                      completer0.complete();
+                    } catch (e0, s0) {
+                      completer0.completeError(e0, s0);
                     }
-                  });
-                  return completer0.future;
-                })).catchError(((error) {
-                  dependenciesToPrecompile.forEach(
-                      (package) => deleteEntry(path.join(depsDir, package)));
-                  throw error;
-                })).then((x1) {
-                  try {
-                    x1;
-                    completer0.complete();
-                  } catch (e0, s0) {
-                    completer0.completeError(e0, s0);
-                  }
-                }, onError: completer0.completeError);
+                  }, onError: completer0.completeError);
+                }
+                if (dependenciesToPrecompile.isEmpty) {
+                  completer0.complete(null);
+                } else {
+                  join2();
+                }
               }
-              if (dependenciesToPrecompile.isEmpty) {
-                completer0.complete(null);
+              if (dirExists(depsDir)) {
+                var it0 = dependenciesToPrecompile.iterator;
+                break0() {
+                  var it1 = listDir(depsDir).iterator;
+                  break1() {
+                    join1();
+                  }
+                  var trampoline1;
+                  continue1() {
+                    trampoline1 = null;
+                    if (it1.moveNext()) {
+                      var subdir = it1.current;
+                      var package = graph.packages[path.basename(subdir)];
+                      join3() {
+                        trampoline1 = continue1;
+                      }
+                      if (package == null ||
+                          package.pubspec.transformers.isEmpty ||
+                          graph.isPackageMutable(package.name)) {
+                        deleteEntry(subdir);
+                        join3();
+                      } else {
+                        join3();
+                      }
+                    } else {
+                      break1();
+                    }
+                  }
+                  trampoline1 = continue1;
+                  do trampoline1(); while (trampoline1 != null);
+                }
+                var trampoline0;
+                continue0() {
+                  trampoline0 = null;
+                  if (it0.moveNext()) {
+                    var package = it0.current;
+                    deleteEntry(path.join(depsDir, package));
+                    trampoline0 = continue0;
+                  } else {
+                    break0();
+                  }
+                }
+                trampoline0 = continue0;
+                do trampoline0(); while (trampoline0 != null);
               } else {
                 join1();
               }
diff --git a/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart b/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart
index 0419d8c..a05d2ce 100644
--- a/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart
+++ b/sdk/lib/_internal/pub_generated/lib/src/global_packages.dart
@@ -975,7 +975,7 @@
 # The VM exits with code 255 if the snapshot version is out-of-date.
 # If it is, we need to delete it and run "pub global" manually.
 exit_code=\$?
-if [[ \$exit_code != 255 ]]; then
+if [ \$exit_code != 255 ]; then
   exit \$exit_code
 fi
 
diff --git a/sdk/lib/_internal/pub_generated/test/get/cache_transformed_dependency_test.dart b/sdk/lib/_internal/pub_generated/test/get/cache_transformed_dependency_test.dart
index dd4fda8..222e974 100644
--- a/sdk/lib/_internal/pub_generated/test/get/cache_transformed_dependency_test.dart
+++ b/sdk/lib/_internal/pub_generated/test/get/cache_transformed_dependency_test.dart
@@ -404,6 +404,54 @@
         "lib/foo.dart: true, lib/does/not/exist.dart: false");
     endPubServe();
   });
+
+  // Regression test for issue 21810.
+  integration(
+      "decaches when the dependency is updated to something " "untransformed",
+      () {
+    servePackages((builder) {
+      builder.serveRepoPackage('barback');
+
+      builder.serve("foo", "1.2.3", deps: {
+        'barback': 'any'
+      }, pubspec: {
+        'transformers': ['foo']
+      },
+          contents: [
+              d.dir(
+                  "lib",
+                  [
+                      d.file("transformer.dart", replaceTransformer("Hello", "Goodbye")),
+                      d.file("foo.dart", "final message = 'Hello!';")])]);
+
+      builder.serve("foo", "1.2.4", deps: {
+        'barback': 'any'
+      },
+          contents: [d.dir("lib", [d.file("foo.dart", "final message = 'Hello!';")])]);
+    });
+
+    d.appDir({
+      "foo": "1.2.3"
+    }).create();
+
+    pubGet(output: contains("Precompiled foo."));
+
+    d.dir(
+        appPath,
+        [
+            d.dir(
+                ".pub/deps/debug/foo/lib",
+                [d.file("foo.dart", "final message = 'Goodbye!';")])]).validate();
+
+    // Upgrade to the new version of foo.
+    d.appDir({
+      "foo": "1.2.4"
+    }).create();
+
+    pubGet(output: isNot(contains("Precompiled foo.")));
+
+    d.dir(appPath, [d.nothing(".pub/deps/debug/foo")]).validate();
+  });
 }
 
 String replaceTransformer(String input, String output) {
diff --git a/sdk/lib/_internal/pub_generated/test/serve/supports_cross_origin_header_test.dart b/sdk/lib/_internal/pub_generated/test/serve/supports_cross_origin_header_test.dart
new file mode 100644
index 0000000..9059393
--- /dev/null
+++ b/sdk/lib/_internal/pub_generated/test/serve/supports_cross_origin_header_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS d.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 pub_tests;
+
+import 'package:scheduled_test/scheduled_test.dart';
+
+import '../descriptor.dart' as d;
+import '../test_pub.dart';
+import 'utils.dart';
+
+main() {
+  initConfig();
+  integration("sends responses that allow cross-origin requests", () {
+    d.dir(
+        appPath,
+        [d.appPubspec(), d.dir("web", [d.file("index.html", "<body>")])]).create();
+
+    pubServe();
+    requestShouldSucceed(
+        "index.html",
+        "<body>",
+        headers: containsPair("access-control-allow-origin", "*"));
+    endPubServe();
+  });
+}
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index a2289fd..54ef35f 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -10066,19 +10066,12 @@
 
 }
 
-// TODO(jacobr): this is an inefficient implementation but it is hard to see
-// a better option given that we cannot quite force NodeList to be an
-// ElementList as there are valid cases where a NodeList JavaScript object
-// contains Node objects that are not Elements.
-class _FrozenElementList<T extends Element> extends ListBase<T>
-    implements ElementList<T>, NodeListWrapper {
+// Wrapper over an immutable NodeList to make it implement ElementList<Element>.
+class _FrozenElementList extends ListBase
+    implements ElementList, NodeListWrapper {
   final List<Node> _nodeList;
-  // The subset of _nodeList that are Elements.
-  List<Element> _elementList;
 
-  _FrozenElementList._wrap(this._nodeList) {
-    _elementList = _nodeList.where((e) => e is Element).toList();
-  }
+  _FrozenElementList._wrap(this._nodeList);
 
   int get length => _nodeList.length;
 
@@ -10106,22 +10099,22 @@
 
   Element get single => _nodeList.single;
 
-  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
+  CssClassSet get classes => new _MultiElementCssClassSet(this);
 
   CssStyleDeclarationBase get style =>
-      new _CssStyleDeclarationSet(_elementList);
+      new _CssStyleDeclarationSet(this);
 
   void set classes(Iterable<String> value) {
-    _elementList.forEach((e) => e.classes = value);
+    _nodeList.forEach((e) => e.classes = value);
   }
 
-  CssRect get contentEdge => new _ContentCssListRect(_elementList);
+  CssRect get contentEdge => new _ContentCssListRect(this);
 
-  CssRect get paddingEdge => _elementList.first.paddingEdge;
+  CssRect get paddingEdge => this.first.paddingEdge;
 
-  CssRect get borderEdge => _elementList.first.borderEdge;
+  CssRect get borderEdge => this.first.borderEdge;
 
-  CssRect get marginEdge => _elementList.first.marginEdge;
+  CssRect get marginEdge => this.first.marginEdge;
 
   List<Node> get rawList => _nodeList;
 
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 601400b..173e527 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -11089,19 +11089,12 @@
 
 }
 
-// TODO(jacobr): this is an inefficient implementation but it is hard to see
-// a better option given that we cannot quite force NodeList to be an
-// ElementList as there are valid cases where a NodeList JavaScript object
-// contains Node objects that are not Elements.
-class _FrozenElementList<T extends Element> extends ListBase<T>
-    implements ElementList<T>, NodeListWrapper {
+// Wrapper over an immutable NodeList to make it implement ElementList<Element>.
+class _FrozenElementList extends ListBase
+    implements ElementList, NodeListWrapper {
   final List<Node> _nodeList;
-  // The subset of _nodeList that are Elements.
-  List<Element> _elementList;
 
-  _FrozenElementList._wrap(this._nodeList) {
-    _elementList = _nodeList.where((e) => e is Element).toList();
-  }
+  _FrozenElementList._wrap(this._nodeList);
 
   int get length => _nodeList.length;
 
@@ -11129,22 +11122,22 @@
 
   Element get single => _nodeList.single;
 
-  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
+  CssClassSet get classes => new _MultiElementCssClassSet(this);
 
   CssStyleDeclarationBase get style =>
-      new _CssStyleDeclarationSet(_elementList);
+      new _CssStyleDeclarationSet(this);
 
   void set classes(Iterable<String> value) {
-    _elementList.forEach((e) => e.classes = value);
+    _nodeList.forEach((e) => e.classes = value);
   }
 
-  CssRect get contentEdge => new _ContentCssListRect(_elementList);
+  CssRect get contentEdge => new _ContentCssListRect(this);
 
-  CssRect get paddingEdge => _elementList.first.paddingEdge;
+  CssRect get paddingEdge => this.first.paddingEdge;
 
-  CssRect get borderEdge => _elementList.first.borderEdge;
+  CssRect get borderEdge => this.first.borderEdge;
 
-  CssRect get marginEdge => _elementList.first.marginEdge;
+  CssRect get marginEdge => this.first.marginEdge;
 
   List<Node> get rawList => _nodeList;
 
@@ -31426,10 +31419,10 @@
     if ((blob_OR_source_OR_stream is Blob || blob_OR_source_OR_stream == null)) {
       return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaStream)) {
+    if ((blob_OR_source_OR_stream is MediaSource)) {
       return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
     }
-    if ((blob_OR_source_OR_stream is MediaSource)) {
+    if ((blob_OR_source_OR_stream is MediaStream)) {
       return _blink.BlinkURL.instance.createObjectURL_Callback_1_(blob_OR_source_OR_stream);
     }
     throw new ArgumentError("Incorrect number or type of arguments");
diff --git a/sdk/lib/html/html_common/html_common_dart2js.dart b/sdk/lib/html/html_common/html_common_dart2js.dart
index 1cd0cb3..e823008 100644
--- a/sdk/lib/html/html_common/html_common_dart2js.dart
+++ b/sdk/lib/html/html_common/html_common_dart2js.dart
@@ -12,8 +12,8 @@
 import 'dart:_foreign_helper' show JS;
 import 'dart:_interceptors' show Interceptor, JSExtendableArray;
 
-import 'metadata.dart';
-export 'metadata.dart';
+import 'dart:_metadata';
+export 'dart:_metadata';
 
 part 'css_class_set.dart';
 part 'conversions.dart';
diff --git a/site/try/poi/poi.dart b/site/try/poi/poi.dart
index b8f530c..7c023d0 100644
--- a/site/try/poi/poi.dart
+++ b/site/try/poi/poi.dart
@@ -18,6 +18,7 @@
     reuseCompiler;
 
 import 'package:dart2js_incremental/library_updater.dart' show
+    IncrementalCompilerContext,
     LibraryUpdater;
 
 import 'package:compiler/src/source_file_provider.dart' show
@@ -406,8 +407,10 @@
   }
 
   Future<Compiler> invokeReuseCompiler() {
+    var context = new IncrementalCompilerContext();
     updater = new LibraryUpdater(
-        cachedCompiler, inputProvider, script, printWallClock, printVerbose);
+        cachedCompiler, inputProvider, printWallClock, printVerbose, context);
+    context.registerUriWithUpdates([script]);
     return reuseCompiler(
         diagnosticHandler: handler,
         inputProvider: inputProvider,
@@ -431,7 +434,7 @@
     if (!isCompiler) {
       newCompiler.enqueuerFilter = new ScriptOnlyFilter(script);
     }
-    return runPoiInternal(newCompiler, sw, updater, position);
+    return runPoiInternal(newCompiler, sw, updater, script, position);
   });
 }
 
@@ -439,6 +442,7 @@
     Compiler newCompiler,
     Stopwatch sw,
     LibraryUpdater updater,
+    Uri uri,
     int position) {
   bool isFullCompile = cachedCompiler != newCompiler;
   cachedCompiler = newCompiler;
@@ -464,7 +468,7 @@
       return !cachedCompiler.compilationFailed;
     });
   } else {
-    compilation = cachedCompiler.run(updater.uri);
+    compilation = cachedCompiler.run(uri);
   }
 
   return compilation.then((success) {
diff --git a/tests/co19/co19-dart2dart.status b/tests/co19/co19-dart2dart.status
index 5553cf7..8be59a6 100644
--- a/tests/co19/co19-dart2dart.status
+++ b/tests/co19/co19-dart2dart.status
@@ -30,7 +30,6 @@
 Language/12_Expressions/12_Instance_Creation/1_New_A04_t02: RuntimeError # co19-roll r607: Please triage this failure
 Language/12_Expressions/17_Getter_Invocation_A07_t02: Pass, RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Invocation/memberName_A01_t01: Pass, RuntimeError # co18-roll r607: Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # co19-roll r607: Please triage this failure
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # co19-roll r607: Please triage this failure
 
@@ -47,19 +46,11 @@
 Language/07_Classes/3_Setters_A04_t07: Fail # inherited from VM
 Language/12_Expressions/01_Constants_A03_t01: Fail # Issue 13652
 
-LibTest/core/Match/operator_subscript_A01_t01: Fail # inherited from VM
-LibTest/core/Match/operator_subscript_A01_t01: Fail, OK # co19 issue 294
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # inherited from VM
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail, OK # co19 issue 294
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # inherited from VM
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail
 LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # inherited from VM
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # inherited from VM
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A03_t01: Fail # inherited from VM
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A03_t01: Fail, OK # co19 issue 294
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: Fail # issue 12508
 LibTest/core/RegExp/firstMatch_A01_t01: Fail, OK # co19 issue 294
 LibTest/core/int/operator_left_shift_A01_t02: Fail, OK # co19 issue 129
 LibTest/core/int/toRadixString_A01_t01: Fail # inherited from VM
@@ -101,7 +92,6 @@
 Language/12_Expressions/22_Equality_A01_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/22_Equality_A05_t01: fail # co19-roll r546: Please triage this failure
 Language/12_Expressions/30_Identifier_Reference_A02_t01: fail # co19-roll r546: Please triage this failure
-Language/13_Statements/02_Expression_Statements_A01_t08: fail # co19-roll r546: Please triage this failure
 Language/13_Statements/09_Switch_A01_t02: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # co19-roll r546: Please triage this failure
 Language/14_Libraries_and_Scripts/1_Imports_A03_t09: fail # co19-roll r546: Please triage this failure
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index fcc4f77..934fc87 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -27,6 +27,7 @@
 Language/07_Classes/07_Classes_A13_t09: Fail # Missing CT error on member with same name a type parameter
 Language/03_Overview/1_Scoping_A02_t05: CompileTimeError # Issue 21072
 Language/03_Overview/1_Scoping_A02_t06: CompileTimeError # Issue 21072
+LibTest/async/Stream/listen_A05_t01: RuntimeError # https://code.google.com/p/co19/issues/detail?id=736 (see also dartbug.com/15171)
 LibTest/core/double/INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: RuntimeError # TODO(ahe): Please triage this failure.
 LibTest/typed_data/ByteData/getFloat32_A02_t02: fail # co19-roll r569: Please triage this failure
@@ -438,7 +439,6 @@
 Language/12_Expressions/22_Equality_A05_t01: fail # Issue 21137
 Language/12_Expressions/30_Identifier_Reference_A02_t01: fail # Issue 21154
 Language/12_Expressions/33_Type_Cast_A02_t03: fail # co19 issue 716
-Language/13_Statements/02_Expression_Statements_A01_t08: fail # Issue 21155
 Language/13_Statements/10_Rethrow_A01_t04: fail # co19 issue 719
 Language/13_Statements/10_Rethrow_A01_t05: fail # co19 issue 719
 Language/14_Libraries_and_Scripts/1_Imports_A03_t08: fail # Issue 21171
@@ -450,6 +450,8 @@
 Language/15_Types/4_Interface_Types_A11_t01: crash # Issue 21174
 Language/15_Types/4_Interface_Types_A11_t02: crash # Issue 21174
 Language/15_Types/4_Interface_Types_A12_t10: fail # co19 issue 716
+LibTest/convert/JsonCodec/encode_A01_t01: RuntimeError # code.google.com/p/co19/issues/detail?id=735
+LibTest/convert/JsonCodec/encode_A01_t02: RuntimeError # code.google.com/p/co19/issues/detail?id=735
 LibTest/core/DateTime/DateTime_A01_t03: fail # co19-roll r546: Please triage this failure
 LibTest/core/DateTime/parse_A03_t01: fail # co19-roll r546: Please triage this failure
 LibTest/core/Duration/operator_div_A01_t01: fail # co19-roll r546: Please triage this failure
@@ -628,9 +630,6 @@
 LibTest/math/pow_A16_t01: fail # co19-roll r587: Please triage this failure
 
 LibTest/async/Stream/handleError_A04_t01: RuntimeError # co19-roll r641: Please triage this failure
-LibTest/async/Stream/listen_A05_t01: RuntimeError # co19-roll r641: Please triage this failure
-LibTest/convert/JsonCodec/encode_A01_t01: RuntimeError # co19-roll r641: Please triage this failure
-LibTest/convert/JsonCodec/encode_A01_t02: RuntimeError # co19-roll r641: Please triage this failure
 
 [ $compiler == dart2js && $runtime == d8 && $system == windows ]
 LibTest/async/DeferredLibrary/*: Skip # Issue 17458
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 20b65f1..32b96fa 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -5,17 +5,12 @@
 
 [ $compiler == none && ($runtime == vm || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A03_t01: Fail # Issue 12508
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Atom_A02_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_DecimalEscape_A01_t02: Fail # Issue 12508
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterEscape_A06_t02: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 12508
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 12508
-LibTest/core/RegExp/Pattern_semantics/firstMatch_Term_A04_t01: RuntimeError # Issue 12508
 
-LibTest/core/Match/operator_subscript_A01_t01: Fail # Issue 12508
 LibTest/core/RegExp/firstMatch_A01_t01: Fail # Issue 12508
 LibTest/core/int/toRadixString_A01_t01: Fail # co19 issue 492
 
@@ -47,7 +42,6 @@
 LibTest/isolate/Isolate/spawnUri_A02_t04: Skip # Dart issue 15974
 LibTest/isolate/Isolate/spawn_A02_t02: RuntimeError # Dart issue 15617
 
-LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # Issue 12508
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
 
diff --git a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
index 7392142..3ec0c34 100644
--- a/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
+++ b/tests/compiler/dart2js/backend_dart/dart_backend_test.dart
@@ -214,7 +214,7 @@
   // Maybe typedef should be included in the result too, but it
   // works fine without it.
   testDart2Dart('''
-typedef void foofunc(arg);
+typedef void foofunc(_0);
 main() {
   new A((arg) {});
 }
@@ -600,7 +600,10 @@
   final compiler;
   DynoMap(this.compiler);
 
-  ElementAst operator[](Element element) => new ElementAst(element);
+  ElementAst operator[](AstElement element) {
+    return new ElementAst(element.resolvedAst.node,
+                          element.resolvedAst.elements);
+  }
 
   noSuchMethod(Invocation invocation) => throw 'unimplemented method';
 }
@@ -669,13 +672,13 @@
 }
 ''';
   var expectedResult = '''
-typedef void MyFunction<T_B extends num>(T_B arg);
+typedef void MyFunction<T_B extends num>(T_B _0);
 class T {}
 class B<T_B> {}
 class A<T_B> extends B<T_B> {
   T_B f;
 }
-typedef void MyFunction_A<T_B extends num>(T_B arg);
+typedef void MyFunction_A<T_B extends num>(T_B _0);
 class T_A {}
 class B_A<T_B> {}
 class A_A<T_B> extends B_A<T_B> {
diff --git a/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart b/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
index cb158e78..3f67ca5 100644
--- a/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
+++ b/tests/compiler/dart2js/backend_dart/opt_constprop_test.dart
@@ -28,29 +28,30 @@
 //  }
 
 String CP1_IN = """
-(FunctionDefinition main (return) (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 1)))
   (LetCont (k0 v2)
-    (LetCont (k1) (LetPrim v3 (Constant IntConstant(2)))
+    (LetCont (k1) (LetPrim v3 (Constant (Int 2)))
       (InvokeContinuation return v3))
-    (LetCont (k2) (LetPrim v4 (Constant IntConstant(3)))
+    (LetCont (k2) (LetPrim v4 (Constant (Int 3)))
       (InvokeContinuation return v4))
     (Branch (IsTrue v2) k1 k2))
   (InvokeMethod v0 == v1 k0))
 """;
 String CP1_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 1)))
   (LetCont (k0 v2)
     (LetCont (k1)
-      (LetPrim v3 (Constant IntConstant(2)))
+      (LetPrim v3 (Constant (Int 2)))
       (InvokeContinuation return v3))
     (LetCont (k2)
-      (LetPrim v4 (Constant IntConstant(3)))
+      (LetPrim v4 (Constant (Int 3)))
       (InvokeContinuation return v4))
     (InvokeContinuation k1 ))
-  (LetPrim v5 (Constant BoolConstant(true)))
+  (LetPrim v5 (Constant (Bool true)))
   (InvokeContinuation k0 v5))
 """;
 
@@ -70,86 +71,87 @@
 //  }
 
 String CP2_IN = """
-(FunctionDefinition main (return) (LetPrim v0 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
   (LetCont* (k0)
-    (LetCont (k1) (LetPrim v1 (Constant IntConstant(42)))
+    (LetCont (k1) (LetPrim v1 (Constant (Int 42)))
       (InvokeContinuation return v1))
-    (LetCont (k2) (LetPrim v2 (Constant BoolConstant(false)))
+    (LetCont (k2) (LetPrim v2 (Constant (Bool false)))
       (LetCont (k3 v3)
         (LetCont (k4) (InvokeContinuation return v0))
-        (LetCont (k5) (LetPrim v4 (Constant BoolConstant(true)))
+        (LetCont (k5) (LetPrim v4 (Constant (Bool true)))
           (LetCont (k6 v5)
             (LetCont (k7) (InvokeContinuation return v0))
             (LetCont (k8) (InvokeContinuation* k0))
             (Branch (IsTrue v5) k7 k8))
-          (LetCont (k9) (LetPrim v6 (Constant IntConstant(1)))
+          (LetCont (k9) (LetPrim v6 (Constant (Int 1)))
             (LetCont (k10 v7)
-              (LetCont (k11) (LetPrim v8 (Constant BoolConstant(true)))
+              (LetCont (k11) (LetPrim v8 (Constant (Bool true)))
                 (InvokeContinuation k6 v8))
-              (LetCont (k12) (LetPrim v9 (Constant BoolConstant(false)))
+              (LetCont (k12) (LetPrim v9 (Constant (Bool false)))
                 (InvokeContinuation k6 v9))
               (Branch (IsTrue v7) k11 k12))
             (InvokeMethod v0 == v6 k10))
-          (LetCont (k13) (LetPrim v10 (Constant BoolConstant(false)))
+          (LetCont (k13) (LetPrim v10 (Constant (Bool false)))
             (InvokeContinuation k6 v10))
           (Branch (IsTrue v4) k9 k13))
         (Branch (IsTrue v3) k4 k5))
-      (LetCont (k14) (LetPrim v11 (Constant BoolConstant(true)))
+      (LetCont (k14) (LetPrim v11 (Constant (Bool true)))
         (InvokeContinuation k3 v11))
-      (LetCont (k15) (LetPrim v12 (Constant BoolConstant(false)))
-        (LetCont (k16) (LetPrim v13 (Constant BoolConstant(true)))
+      (LetCont (k15) (LetPrim v12 (Constant (Bool false)))
+        (LetCont (k16) (LetPrim v13 (Constant (Bool true)))
           (InvokeContinuation k3 v13))
-        (LetCont (k17) (LetPrim v14 (Constant BoolConstant(false)))
+        (LetCont (k17) (LetPrim v14 (Constant (Bool false)))
           (InvokeContinuation k3 v14))
         (Branch (IsTrue v12) k16 k17))
       (Branch (IsTrue v2) k14 k15))
-    (LetPrim v15 (Constant BoolConstant(true)))
+    (LetPrim v15 (Constant (Bool true)))
     (Branch (IsTrue v15) k2 k1))
   (InvokeContinuation k0))
 """;
 String CP2_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
   (LetCont* (k0)
-    (LetCont (k1) (LetPrim v1 (Constant IntConstant(42)))
+    (LetCont (k1) (LetPrim v1 (Constant (Int 42)))
       (InvokeContinuation return v1))
     (LetCont (k2)
-      (LetPrim v2 (Constant BoolConstant(false)))
+      (LetPrim v2 (Constant (Bool false)))
       (LetCont (k3 v3)
         (LetCont (k4) (InvokeContinuation return v0))
         (LetCont (k5)
-          (LetPrim v4 (Constant BoolConstant(true)))
+          (LetPrim v4 (Constant (Bool true)))
           (LetCont (k6 v5)
             (LetCont (k7) (InvokeContinuation return v0))
             (LetCont (k8) (InvokeContinuation* k0 ))
             (InvokeContinuation k7 ))
           (LetCont (k9)
-            (LetPrim v6 (Constant IntConstant(1)))
+            (LetPrim v6 (Constant (Int 1)))
             (LetCont (k10 v7)
               (LetCont (k11)
-                (LetPrim v8 (Constant BoolConstant(true)))
+                (LetPrim v8 (Constant (Bool true)))
                 (InvokeContinuation k6 v8))
-              (LetCont (k12) (LetPrim v9 (Constant BoolConstant(false)))
+              (LetCont (k12) (LetPrim v9 (Constant (Bool false)))
                 (InvokeContinuation k6 v9))
               (InvokeContinuation k11 ))
-            (LetPrim v10 (Constant BoolConstant(true)))
+            (LetPrim v10 (Constant (Bool true)))
             (InvokeContinuation k10 v10))
-          (LetCont (k13) (LetPrim v11 (Constant BoolConstant(false)))
+          (LetCont (k13) (LetPrim v11 (Constant (Bool false)))
             (InvokeContinuation k6 v11))
           (InvokeContinuation k9 ))
         (InvokeContinuation k5 ))
-      (LetCont (k14) (LetPrim v12 (Constant BoolConstant(true)))
+      (LetCont (k14) (LetPrim v12 (Constant (Bool true)))
         (InvokeContinuation k3 v12))
       (LetCont (k15)
-        (LetPrim v13 (Constant BoolConstant(false)))
-        (LetCont (k16) (LetPrim v14 (Constant BoolConstant(true)))
+        (LetPrim v13 (Constant (Bool false)))
+        (LetCont (k16) (LetPrim v14 (Constant (Bool true)))
           (InvokeContinuation k3 v14))
         (LetCont (k17)
-          (LetPrim v15 (Constant BoolConstant(false)))
+          (LetPrim v15 (Constant (Bool false)))
           (InvokeContinuation k3 v15))
         (InvokeContinuation k17 ))
       (InvokeContinuation k15 ))
-    (LetPrim v16 (Constant BoolConstant(true)))
+    (LetPrim v16 (Constant (Bool true)))
     (InvokeContinuation k2 ))
   (InvokeContinuation k0 ))
 """;
@@ -166,10 +168,11 @@
 //  }
 
 String CP3_IN = """
-(FunctionDefinition main ( return) (LetPrim v0 (Constant IntConstant(1)))
-  (LetCont (k0 v1) (LetPrim v2 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetCont (k0 v1) (LetPrim v2 (Constant (Int 1)))
     (LetCont (k1 v3)
-      (LetCont (k2) (LetPrim v4 (Constant IntConstant(42)))
+      (LetCont (k2) (LetPrim v4 (Constant (Int 42)))
         (InvokeContinuation return v4))
       (LetCont (k3) (InvokeContinuation return v1))
       (Branch (IsTrue v3) k2 k3))
@@ -181,29 +184,29 @@
 // Addition.
 
 String CP4_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(2)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 2)))
   (LetCont (k0 v2)
      (InvokeContinuation return v2))
   (InvokeMethod v0 + v1 k0))
 """;
 String CP4_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(2)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 2)))
   (LetCont (k0 v2)
      (InvokeContinuation return v2))
-  (LetPrim v3 (Constant IntConstant(3)))
+  (LetPrim v3 (Constant (Int 3)))
   (InvokeContinuation k0 v3))
 """;
 
 // Array access operator (no optimization).
 
 String CP5_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(2)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 2)))
   (LetCont (k0 v2)
      (InvokeContinuation return v2))
   (InvokeMethod v0 [] v1 k0))
@@ -213,32 +216,32 @@
 // Division by 0.
 
 String CP6_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 0)))
   (LetCont (k0 v2)
      (InvokeContinuation return v2))
   (InvokeMethod v0 / v1 k0))
 """;
 String CP6_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 0)))
   (LetCont (k0 v2)
      (InvokeContinuation return v2))
-  (LetPrim v3 (Constant DoubleConstant(Infinity)))
+  (LetPrim v3 (Constant (Double Infinity)))
   (InvokeContinuation k0 v3))
 """;
 
 // Concatenate strings.
 
 String CP7_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant StringConstant("b")))
-  (LetPrim v1 (Constant StringConstant("d")))
-  (LetPrim v2 (Constant StringConstant("a")))
-  (LetPrim v3 (Constant StringConstant("c")))
-  (LetPrim v4 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (String "b")))
+  (LetPrim v1 (Constant (String "d")))
+  (LetPrim v2 (Constant (String "a")))
+  (LetPrim v3 (Constant (String "c")))
+  (LetPrim v4 (Constant (String "")))
   (LetCont (k0 v5)
     (LetCont (k1 v6)
       (InvokeContinuation return v6))
@@ -246,17 +249,17 @@
   (ConcatenateStrings v2 v0 v3 v1 v4 k0))
 """;
 String CP7_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant StringConstant("b")))
-  (LetPrim v1 (Constant StringConstant("d")))
-  (LetPrim v2 (Constant StringConstant("a")))
-  (LetPrim v3 (Constant StringConstant("c")))
-  (LetPrim v4 (Constant StringConstant("")))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (String "b")))
+  (LetPrim v1 (Constant (String "d")))
+  (LetPrim v2 (Constant (String "a")))
+  (LetPrim v3 (Constant (String "c")))
+  (LetPrim v4 (Constant (String "")))
   (LetCont (k0 v5)
     (LetCont (k1 v6)
       (InvokeContinuation return v6))
     (InvokeMethod v5 length k1))
-  (LetPrim v7 (Constant StringConstant("abcd")))
+  (LetPrim v7 (Constant (String "abcd")))
   (InvokeContinuation k0 v7))
 """;
 
@@ -266,12 +269,12 @@
 // Simple branch removal.
 
 String CP8_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 1)))
   (LetCont (k0 v2)
     (LetCont (k1)
-      (LetPrim v3 (Constant IntConstant(42)))
+      (LetPrim v3 (Constant (Int 42)))
       (InvokeContinuation return v3))
     (LetCont (k2)
       (InvokeContinuation return v0))
@@ -279,79 +282,79 @@
   (InvokeMethod v0 == v1 k0))
 """;
 String CP8_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
-  (LetPrim v1 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
+  (LetPrim v1 (Constant (Int 1)))
   (LetCont (k0 v2)
-    (LetCont (k1) (LetPrim v3 (Constant IntConstant(42)))
+    (LetCont (k1) (LetPrim v3 (Constant (Int 42)))
       (InvokeContinuation return v3))
     (LetCont (k2) (InvokeContinuation return v0))
     (InvokeContinuation k1 ))
-  (LetPrim v4 (Constant BoolConstant(true)))
+  (LetPrim v4 (Constant (Bool true)))
   (InvokeContinuation k0 v4))
 """;
 
 // While loop.
 
 String CP9_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
   (LetCont* (k0 v1)
     (LetCont (k1)
       (InvokeContinuation return v1))
     (LetCont (k2)
-      (LetPrim v2 (Constant IntConstant(1)))
+      (LetPrim v2 (Constant (Int 1)))
       (LetCont (k3 v3)
         (LetCont (k4 v4)
           (LetCont (k5)
-            (LetPrim v5 (Constant IntConstant(42)))
+            (LetPrim v5 (Constant (Int 42)))
             (InvokeContinuation return v5))
           (LetCont (k6)
-            (LetPrim v6 (Constant IntConstant(1)))
+            (LetPrim v6 (Constant (Int 1)))
             (LetCont (k7 v7)
               (InvokeContinuation* k0 v7))
             (InvokeMethod v1 + v6 k7))
           (Branch (IsTrue v4) k5 k6))
         (LetCont (k8)
-          (LetPrim v8 (Constant BoolConstant(false)))
+          (LetPrim v8 (Constant (Bool false)))
           (InvokeContinuation k4 v8))
         (LetCont (k9)
-          (LetPrim v9 (Constant BoolConstant(true)))
+          (LetPrim v9 (Constant (Bool true)))
           (InvokeContinuation k4 v9))
         (Branch (IsTrue v3) k8 k9))
       (InvokeMethod v1 == v2 k3))
-    (LetPrim v10 (Constant BoolConstant(true)))
+    (LetPrim v10 (Constant (Bool true)))
     (Branch (IsTrue v10) k2 k1))
   (InvokeContinuation k0 v0))
 """;
 String CP9_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(1)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 1)))
   (LetCont* (k0 v1)
     (LetCont (k1)
       (InvokeContinuation return v1))
     (LetCont (k2)
-      (LetPrim v2 (Constant IntConstant(1)))
+      (LetPrim v2 (Constant (Int 1)))
       (LetCont (k3 v3)
         (LetCont (k4 v4)
           (LetCont (k5)
-            (LetPrim v5 (Constant IntConstant(42)))
+            (LetPrim v5 (Constant (Int 42)))
             (InvokeContinuation return v5))
           (LetCont (k6)
-            (LetPrim v6 (Constant IntConstant(1)))
+            (LetPrim v6 (Constant (Int 1)))
             (LetCont (k7 v7)
               (InvokeContinuation* k0 v7))
             (InvokeMethod v1 + v6 k7))
           (Branch (IsTrue v4) k5 k6))
         (LetCont (k8)
-          (LetPrim v8 (Constant BoolConstant(false)))
+          (LetPrim v8 (Constant (Bool false)))
           (InvokeContinuation k4 v8))
         (LetCont (k9)
-          (LetPrim v9 (Constant BoolConstant(true)))
+          (LetPrim v9 (Constant (Bool true)))
           (InvokeContinuation k4 v9))
         (Branch (IsTrue v3) k8 k9))
       (InvokeMethod v1 == v2 k3))
-    (LetPrim v10 (Constant BoolConstant(true)))
+    (LetPrim v10 (Constant (Bool true)))
     (InvokeContinuation k2 ))
   (InvokeContinuation k0 v0))
 """;
@@ -365,23 +368,23 @@
 //  }
 
 String CP10_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont* (k0 v1)
     (LetCont (k1)
-      (LetPrim v2 (Constant NullConstant))
+      (LetPrim v2 (Constant (Null)))
       (InvokeContinuation return v2))
     (LetCont (k2)
-      (LetPrim v3 (Constant IntConstant(42)))
+      (LetPrim v3 (Constant (Int 42)))
       (LetCont (k3 v4)
         (LetCont (k4 v5)
-          (LetPrim v6 (Constant IntConstant(1)))
+          (LetPrim v6 (Constant (Int 1)))
           (LetCont (k5 v7)
             (InvokeContinuation* k0 v7))
           (InvokeMethod v1 + v6 k5))
         (InvokeStatic print v4 k4))
       (InvokeMethod v3 + v1 k3))
-    (LetPrim v8 (Constant IntConstant(2)))
+    (LetPrim v8 (Constant (Int 2)))
     (LetCont (k6 v9)
       (Branch (IsTrue v9) k2 k1))
     (InvokeMethod v1 < v8 k6))
@@ -404,8 +407,11 @@
   return compiler.init().then((_) {
     final unstringifier = new SExpressionUnstringifier();
     final stringifier   = new SExpressionStringifier();
-    final optimizer     = new ConstantPropagator(
-        compiler, dart2js.DART_CONSTANT_SYSTEM);
+    final optimizer     = new TypePropagator(
+        compiler.types,
+        dart2js.DART_CONSTANT_SYSTEM,
+        new UnitTypeSystem(),
+        compiler.internalError);
 
     final f = unstringifier.unstringify(input);
     optimizer.rewrite(f);
diff --git a/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart b/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
index 1d84848..e45b537 100644
--- a/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
+++ b/tests/compiler/dart2js/backend_dart/opt_redundant_phi_test.dart
@@ -19,38 +19,40 @@
 // }
 
 String READ_IN_LOOP_IN = """
-(FunctionDefinition main (return) (LetPrim v0 (Constant IntConstant(42)))
-  (LetPrim v1 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 42)))
+  (LetPrim v1 (Constant (Int 0)))
   (LetCont* (k0 v2 v3)
-    (LetCont (k1) (LetPrim v4 (Constant NullConstant))
+    (LetCont (k1) (LetPrim v4 (Constant (Null)))
       (InvokeContinuation return v4))
     (LetCont (k2)
       (LetCont (k3 v5)
-        (LetCont (k4 v6) (LetPrim v7 (Constant IntConstant(1)))
+        (LetCont (k4 v6) (LetPrim v7 (Constant (Int 1)))
           (LetCont (k5 v8) (InvokeContinuation* k0 v2 v8))
           (InvokeMethod v3 + v7 k5))
         (InvokeStatic print v5 k4))
       (InvokeMethod v2 toString k3))
-    (LetPrim v9 (Constant IntConstant(2)))
+    (LetPrim v9 (Constant (Int 2)))
     (LetCont (k6 v10) (Branch (IsTrue v10) k2 k1))
     (InvokeMethod v3 < v9 k6))
   (InvokeContinuation k0 v0 v1))
 """;
 
 String READ_IN_LOOP_OUT = """
-(FunctionDefinition main ( return) (LetPrim v0 (Constant IntConstant(42)))
-  (LetPrim v1 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 42)))
+  (LetPrim v1 (Constant (Int 0)))
   (LetCont* (k0 v2)
-    (LetCont (k1) (LetPrim v3 (Constant NullConstant))
+    (LetCont (k1) (LetPrim v3 (Constant (Null)))
       (InvokeContinuation return v3))
     (LetCont (k2)
       (LetCont (k3 v4)
-        (LetCont (k4 v5) (LetPrim v6 (Constant IntConstant(1)))
+        (LetCont (k4 v5) (LetPrim v6 (Constant (Int 1)))
           (LetCont (k5 v7) (InvokeContinuation* k0 v7))
           (InvokeMethod v2 + v6 k5))
         (InvokeStatic print v4 k4))
       (InvokeMethod v0 toString k3))
-    (LetPrim v8 (Constant IntConstant(2)))
+    (LetPrim v8 (Constant (Int 2)))
     (LetCont (k6 v9) (Branch (IsTrue v9) k2 k1))
     (InvokeMethod v2 < v8 k6))
   (InvokeContinuation k0 v1))
@@ -72,66 +74,68 @@
 // are removed from k5, and only then can k0 be optimized as well.
 
 const String INNER_LOOP_IN = """
-(FunctionDefinition main (return) (LetPrim v0 (Constant IntConstant(42)))
-  (LetPrim v1 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 42)))
+  (LetPrim v1 (Constant (Int 0)))
   (LetCont* (k0 v2 v3)
     (LetCont (k1)
       (LetCont (k2 v4)
-        (LetCont (k3 v5) (LetPrim v6 (Constant NullConstant))
+        (LetCont (k3 v5) (LetPrim v6 (Constant (Null)))
           (InvokeContinuation return v6))
         (InvokeStatic print v4 k3))
       (InvokeMethod v2 toString k2))
-    (LetCont (k4) (LetPrim v7 (Constant IntConstant(0)))
+    (LetCont (k4) (LetPrim v7 (Constant (Int 0)))
       (LetCont* (k5 v8 v9 v10)
-        (LetCont (k6) (LetPrim v11 (Constant IntConstant(1)))
+        (LetCont (k6) (LetPrim v11 (Constant (Int 1)))
           (LetCont (k7 v12) (InvokeContinuation* k0 v8 v12))
           (InvokeMethod v9 + v11 k7))
         (LetCont (k8)
           (LetCont (k9 v13)
-            (LetCont (k10 v14) (LetPrim v15 (Constant IntConstant(1)))
+            (LetCont (k10 v14) (LetPrim v15 (Constant (Int 1)))
               (LetCont (k11 v16)
                 (InvokeContinuation* k5 v8 v9 v16))
               (InvokeMethod v10 + v15 k11))
             (InvokeStatic print v13 k10))
           (InvokeMethod v9 toString k9))
-        (LetPrim v17 (Constant IntConstant(2)))
+        (LetPrim v17 (Constant (Int 2)))
         (LetCont (k12 v18) (Branch (IsTrue v18) k8 k6))
         (InvokeMethod v10 < v17 k12))
       (InvokeContinuation k5 v2 v3 v7))
-    (LetPrim v19 (Constant IntConstant(2)))
+    (LetPrim v19 (Constant (Int 2)))
     (LetCont (k13 v20) (Branch (IsTrue v20) k4 k1))
     (InvokeMethod v3 < v19 k13))
   (InvokeContinuation k0 v0 v1))
 """;
 
 const String INNER_LOOP_OUT = """
-(FunctionDefinition main ( return) (LetPrim v0 (Constant IntConstant(42)))
-  (LetPrim v1 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 42)))
+  (LetPrim v1 (Constant (Int 0)))
   (LetCont* (k0 v2)
     (LetCont (k1)
       (LetCont (k2 v3)
-        (LetCont (k3 v4) (LetPrim v5 (Constant NullConstant))
+        (LetCont (k3 v4) (LetPrim v5 (Constant (Null)))
           (InvokeContinuation return v5))
         (InvokeStatic print v3 k3))
       (InvokeMethod v0 toString k2))
-    (LetCont (k4) (LetPrim v6 (Constant IntConstant(0)))
+    (LetCont (k4) (LetPrim v6 (Constant (Int 0)))
       (LetCont* (k5 v7)
-        (LetCont (k6) (LetPrim v8 (Constant IntConstant(1)))
+        (LetCont (k6) (LetPrim v8 (Constant (Int 1)))
           (LetCont (k7 v9) (InvokeContinuation* k0 v9))
           (InvokeMethod v2 + v8 k7))
         (LetCont (k8)
           (LetCont (k9 v10)
-            (LetCont (k10 v11) (LetPrim v12 (Constant IntConstant(1)))
+            (LetCont (k10 v11) (LetPrim v12 (Constant (Int 1)))
               (LetCont (k11 v13)
                 (InvokeContinuation* k5 v13))
               (InvokeMethod v7 + v12 k11))
             (InvokeStatic print v10 k10))
           (InvokeMethod v2 toString k9))
-        (LetPrim v14 (Constant IntConstant(2)))
+        (LetPrim v14 (Constant (Int 2)))
         (LetCont (k12 v15) (Branch (IsTrue v15) k8 k6))
         (InvokeMethod v7 < v14 k12))
       (InvokeContinuation k5 v6))
-    (LetPrim v16 (Constant IntConstant(2)))
+    (LetPrim v16 (Constant (Int 2)))
     (LetCont (k13 v17) (Branch (IsTrue v17) k4 k1))
     (InvokeMethod v2 < v16 k13))
   (InvokeContinuation k0 v1))
@@ -148,18 +152,19 @@
 // }
 
 String BASIC_LOOP_IN = """
-(FunctionDefinition main ( return) (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont* (k0 v1)
-    (LetCont (k1) (LetPrim v2 (Constant NullConstant))
+    (LetCont (k1) (LetPrim v2 (Constant (Null)))
       (InvokeContinuation return v2))
     (LetCont (k2)
       (LetCont (k3 v3)
-        (LetCont (k4 v4) (LetPrim v5 (Constant IntConstant(1)))
+        (LetCont (k4 v4) (LetPrim v5 (Constant (Int 1)))
           (LetCont (k5 v6) (InvokeContinuation* k0 v6))
           (InvokeMethod v1 + v5 k5))
         (InvokeStatic print v3 k4))
       (InvokeMethod v1 toString k3))
-    (LetPrim v7 (Constant IntConstant(2)))
+    (LetPrim v7 (Constant (Int 2)))
     (LetCont (k6 v8) (Branch (IsTrue v8) k2 k1))
     (InvokeMethod v1 < v7 k6))
   (InvokeContinuation k0 v0))
@@ -172,20 +177,20 @@
 // IR written by hand since this case is currently not being generated.
 
 String SCOPING_IN = """
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetCont (k0 v1)
     (InvokeStatic print v1 return))
-  (LetPrim v0 (Constant IntConstant(0)))
-  (LetPrim v2 (Constant NullConstant))
+  (LetPrim v0 (Constant (Int 0)))
+  (LetPrim v2 (Constant (Null)))
   (InvokeContinuation k0 v0))
 """;
 
 String SCOPING_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0)
     (InvokeStatic print v0 return))
-  (LetPrim v1 (Constant NullConstant))
+  (LetPrim v1 (Constant (Null)))
   (InvokeContinuation k0 ))
 """;
 
@@ -193,8 +198,8 @@
 // IR written by hand.
 
 String NEVER_INVOKED_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
     (InvokeStatic print v1 return))
   (InvokeContinuation return v0))
diff --git a/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart b/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
index 4b3fc39..bcd9e0a 100644
--- a/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
+++ b/tests/compiler/dart2js/backend_dart/opt_shrinking_test.dart
@@ -20,12 +20,15 @@
 //  }
 
 String DEAD_VAL_IN = """
-(FunctionDefinition main ( return) (LetPrim v0 (Constant IntConstant(42)))
-  (LetPrim v1 (Constant IntConstant(0))) (InvokeContinuation return v1))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 42)))
+  (LetPrim v1 (Constant (Int 0)))
+  (InvokeContinuation return v1))
 """;
 String DEAD_VAL_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0))) (InvokeContinuation return v0))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
+  (InvokeContinuation return v0))
 """;
 
 // Iterative dead-val. No optimizations possible since the continuation to
@@ -38,10 +41,10 @@
 //  }
 
 String ITERATIVE_DEAD_VAL1_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(42)))
-  (LetPrim v1 (Constant IntConstant(1)))
-  (LetCont (k0 v2) (LetPrim v3 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 42)))
+  (LetPrim v1 (Constant (Int 1)))
+  (LetCont (k0 v2) (LetPrim v3 (Constant (Int 0)))
     (InvokeContinuation return v3))
   (InvokeMethod v0 + v1 k0))
 """;
@@ -50,18 +53,18 @@
 // Iterative dead-val. IR written by hand.
 
 String ITERATIVE_DEAD_VAL2_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(42)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 42)))
   (LetPrim v1
     (CreateFunction
-      (FunctionDefinition f (i return)
+      (FunctionDefinition f (i) return ()
         (InvokeContinuation return v0))))
-  (LetPrim v2 (Constant IntConstant(0)))
+  (LetPrim v2 (Constant (Int 0)))
   (InvokeContinuation return v2))
 """;
 String ITERATIVE_DEAD_VAL2_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (InvokeContinuation return v0))
 """;
 
@@ -69,20 +72,20 @@
 // IR written by hand.
 
 String DEAD_CONT_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v4 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v4 (Constant (Int 0)))
   (LetCont (k0 v0) (InvokeConstructor List return))
   (LetCont (k1 v1)
-    (LetCont (k2 v2) (LetPrim v3 (Constant IntConstant(0)))
+    (LetCont (k2 v2) (LetPrim v3 (Constant (Int 0)))
       (InvokeContinuation return v3))
     (InvokeStatic print v4 k2))
   (InvokeStatic print v4 k1))
 """;
 String DEAD_CONT_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
-    (LetCont (k1 v2) (LetPrim v3 (Constant IntConstant(0)))
+    (LetCont (k1 v2) (LetPrim v3 (Constant (Int 0)))
       (InvokeContinuation return v3))
     (InvokeStatic print v0 k1))
   (InvokeStatic print v0 k0))
@@ -91,21 +94,21 @@
 // Iterative dead-cont. IR written by hand.
 
 String ITERATIVE_DEAD_CONT_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v4 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v4 (Constant (Int 0)))
   (LetCont (k0 v0) (InvokeConstructor List return))
   (LetCont (k3 v5) (InvokeContinuation k0 v5))
   (LetCont (k1 v1)
-    (LetCont (k2 v2) (LetPrim v3 (Constant IntConstant(0)))
+    (LetCont (k2 v2) (LetPrim v3 (Constant (Int 0)))
       (InvokeContinuation return v3))
     (InvokeStatic print v4 k2))
   (InvokeStatic print v4 k1))
 """;
 String ITERATIVE_DEAD_CONT_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
-    (LetCont (k1 v2) (LetPrim v3 (Constant IntConstant(0)))
+    (LetCont (k1 v2) (LetPrim v3 (Constant (Int 0)))
       (InvokeContinuation return v3))
     (InvokeStatic print v0 k1))
   (InvokeStatic print v0 k0))
@@ -115,21 +118,21 @@
 // IR written by hand.
 
 String BETA_CONT_LIN_IN = """
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetCont (k0 v0)
     (LetCont (k1 v1)
-      (LetCont (k2 v2) (LetPrim v3 (Constant IntConstant(0)))
+      (LetCont (k2 v2) (LetPrim v3 (Constant (Int 0)))
         (InvokeContinuation return v3))
       (InvokeStatic print v0 k2))
     (InvokeStatic print v0 k1))
-  (LetPrim v4 (Constant IntConstant(0)))
+  (LetPrim v4 (Constant (Int 0)))
   (InvokeContinuation k0 v4))
 """;
 String BETA_CONT_LIN_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
-    (LetCont (k1 v2) (LetPrim v3 (Constant IntConstant(0)))
+    (LetCont (k1 v2) (LetPrim v3 (Constant (Int 0)))
       (InvokeContinuation return v3))
     (InvokeStatic print v0 k1))
   (InvokeStatic print v0 k0))
@@ -138,10 +141,10 @@
 // Beta-cont-lin with recursive continuation. IR written by hand.
 
 String RECURSIVE_BETA_CONT_LIN_IN = """
-(FunctionDefinition main ( return)
+(FunctionDefinition main () return ()
   (LetCont* (k0 v0)
     (InvokeContinuation* k0 v0))
-  (LetPrim v1 (Constant IntConstant(0)))
+  (LetPrim v1 (Constant (Int 0)))
   (InvokeContinuation k0 v1))
 """;
 String RECURSIVE_BETA_CONT_LIN_OUT = RECURSIVE_BETA_CONT_LIN_IN;
@@ -149,17 +152,17 @@
 // Beta-cont-lin used inside body. IR written by hand.
 
 String USED_BETA_CONT_LIN_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1)
     (LetCont (k1 v2)
-      (LetCont (k2 v3) (LetPrim v4 (Constant IntConstant(0)))
+      (LetCont (k2 v3) (LetPrim v4 (Constant (Int 0)))
         (InvokeContinuation return v4))
       (InvokeStatic print v1 k2))
     (InvokeStatic print v1 k1))
     (LetPrim v5
       (CreateFunction
-        (FunctionDefinition f ( return)
+        (FunctionDefinition f () return ()
           (InvokeContinuation return v1))))
   (InvokeContinuation k0 v0))
 """;
@@ -169,19 +172,19 @@
 // IR written by hand.
 
 String ETA_CONT_IN = """
-(FunctionDefinition main ( return)
-  (LetPrim v3 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v3 (Constant (Int 0)))
   (LetCont* (k1 v1) (InvokeContinuation return v3))
   (LetCont (k0 v0) (InvokeContinuation k1 v0))
   (LetPrim v4
     (CreateFunction
-      (FunctionDefinition f ( return)
+      (FunctionDefinition f () return ()
         (InvokeContinuation k1 v3))))
   (InvokeContinuation k0 v3))
 """;
 String ETA_CONT_OUT = """
-(FunctionDefinition main ( return)
-  (LetPrim v0 (Constant IntConstant(0)))
+(FunctionDefinition main () return ()
+  (LetPrim v0 (Constant (Int 0)))
   (LetCont (k0 v1) (InvokeContinuation return v0))
   (InvokeContinuation k0 v0))
 """;
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_test.dart b/tests/compiler/dart2js/backend_dart/sexpr_test.dart
index 4682d20..9c4831e 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr_test.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr_test.dart
@@ -109,7 +109,6 @@
         List<String> sexprs = stringifyAll(functions);
         String combined = sexprs.join();
         String withoutNullConstants = combined.replaceAll("Constant null", "");
-
         Expect.isFalse(withoutNullConstants.contains("null"));
         for (String token in expectedTokens) {
           Expect.isTrue(combined.contains(token));
diff --git a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
index d0eeba8..360f9ba 100644
--- a/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
+++ b/tests/compiler/dart2js/backend_dart/sexpr_unstringifier.dart
@@ -142,6 +142,13 @@
   static const String FUNCTION_DEFINITION = "FunctionDefinition";
   static const String IS_TRUE = "IsTrue";
 
+  // Constants
+  static const String BOOL = "Bool";
+  static const String DOUBLE = "Double";
+  static const String INT = "Int";
+  static const String NULL = "Null";
+  static const String STRING = "String";
+
   final Map<String, Definition> name2variable =
       <String, Definition>{ "return": new Continuation.retrn() };
 
@@ -271,29 +278,15 @@
 
     // name
     Element element = new DummyElement("");
-    if (tokens.current != '(' && tokens.current != '{') {
+    if (tokens.current != '(') {
       // This is a named function.
       element = new DummyElement(tokens.read());
     }
 
-    // [closure-vars]
-    List<ClosureVariable> closureVariables = <ClosureVariable>[];
-    if (tokens.current == '{') {
-      tokens.read('{');
-      while (tokens.current != '}') {
-        String varName = tokens.read();
-        ClosureVariable variable =
-            new ClosureVariable(element, new DummyElement(varName));
-        closureVariables.add(variable);
-        name2variable[varName] = variable;
-      }
-      tokens.read('}');
-    }
-
-    // (args cont)
+    // (parameters)
     List<Definition> parameters = <Definition>[];
     tokens.consumeStart();
-    while (tokens.next != ")") {
+    while (tokens.current != ")") {
       String paramName = tokens.read();
       if (name2variable.containsKey(paramName)) {
         parameters.add(name2variable[paramName]);
@@ -303,17 +296,31 @@
         parameters.add(param);
       }
     }
+    tokens.consumeEnd();
 
+    // continuation
     String contName = tokens.read("return");
     Continuation cont = name2variable[contName];
     assert(cont != null);
+
+    // [closure-variables]
+    List<ClosureVariable> closureVariables = <ClosureVariable>[];
+    tokens.consumeStart();
+    while (tokens.current != ')') {
+      String varName = tokens.read();
+      ClosureVariable variable =
+          new ClosureVariable(element, new DummyElement(varName));
+      closureVariables.add(variable);
+      name2variable[varName] = variable;
+    }
     tokens.consumeEnd();
 
     // body
     Expression body = parseExpression();
 
     tokens.consumeEnd();
-    return new FunctionDefinition(element, cont, parameters, body, null, null,
+    return new FunctionDefinition(element, parameters,
+        new RunnableBody(body, cont), null, null,
         closureVariables);
   }
 
@@ -576,79 +583,61 @@
   /// (Constant (constant))
   Constant parseConstant() {
     tokens.consumeStart(CONSTANT);
+    tokens.consumeStart();
+    Constant result;
     String tag = tokens.read();
-
-    // NullConstant.
-    if (tag == "NullConstant") {
-      tokens.consumeEnd();
-      return new Constant(
-          new PrimitiveConstantExpression(new NullConstantValue()));
+    switch (tag) {
+      case NULL:
+        result = new Constant(
+            new PrimitiveConstantExpression(new NullConstantValue()));
+        break;
+      case BOOL:
+        String value = tokens.read();
+        if (value == "true") {
+          result = new Constant(
+              new PrimitiveConstantExpression(new TrueConstantValue()));
+        } else if (value == "false") {
+          result = new Constant(
+              new PrimitiveConstantExpression(new FalseConstantValue()));
+        } else {
+          throw "Invalid Boolean value '$value'.";
+        }
+        break;
+      case STRING:
+        List<String> strings = <String>[];
+        do {
+          strings.add(tokens.read());
+        } while (tokens.current != ")");
+        String string = strings.join(" ");
+        assert(string.startsWith('"') && string.endsWith('"'));
+        StringConstantValue value = new StringConstantValue(
+            new LiteralDartString(string.substring(1, string.length - 1)));
+        result = new Constant(new PrimitiveConstantExpression(value));
+        break;
+      case INT:
+        String value = tokens.read();
+        int intValue = int.parse(value, onError: (_) => null);
+        if (intValue == null) {
+          throw "Invalid int value 'value'.";
+        }
+        result = new Constant(
+            new PrimitiveConstantExpression(new IntConstantValue(intValue)));
+        break;
+      case DOUBLE:
+        String value = tokens.read();
+        double doubleValue = double.parse(value, (_) => null);
+        if (doubleValue == null) {
+          throw "Invalid double value '$value'.";
+        }
+        result = new Constant(new PrimitiveConstantExpression(
+            new DoubleConstantValue(doubleValue)));
+        break;
+      default:
+        throw "Unexpected constant tag '$tag'.";
     }
-
-    // BoolConstant.
-    if (tag == "BoolConstant") {
-      tokens.consumeStart();
-      tag = tokens.read();
-      tokens.consumeEnd();
-      tokens.consumeEnd();
-      if (tag == "true") {
-        return new Constant(new PrimitiveConstantExpression(
-            new TrueConstantValue()));
-      } else if (tag == "false") {
-        return new Constant(new PrimitiveConstantExpression(
-            new FalseConstantValue()));
-      }
-      throw "Invalid bool value '$tag'.";
-    }
-
-    // StringConstant.
-    if (tag == "StringConstant") {
-      tokens.consumeStart();
-      List<String> strings = <String>[];
-      do {
-        strings.add(tokens.read());
-      } while (tokens.current != ")");
-      tokens.consumeEnd();
-
-      String string = strings.join(" ");
-      assert(string.startsWith('"') && string.endsWith('"'));
-
-      StringConstantValue value = new StringConstantValue(
-          new LiteralDartString(string.substring(1, string.length - 1)));
-
-      tokens.consumeEnd();
-      return new Constant(new PrimitiveConstantExpression(value));
-    }
-
-    // IntConstant.
-    if (tag == "IntConstant") {
-      tokens.consumeStart();
-      tag = tokens.read();
-      int intValue = int.parse(tag, onError: (_) => null);
-      if (intValue == null) {
-        throw "Invalid int value '$tag'.";
-      }
-      tokens.consumeEnd();
-      tokens.consumeEnd();
-      return new Constant(new PrimitiveConstantExpression(
-          new IntConstantValue(intValue)));
-    }
-
-    // DoubleConstant.
-    if (tag == "DoubleConstant") {
-      tokens.consumeStart();
-      tag = tokens.read();
-      double doubleValue = double.parse(tag, (_) => null);
-      if (doubleValue == null) {
-        throw "Invalid double value '$tag'.";
-      }
-      tokens.consumeEnd();
-      tokens.consumeEnd();
-      return new Constant(new PrimitiveConstantExpression(
-          new DoubleConstantValue(doubleValue)));
-    }
-
-    throw "Unhandled tag '$tag'.";
+    tokens.consumeEnd();
+    tokens.consumeEnd();
+    return result;
   }
 
   /// (CreateFunction (definition))
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index 23f459b..b923783 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -18,8 +18,6 @@
 
 backend_dart/opt_cyclic_redundant_phi_test: Fail # Issue 20159
 
-deferred_dont_inline_deferred_globals_test: Fail # Issue 21301
-
 mirrors/library_exports_hidden_test: Fail
 mirrors/library_exports_shown_test: Fail
 mirrors/library_imports_hidden_test: Fail
diff --git a/tests/compiler/dart2js/deferred_emit_type_checks_test.dart b/tests/compiler/dart2js/deferred_emit_type_checks_test.dart
index d397aba..e236c69 100644
--- a/tests/compiler/dart2js/deferred_emit_type_checks_test.dart
+++ b/tests/compiler/dart2js/deferred_emit_type_checks_test.dart
@@ -53,11 +53,8 @@
     String mainOutput = outputs['main.js'].mem[0];
     String deferredOutput = outputs['out_1.part.js'].mem[0];
     String isPrefix = compiler.backend.namer.operatorIsPrefix;
-    String escapedIsPrefix = isPrefix.replaceAll(r'$', r'\$');
-    RegExp re = new RegExp(r"\n  _ = .\.A;\n  _."
-                            "${escapedIsPrefix}A = TRUE;");
-    Expect.isTrue(re.hasMatch(deferredOutput));
-    Expect.isFalse(re.hasMatch(mainOutput));
+    Expect.isTrue(deferredOutput.contains('${isPrefix}A: true'));
+    Expect.isFalse(mainOutput.contains('${isPrefix}A: true'));
   }));
 }
 
diff --git a/tests/compiler/dart2js/import_mirrors_test.dart b/tests/compiler/dart2js/import_mirrors_test.dart
index 07c00d0..cbe044b 100644
--- a/tests/compiler/dart2js/import_mirrors_test.dart
+++ b/tests/compiler/dart2js/import_mirrors_test.dart
@@ -7,6 +7,7 @@
 

 library dart2js.test.import;

 

+import 'dart:async';

 import 'package:expect/expect.dart';

 import 'package:async_helper/async_helper.dart';

 import 'package:compiler/src/dart2jslib.dart' show MessageKind;

@@ -252,11 +253,96 @@
        "main.dart => first.dart => package:package2/third.dart => dart:mirrors"]

 };

 

+const DIRECT_EXPORT = const {

+  '/main.dart': '''

+export 'dart:mirrors';

 

-test(Map sourceFiles,

-    {expectedPaths,

-     bool verbose: false,

-     bool enableExperimentalMirrors: false}) {

+main() {}

+''',

+

+  'paths':

+      "main.dart => dart:mirrors",

+};

+

+const INDIRECT_EXPORT1 = const {

+  '/main.dart': '''

+import 'first.dart';

+

+main() {}

+''',

+  '/first.dart': '''

+export 'dart:mirrors';

+''',

+

+  'paths':

+      "first.dart => dart:mirrors",

+  'verbosePaths':

+      "main.dart => first.dart => dart:mirrors",

+};

+

+const INDIRECT_EXPORT2 = const {

+  '/main.dart': '''

+import 'first.dart';

+

+main() {}

+''',

+  '/first.dart': '''

+import 'second.dart';

+''',

+  '/second.dart': '''

+export 'dart:mirrors';

+''',

+

+  'paths':

+      "second.dart => dart:mirrors",

+  'verbosePaths':

+      "main.dart => first.dart => second.dart => dart:mirrors",

+};

+

+const INDIRECT_PACKAGE_EXPORT1 = const {

+  '/main.dart': '''

+import 'first.dart';

+

+main() {}

+''',

+  '/first.dart': '''

+import 'package:package-name/second.dart';

+''',

+  '/pkg/package-name/second.dart': '''

+export 'dart:mirrors';

+''',

+

+  'paths':

+      "first.dart => package:package-name => dart:mirrors",

+  'verbosePaths':

+      "main.dart => first.dart => package:package-name/second.dart "

+      "=> dart:mirrors",

+};

+

+const INDIRECT_PACKAGE_EXPORT2 = const {

+  '/main.dart': '''

+import 'first.dart';

+

+main() {}

+''',

+  '/first.dart': '''

+export 'package:package-name/second.dart';

+''',

+  '/pkg/package-name/second.dart': '''

+import 'dart:mirrors';

+''',

+

+  'paths':

+      "first.dart => package:package-name => dart:mirrors",

+  'verbosePaths':

+      "main.dart => first.dart => package:package-name/second.dart "

+      "=> dart:mirrors",

+};

+

+Future test(Map sourceFiles,

+            {expectedPaths,

+             bool verbose: false,

+             bool enableExperimentalMirrors: false}) {

   if (expectedPaths is! List) {

     expectedPaths = [expectedPaths];

   }

@@ -271,7 +357,7 @@
   var compiler = compilerFor(sourceFiles, diagnosticHandler: collector,

                              packageRoot: Uri.parse('memory:/pkg/'),

                              options: options);

-  asyncTest(() => compiler.run(Uri.parse('memory:/main.dart')).then((_) {

+  return compiler.run(Uri.parse('memory:/main.dart')).then((_) {

     Expect.equals(0, collector.errors.length, 'Errors: ${collector.errors}');

     if (enableExperimentalMirrors) {

       Expect.equals(0, collector.warnings.length,

@@ -285,32 +371,43 @@
                   MessageKind.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)}).toString(),

           collector.warnings.first.message);

     }

-  }));

+  });

 }

 

-checkPaths(Map sourceData) {

+Future checkPaths(Map sourceData) {

   Map sourceFiles = sourceData;

   var expectedPaths = sourceData['paths'];

   var expectedVerbosePaths = sourceData['verbosePaths'];

   if (expectedVerbosePaths == null) {

     expectedVerbosePaths = expectedPaths;

   }

-  test(sourceFiles, expectedPaths: expectedPaths);

-  test(sourceFiles, expectedPaths: expectedVerbosePaths, verbose: true);

-  test(sourceFiles, enableExperimentalMirrors: true);

+  return test(sourceFiles, expectedPaths: expectedPaths).then((_) {

+    return test(

+        sourceFiles, expectedPaths: expectedVerbosePaths, verbose: true);

+  }).then((_) {

+    return test(sourceFiles, enableExperimentalMirrors: true);

+  });

 }

 

 void main() {

-  checkPaths(DIRECT_IMPORT);

-  checkPaths(INDIRECT_IMPORT1);

-  checkPaths(INDIRECT_IMPORT2);

-  checkPaths(INDIRECT_PACKAGE_IMPORT1);

-  checkPaths(INDIRECT_PACKAGE_IMPORT2);

-  checkPaths(INDIRECT_PACKAGE_IMPORT3);

-  checkPaths(INDIRECT_PACKAGE_IMPORT4);

-  checkPaths(DUAL_DIRECT_IMPORT);

-  checkPaths(DUAL_INDIRECT_IMPORT1);

-  checkPaths(DUAL_INDIRECT_IMPORT2);

-  checkPaths(DUAL_INDIRECT_IMPORT3);

-  checkPaths(DUAL_INDIRECT_PACKAGE_IMPORT1);

+  asyncTest(() => Future.forEach([

+      DIRECT_IMPORT,

+      INDIRECT_IMPORT1,

+      INDIRECT_IMPORT2,

+      INDIRECT_PACKAGE_IMPORT1,

+      INDIRECT_PACKAGE_IMPORT2,

+      INDIRECT_PACKAGE_IMPORT3,

+      INDIRECT_PACKAGE_IMPORT4,

+      DUAL_DIRECT_IMPORT,

+      DUAL_INDIRECT_IMPORT1,

+      DUAL_INDIRECT_IMPORT2,

+      DUAL_INDIRECT_IMPORT3,

+      DUAL_INDIRECT_PACKAGE_IMPORT1,

+      DIRECT_EXPORT,

+      INDIRECT_EXPORT1,

+      INDIRECT_EXPORT2,

+      INDIRECT_PACKAGE_EXPORT1,

+      INDIRECT_PACKAGE_EXPORT2],

+      (map) => checkPaths(map)

+  ));

 }

diff --git a/tests/compiler/dart2js/js_backend_cps_ir_control_flow.dart b/tests/compiler/dart2js/js_backend_cps_ir_control_flow.dart
index 746735b..2695588 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_control_flow.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_control_flow.dart
@@ -116,11 +116,25 @@
   if (1) {
     print('bad');
   } else {
-    print('ok');
+    print('good');
   }
 }""","""
 function() {
-  P.print("bad");
+  P.print("good");
+  return null;
+}"""),
+  const TestEntry("""
+foo() => 2;
+main() {
+  if (foo()) {
+    print('bad');
+  } else {
+    print('good');
+  }
+}""","""
+function() {
+  V.foo();
+  P.print("good");
   return null;
 }"""),
 ];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_interceptors.dart b/tests/compiler/dart2js/js_backend_cps_ir_interceptors.dart
new file mode 100644
index 0000000..6640b9a
--- /dev/null
+++ b/tests/compiler/dart2js/js_backend_cps_ir_interceptors.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Tests of interceptors.
+
+library interceptors_tests;
+
+import 'js_backend_cps_ir_test.dart';
+
+const List<TestEntry> tests = const [
+  const TestEntry("""
+main() {
+  var g = 1;
+
+  var x = g + 3;
+  print(x);
+}""",
+r"""
+function() {
+  var g, v0;
+  g = 1;
+  v0 = 3;
+  P.print(J.getInterceptor(g).$add(g, v0));
+  return null;
+}"""),
+];
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_operators.dart b/tests/compiler/dart2js/js_backend_cps_ir_operators.dart
index 3cdcf9b..781dde1 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_operators.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_operators.dart
@@ -11,7 +11,7 @@
 const List<TestEntry> tests = const [
   const TestEntry("main() { return true ? 42 : 'foo'; }"),
   const TestEntry("""
-foo() => foo;
+foo() => foo();
 main() {
   print(foo() ? "hello world" : "bad bad");
 }""",
diff --git a/tests/compiler/dart2js/js_backend_cps_ir_test.dart b/tests/compiler/dart2js/js_backend_cps_ir_test.dart
index 030b214..396e0e8 100644
--- a/tests/compiler/dart2js/js_backend_cps_ir_test.dart
+++ b/tests/compiler/dart2js/js_backend_cps_ir_test.dart
@@ -18,6 +18,7 @@
 import 'js_backend_cps_ir_literals.dart' as literals;
 import 'js_backend_cps_ir_operators.dart' as operators;
 import 'js_backend_cps_ir_control_flow.dart' as control_flow;
+import 'js_backend_cps_ir_interceptors.dart' as interceptors;
 
 const String TEST_MAIN_FILE = 'test.dart';
 
@@ -25,7 +26,8 @@
      ..addAll(basic.tests)
      ..addAll(literals.tests)
      ..addAll(control_flow.tests)
-     ..addAll(operators.tests);
+     ..addAll(operators.tests)
+     ..addAll(interceptors.tests);
 
 class TestEntry {
   final String source;
diff --git a/tests/compiler/dart2js/library_resolution_test.dart b/tests/compiler/dart2js/library_resolution_test.dart
new file mode 100644
index 0000000..9cd69b2
--- /dev/null
+++ b/tests/compiler/dart2js/library_resolution_test.dart
@@ -0,0 +1,130 @@
+// 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.
+
+/// Check that relative URIs are resolved against the canonical name of a
+/// library. This only matters for dart:-libraries, so this test mocks up two
+/// dart:-libraries.
+
+import "dart:io";
+
+import "dart:async";
+
+import "memory_source_file_helper.dart";
+
+import "package:async_helper/async_helper.dart";
+
+import 'package:expect/expect.dart' show
+    Expect;
+
+import 'package:compiler/src/elements/elements.dart' show
+    LibraryElement;
+
+import 'package:compiler/src/dart2jslib.dart' show
+    MessageKind;
+
+import 'package:_internal/libraries.dart' show
+    DART2JS_PLATFORM,
+    LibraryInfo;
+
+const LibraryInfo mock1LibraryInfo = const LibraryInfo(
+    "mock1.dart",
+    category: "Shared",
+    documented: false,
+    platforms: DART2JS_PLATFORM);
+
+const LibraryInfo mock2LibraryInfo = const LibraryInfo(
+    "mock2.dart",
+    category: "Shared",
+    documented: false,
+    platforms: DART2JS_PLATFORM);
+
+class CustomCompiler extends Compiler {
+  final Map<String, LibraryInfo> customLibraryInfo;
+
+  CustomCompiler(
+      this.customLibraryInfo,
+      provider,
+      outputProvider,
+      handler,
+      libraryRoot,
+      packageRoot,
+      options,
+      environment)
+      : super(
+          provider,
+          outputProvider,
+          handler,
+          libraryRoot,
+          packageRoot,
+          options,
+          environment);
+
+  LibraryInfo lookupLibraryInfo(String name) {
+    if (name == "m_o_c_k_1") return mock1LibraryInfo;
+    if (name == "m_o_c_k_2") return mock2LibraryInfo;
+    return super.lookupLibraryInfo(name);
+  }
+}
+
+main() {
+  Uri sdkRoot = Uri.base.resolve("sdk/");
+  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
+
+  var provider = new MemorySourceFileProvider(MEMORY_SOURCE_FILES);
+  var handler = new FormattingDiagnosticHandler(provider);
+
+  outputProvider(String name, String extension) {
+    if (name != '') throw 'Attempt to output file "$name.$extension"';
+    return new NullSink('$name.$extension');
+  }
+
+  Future wrappedProvider(Uri uri) {
+    if (uri == sdkRoot.resolve('lib/mock1.dart')) {
+      return provider.readStringFromUri(Uri.parse('memory:mock1.dart'));
+    }
+    if (uri == sdkRoot.resolve('lib/mock2.dart')) {
+      return provider.readStringFromUri(Uri.parse('memory:mock2.dart'));
+    }
+    return provider.readStringFromUri(uri);
+  }
+
+  String expectedMessage =
+      MessageKind.LIBRARY_NOT_FOUND.message(
+          {'resolvedUri': 'dart:mock2.dart'}).computeMessage();
+
+  int actualMessageCount = 0;
+
+  wrappedHandler(
+      Uri uri, int begin, int end, String message, kind) {
+    if (message == expectedMessage) {
+      actualMessageCount++;
+    } else {
+      return handler(uri, begin, end, message, kind);
+    }
+  }
+
+  checkLibrary(LibraryElement library) {
+    Expect.equals(1, actualMessageCount);
+  }
+
+  Compiler compiler = new CustomCompiler(
+      {},
+      wrappedProvider,
+      outputProvider,
+      wrappedHandler,
+      sdkRoot,
+      packageRoot,
+      [],
+      {});
+
+  asyncStart();
+  compiler.libraryLoader.loadLibrary(Uri.parse("dart:m_o_c_k_1"))
+      .then(checkLibrary)
+      .then(asyncSuccess);
+}
+
+const Map MEMORY_SOURCE_FILES = const {
+  "mock1.dart": "library mock1; import 'mock2.dart';",
+  "mock2.dart": "library mock2;",
+};
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index b21d660..789a12c 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -8,7 +8,6 @@
 statements_test: Fail
 typed_locals_test: Fail
 no_such_method_test: Fail # Wrong Invocation.memberName.
-deferred/deferred_constant_test: Fail # http://dartbug.com/11138
 constant_javascript_semantics4_test: Fail, OK
 mirrors_used_closure_test: Fail # Issue 17939
 
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index f01bb1f..2a0826b 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -17,6 +17,9 @@
 string_from_environment_default_value: Skip
 string_from_environment_test: Skip
 
+[ $compiler == dart2dart && $builder_tag == new_backend ]
+regexp/pcre_test: Crash # Issue 19953
+
 [ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 bool_from_environment2_test: Skip
 bool_from_environment_default_value_test: Skip
@@ -217,8 +220,8 @@
 [ $system == windows && $arch == x64 ]
 stopwatch_test: Skip  # Flaky test due to expected performance behaviour.
 
-[ $runtime != d8 ]
-# The regexp tests are not verified to work on non d8 platforms yet.
+[ $runtime != d8 && $runtime != vm ]
+# The regexp tests are not verified to work on non d8/vm platforms yet.
 regexp/*: Skip
 
 [ $runtime == vm ]
diff --git a/tests/corelib/safe_to_string_test.dart b/tests/corelib/safe_to_string_test.dart
index c48b5dd..ad2fbdc 100644
--- a/tests/corelib/safe_to_string_test.dart
+++ b/tests/corelib/safe_to_string_test.dart
@@ -28,6 +28,8 @@
   Expect.stringEquals('null', Error.safeToString(null));
   Expect.stringEquals('true', Error.safeToString(true));
   Expect.stringEquals('false', Error.safeToString(false));
-  Expect.stringEquals("Instance of 'Object'",
+  // The class name may be minified.
+  String className = "$Object";
+  Expect.stringEquals("Instance of '$className'",
                       Error.safeToString(new Object()));
 }
diff --git a/tests/html/html.status b/tests/html/html.status
index d42d012..01ae6f0 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -234,6 +234,7 @@
 canvasrenderingcontext2d_test/drawImage_video_element: Fail # Safari does not support drawImage w/ video element
 canvasrenderingcontext2d_test/drawImage_video_element_dataUrl: Fail # Safari does not support drawImage w/ video element
 audiocontext_test/functional: Fail # Issue 14354
+element_test: Pass, Fail # Issue 21434
 
 # Safari Feature support statuses-
 # All changes should be accompanied by platform support annotation changes.
diff --git a/tests/language/deferred_global_lib.dart b/tests/language/deferred_global_lib.dart
index be4a001..a8fdca5 100644
--- a/tests/language/deferred_global_lib.dart
+++ b/tests/language/deferred_global_lib.dart
@@ -11,6 +11,10 @@
 }());
 
 var lazyConstGlobal = "lazyConstGlobal";
+// Regression test for bug #21840.
+var const1Global = const {};
+final lazyConstGlobal2 = const1Global;
+
 var lazyNonConstGlobal = (() {
   sideEffectCounter++;
   return "lazyNonConstGlobal";
diff --git a/tests/language/deferred_global_test.dart b/tests/language/deferred_global_test.dart
index 709921e..21ef619 100644
--- a/tests/language/deferred_global_test.dart
+++ b/tests/language/deferred_global_test.dart
@@ -7,9 +7,16 @@
 
 import "deferred_global_lib.dart" deferred as lib;
 
+var nonDeferredGlobal = const {};
+
 void main() {
+  nonDeferredGlobal = null;
   asyncStart();
   lib.loadLibrary().then((_) {
+    // Ensure non-deferred globals are not reset when loading a deferred
+    // library.
+    Expect.equals(null, nonDeferredGlobal);
+
     Expect.equals("finalConstGlobal", lib.finalConstGlobal);
     Expect.equals(0, lib.sideEffectCounter);
     Expect.equals("finalNonConstGlobal", lib.finalNonConstGlobal);
@@ -40,7 +47,14 @@
     Expect.equals("lazyConstGlobal_mutated2", lib.readLazyConstGlobal());
     Expect.equals("lazyNonConstGlobal_mutated2", lib.readLazyNonConstGlobal());
 
+    Expect.mapEquals({}, lib.lazyConstGlobal2);
+    lib.const1Global = 0;
     Expect.equals(2, lib.sideEffectCounter);
-    asyncEnd();
+    Expect.equals(0, lib.const1Global);
+    // Try loading the deferred library again, should not reset the globals.
+    lib.loadLibrary().then((_) {
+      Expect.equals(0, lib.const1Global);
+      asyncEnd();
+    });
   });
 }
diff --git a/tests/language/deferred_mixin_lib1.dart b/tests/language/deferred_mixin_lib1.dart
new file mode 100644
index 0000000..37ebd10
--- /dev/null
+++ b/tests/language/deferred_mixin_lib1.dart
@@ -0,0 +1,42 @@
+// 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 lib1;
+
+import "deferred_mixin_shared.dart";
+import "deferred_mixin_test.dart";
+
+class Mixin {
+  foo() => "lib1.Mixin";
+}
+
+class A extends Object with NonDeferredMixin {
+  foo() {
+    return "A with " + super.foo();
+  }
+}
+
+class B extends Object with Mixin {
+  foo() {
+    return "B with " + super.foo();
+  }
+}
+
+class C extends Object with Mixin, NonDeferredMixin1 {
+  foo() {
+    return "C with " + super.foo();
+  }
+}
+
+class D extends Object with NonDeferredMixin2, Mixin {
+  foo() {
+    return "D with " + super.foo();
+  }
+}
+
+class E extends Object with SharedMixin {
+  foo() {
+    return "E with " + super.foo();
+  }
+}
diff --git a/tests/language/deferred_mixin_lib2.dart b/tests/language/deferred_mixin_lib2.dart
new file mode 100644
index 0000000..afe81b8
--- /dev/null
+++ b/tests/language/deferred_mixin_lib2.dart
@@ -0,0 +1,13 @@
+// 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 lib2;
+
+import "deferred_mixin_shared.dart";
+
+class A extends Object with SharedMixin {
+  foo() {
+    return "lib2.A with " + super.foo();
+  }
+}
\ No newline at end of file
diff --git a/tests/language/deferred_mixin_shared.dart b/tests/language/deferred_mixin_shared.dart
new file mode 100644
index 0000000..2ad9832
--- /dev/null
+++ b/tests/language/deferred_mixin_shared.dart
@@ -0,0 +1,9 @@
+// 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 shared;
+
+class SharedMixin {
+  foo() => "SharedMixin";
+}
\ No newline at end of file
diff --git a/tests/language/deferred_mixin_test.dart b/tests/language/deferred_mixin_test.dart
new file mode 100644
index 0000000..11a69a3
--- /dev/null
+++ b/tests/language/deferred_mixin_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+import "deferred_mixin_lib1.dart" deferred as lib1;
+import "deferred_mixin_lib2.dart" deferred as lib2;
+
+class NonDeferredMixin {
+ foo() => "NonDeferredMixin";
+}
+
+class NonDeferredMixin1 {
+ foo() => "NonDeferredMixin1";
+}
+
+class NonDeferredMixin2 {
+ foo() => "NonDeferredMixin2";
+}
+
+main() {
+  Expect.equals("NonDeferredMixin", new NonDeferredMixin().foo());
+  Expect.equals("NonDeferredMixin1", new NonDeferredMixin1().foo());
+  Expect.equals("NonDeferredMixin2", new NonDeferredMixin2().foo());
+  asyncStart();
+  lib1.loadLibrary().then((_) {
+    Expect.equals("lib1.Mixin", new lib1.Mixin().foo());
+    Expect.equals("A with NonDeferredMixin", new lib1.A().foo());
+    Expect.equals("B with lib1.Mixin", new lib1.B().foo());
+    Expect.equals("C with NonDeferredMixin1", new lib1.C().foo());
+    Expect.equals("D with lib1.Mixin", new lib1.D().foo());
+    Expect.equals("E with SharedMixin", new lib1.E().foo());
+    lib2.loadLibrary().then((_) {
+      Expect.equals("lib2.A with SharedMixin", new lib2.A().foo());
+      asyncEnd();
+    });
+  });
+}
diff --git a/tests/language/deferred_static_seperate_lib1.dart b/tests/language/deferred_static_seperate_lib1.dart
new file mode 100644
index 0000000..9296523
--- /dev/null
+++ b/tests/language/deferred_static_seperate_lib1.dart
@@ -0,0 +1,51 @@
+// 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 lib1;
+
+class ConstClass {
+  final x;
+  const ConstClass(this.x);
+}
+
+var x = const ConstClass(const ConstClass(1));
+
+class C {
+  static foo() {
+    () {} (); // Hack to avoid inlining.
+    return 1;
+  }
+  bar() {
+    () {} (); // Hack to avoid inlining.
+    return 1;
+  }
+}
+
+class C1 {
+  static var foo = const {};
+  var bar = const {};
+}
+
+class C2 {
+  static var foo = new Map.from({1: 2});
+  var bar = new Map.from({1: 2});
+}
+
+class C3 {
+  static final foo = const ConstClass(const ConstClass(1));
+  final bar = const ConstClass(const ConstClass(1));
+}
+
+class C4 {
+  static final foo = new Map.from({x: x});
+  final bar = new Map.from({x: x});
+}
+
+class C5 {
+  static const foo = const [const {1: 3}];
+  bar() {
+    () {} (); // Hack to avoid inlining.
+    return 1;
+  }
+}
\ No newline at end of file
diff --git a/tests/language/deferred_static_seperate_lib2.dart b/tests/language/deferred_static_seperate_lib2.dart
new file mode 100644
index 0000000..a2f4cbb
--- /dev/null
+++ b/tests/language/deferred_static_seperate_lib2.dart
@@ -0,0 +1,22 @@
+// 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 lib2;
+
+import "package:expect/expect.dart";
+import "deferred_static_seperate_lib1.dart";
+
+foo() {
+  Expect.equals(1, C.foo());
+  Expect.mapEquals({}, C1.foo);
+
+  Expect.mapEquals({1: 2}, C2.foo);
+  C2.foo = {1: 2};
+  Expect.mapEquals({1: 2}, C2.foo);
+
+  Expect.equals(x, C3.foo);
+  Expect.mapEquals({x: x}, C4.foo);
+  Expect.listEquals([const{1: 3}], C5.foo);
+
+}
\ No newline at end of file
diff --git a/tests/language/deferred_static_seperate_test.dart b/tests/language/deferred_static_seperate_test.dart
new file mode 100644
index 0000000..f1b4986
--- /dev/null
+++ b/tests/language/deferred_static_seperate_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+// The class lib1.C is referenced via lib1
+// The static function lib1.C.foo is referenced via lib2
+// Dart2js will put them in seperate hunks.
+// Similarly for C2, ..., C5.
+
+import "package:expect/expect.dart";
+import "deferred_static_seperate_lib1.dart" deferred as lib1;
+import "deferred_static_seperate_lib2.dart" deferred as lib2;
+
+void main() {
+  lib1.loadLibrary().then((_) {
+    lib2.loadLibrary().then((_) {
+      Expect.equals(1, new lib1.C().bar());
+      var x = new lib1.C2();
+      Expect.mapEquals({1: 2}, x.bar);
+      x.bar = {2: 3};
+      Expect.mapEquals({2: 3}, x.bar);
+
+      Expect.equals(lib1.x, new lib1.C3().bar);
+      Expect.mapEquals({lib1.x: lib1.x}, new lib1.C4().bar);
+      Expect.equals(1, new lib1.C5().bar());
+
+      lib2.foo();
+    });
+  });
+}
\ No newline at end of file
diff --git a/tests/language/generic_object_type_test.dart b/tests/language/generic_object_type_test.dart
new file mode 100644
index 0000000..4b1733a
--- /dev/null
+++ b/tests/language/generic_object_type_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class Tester<T> {
+  testGenericType(x) {
+    return x is T;
+  }
+}
+
+main() {
+  // The Dart Object type is special in that it doesn't have any superclass.
+  Expect.isTrue(new Tester<Object>().testGenericType(new Object()));
+}
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index a19cceb..5ee3135 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -2,6 +2,9 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+[ $compiler == dart2js && $csp ]
+deferred_mixin_test: RuntimeError # Issue 21863
+
 [ $compiler == dart2js || $compiler == dart2dart ]
 symbol_literal_test/*: Fail # Issue 21825
 constructor_duplicate_final_test/01: Fail # Issue 13363
@@ -140,13 +143,9 @@
 const_switch_test/02: RuntimeError # Issue 17960
 const_switch_test/04: RuntimeError # Issue 17960
 
-deferred_constant_list_test: RuntimeError # Issue 21293
-
 enum_const_test: RuntimeError # Issue 21817
 
 # Compilation errors.
-const_var_test: CompileTimeError # Issue 12793
-map_literal3_test: CompileTimeError # Issue 12793
 method_override5_test: RuntimeError # Issue 12809
 external_test/10: CompileTimeError # Issue 12887
 external_test/13: CompileTimeError # Issue 12887
@@ -168,6 +167,10 @@
 [ $compiler == dart2js && ($runtime == ff || $runtime == jsshell || $runtime == safari || $runtime == safarimobilesim)]
 round_test: Fail, OK # Common JavaScript engine Math.round bug.
 
+[ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim)]
+# Safari codegen bug, fixed on some versions of Safari 7.1 (Version 7.1 (9537.85.10.17.1))
+call_through_getter_test: Fail, OK
+
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 override_field_test/02: Pass, Slow # TODO(kasperl): Please triage.
 
@@ -183,6 +186,11 @@
 closure_call_wrong_argument_count_negative_test: Skip
 label_test: Skip
 
+[ $compiler == dart2dart && $builder_tag == new_backend && $minified == true ]
+# This test fails in minified, because the type-argument is
+# renamed, but the symbol naming it it is not.
+type_variable_conflict2_test/01: RuntimeError # Issue 16180
+
 [ $compiler == dart2dart && $builder_tag == new_backend && $minified == false ]
 # This test happens not to fail in minified, because the type-argument is
 # renamed, but the unresolved reference to it is not.
@@ -221,8 +229,6 @@
 
 metadata_test: Fail # Issue 12762
 const_evaluation_test/01: Fail # Issue 12762
-const_var_test: CompileTimeError # Issue 12794
-map_literal3_test: Fail # Issue 12794
 built_in_identifier_test/01: Fail # Issue 13022
 method_override4_test: Fail # Issue 12810
 method_override5_test: Fail # Issue 12810
diff --git a/tests/language/mixin_only_for_rti_test.dart b/tests/language/mixin_only_for_rti_test.dart
new file mode 100644
index 0000000..4c2245a
--- /dev/null
+++ b/tests/language/mixin_only_for_rti_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+class Tester<T> {
+  testGenericType(x) {
+    return x is T;
+  }
+}
+
+abstract class A = B with C;
+class B {}
+class C {}
+
+class X extends Y with Z {}
+class Y {}
+class Z {}
+
+main() {
+  // Classes A and X are only used as generic arguments.
+  Expect.isFalse(new Tester<A>().testGenericType(new Object()));
+  Expect.isFalse(new Tester<X>().testGenericType(new Object()));
+}
diff --git a/tests/language/type_literal_prefix_call_test.dart b/tests/language/type_literal_prefix_call_test.dart
new file mode 100644
index 0000000..8dfdfb3
--- /dev/null
+++ b/tests/language/type_literal_prefix_call_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'dart:core' as core;
+
+// Check that calling a type with a prefix is allowed, but throws at runtime.
+
+main() {
+  Expect.throws(() => core.List(), (e) => e is core.NoSuchMethodError); /// 00: static type warning
+}
diff --git a/tests/standalone/debugger/breakpoint_resolved_test.dart b/tests/standalone/debugger/breakpoint_resolved_test.dart
index efb0c43..14c2827 100644
--- a/tests/standalone/debugger/breakpoint_resolved_test.dart
+++ b/tests/standalone/debugger/breakpoint_resolved_test.dart
@@ -28,7 +28,7 @@
   Resume(),  // Next breakpoint expected in main, when bar() returns.
   MatchFrame(0, "main"),
   // Only two breakpoint resolved events expected.
-  ExpectEvent("breakpointResolved", {"breakpointId": 1}),
   ExpectEvent("breakpointResolved", {"breakpointId": 2}),
+  ExpectEvent("breakpointResolved", {"breakpointId": 3}),
   Resume(),
 ];
diff --git a/tests/standalone/pair_location_remapping_test.dart b/tests/standalone/pair_location_remapping_test.dart
new file mode 100644
index 0000000..277ccc5
--- /dev/null
+++ b/tests/standalone/pair_location_remapping_test.dart
@@ -0,0 +1,30 @@
+// 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.
+// Test that pair locations are remaped in slow path environments.
+// VMOptions=--optimization_counter_threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+class A {
+  final f;
+  A(this.f);
+}
+
+foo(i) {
+  var j = 0x7fffffffffffffff + i;
+  var c = new A(j);  // allocation will be sunk
+  var r = 0;
+  for (var k = 0; k < 10; k++) {
+    if ((j & (1 << k)) != 0) {
+      r++;
+    }
+  }
+  return c.f - r;
+}
+
+main() {
+  for (var i = 0; i < 1000; i++) {
+    Expect.equals(0x7fffffffffffffff - 10, foo(0));
+  }
+}
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index f3579db..0385ad0 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -88,6 +88,7 @@
 javascript_compatibility_errors_test: Skip
 javascript_compatibility_warnings_test: Skip
 unboxed_int_converter_test: Skip
+pair_location_remapping_test: Skip
 
 [ $compiler == dart2js && $jscl ]
 assert_test: RuntimeError, OK # Assumes unspecified fields on the AssertionError.
diff --git a/tests/try/poi/apply_updates_test.dart b/tests/try/poi/apply_updates_test.dart
index 8d79435..303bddd 100644
--- a/tests/try/poi/apply_updates_test.dart
+++ b/tests/try/poi/apply_updates_test.dart
@@ -10,6 +10,7 @@
     UTF8;
 
 import 'package:dart2js_incremental/library_updater.dart' show
+    IncrementalCompilerContext,
     LibraryUpdater,
     Update;
 
@@ -37,8 +38,11 @@
     PartialFunctionElement before = library.localLookup(expectedUpdate);
     var beforeNode = before.parseNode(compiler);
 
+    var context = new IncrementalCompilerContext();
     LibraryUpdater updater =
-        new LibraryUpdater(this.compiler, null, scriptUri, nolog, nolog);
+        new LibraryUpdater(this.compiler, null, nolog, nolog, context);
+    context.registerUriWithUpdates([scriptUri]);
+
     bool actualCanReuse =
         updater.canReuseLibrary(library, UTF8.encode(newSource));
     Expect.equals(expectedCanReuse, actualCanReuse);
diff --git a/tests/try/poi/library_updater_test.dart b/tests/try/poi/library_updater_test.dart
index d97dbed..e164162 100644
--- a/tests/try/poi/library_updater_test.dart
+++ b/tests/try/poi/library_updater_test.dart
@@ -2,13 +2,14 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// Test of LibraryUpdater.
+// Test of LibraryUpdater (one compilation unit per library).
 library trydart.library_updater_test;
 
 import 'dart:convert' show
     UTF8;
 
 import 'package:dart2js_incremental/library_updater.dart' show
+    IncrementalCompilerContext,
     LibraryUpdater,
     Update;
 
@@ -34,8 +35,10 @@
         super(before);
 
   Future run() => loadMainApp().then((LibraryElement library) {
+    var context = new IncrementalCompilerContext();
     LibraryUpdater updater =
-        new LibraryUpdater(this.compiler, null, scriptUri, nolog, nolog);
+        new LibraryUpdater(this.compiler, null, nolog, nolog, context);
+    context.registerUriWithUpdates([scriptUri]);
     bool actualCanReuse =
         updater.canReuseLibrary(library, UTF8.encode(newSource));
     Expect.equals(expectedCanReuse, actualCanReuse);
diff --git a/tests/try/poi/source_update.dart b/tests/try/poi/source_update.dart
new file mode 100644
index 0000000..6bd2395
--- /dev/null
+++ b/tests/try/poi/source_update.dart
@@ -0,0 +1,41 @@
+// 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 trydart.source_update;
+
+/// Returns [updates] expanded to full compilation units/source files.
+///
+/// [updates] is a convenient way to write updates/patches to a single source
+/// file without repeating common parts.
+///
+/// For example:
+///   ["head ", ["v1", "v2"], " tail"]
+/// expands to:
+///   ["head v1 tail", "head v2 tail"]
+List<String> expandUpdates(List updates) {
+  int outputCount = updates.firstWhere((e) => e is Iterable).length;
+  List<StringBuffer> result = new List<StringBuffer>(outputCount);
+  for (int i = 0; i < outputCount; i++) {
+    result[i] = new StringBuffer();
+  }
+  for (var chunk in updates) {
+    if (chunk is Iterable) {
+      int segmentCount = 0;
+      for (var segment in chunk) {
+        result[segmentCount++].write(segment);
+      }
+      if (segmentCount != outputCount) {
+        throw new ArgumentError(
+            "Expected ${outputCount} segments, "
+            "but found ${segmentCount} in $chunk");
+      }
+    } else {
+      for (StringBuffer buffer in result) {
+        buffer.write(chunk);
+      }
+    }
+  }
+
+  return result.map((e) => '$e').toList();
+}
diff --git a/tests/try/poi/source_update_test.dart b/tests/try/poi/source_update_test.dart
new file mode 100644
index 0000000..0f98ce8
--- /dev/null
+++ b/tests/try/poi/source_update_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+/// Test [source_update.dart].
+library trydart.source_update_test;
+
+import 'package:expect/expect.dart' show
+    Expect;
+
+import 'source_update.dart' show
+    expandUpdates;
+
+main() {
+  Expect.listEquals(
+      ["head v1 tail", "head v2 tail"],
+      expandUpdates(["head ", ["v1", "v2"], " tail"]));
+
+  Expect.listEquals(
+      ["head v1 tail v2", "head v2 tail v1"],
+      expandUpdates(["head ", ["v1", "v2"], " tail ", ["v2", "v1"]]));
+
+  Expect.throws(() {
+    expandUpdates(["head ", ["v1", "v2"], " tail ", ["v1"]]);
+  });
+
+  Expect.throws(() {
+    expandUpdates(["head ", ["v1", "v2"], " tail ", ["v1", "v2", "v3"]]);
+  });
+}
diff --git a/tests/try/web/incremental_compilation_update_test.dart b/tests/try/web/incremental_compilation_update_test.dart
index 5520f5b..ec333a2 100644
--- a/tests/try/web/incremental_compilation_update_test.dart
+++ b/tests/try/web/incremental_compilation_update_test.dart
@@ -44,66 +44,76 @@
 
 const int TIMEOUT = 100;
 
-const List<List<ProgramResult>> tests = const <List<ProgramResult>>[
+const List<EncodedResult> tests = const <EncodedResult>[
     // Basic hello-world test.
-    const <ProgramResult>[
-        const ProgramResult(
-            "main() { print('Hello, World!'); }",
-            const <String> ['Hello, World!']),
-        const ProgramResult(
-            "main() { print('Hello, Brave New World!'); }",
-            const <String> ['Hello, Brave New World!']),
-    ],
+    const EncodedResult(
+        const [
+            "main() { print('Hello, ",
+            const ["", "Brave New "],
+            "World!'); }",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['Hello, World!']),
+            const ProgramExpectation(
+                const <String>['Hello, Brave New World!']),
+        ]),
 
     // Test that the test framework handles more than one update.
-    const <ProgramResult>[
-        const ProgramResult(
-            "main() { print('Hello darkness, my old friend'); }",
-            const <String> ['Hello darkness, my old friend']),
-        const ProgramResult(
-            "main() { print('I\\'ve come to talk with you again'); }",
-            const <String> ['I\'ve come to talk with you again']),
-        const ProgramResult(
-            "main() { print('Because a vision softly creeping'); }",
-            const <String> ['Because a vision softly creeping']),
-    ],
+    const EncodedResult(
+        const [
+            "main() { print('",
+            const [
+                "Hello darkness, my old friend",
+                "I\\'ve come to talk with you again",
+                "Because a vision softly creeping",
+            ],
+            "'); }",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['Hello darkness, my old friend']),
+            const ProgramExpectation(
+                const <String>['I\'ve come to talk with you again']),
+            const ProgramExpectation(
+                const <String>['Because a vision softly creeping']),
+        ]),
 
     // Test that that isolate support works.
-    const <ProgramResult>[
-        const ProgramResult(
-            "main(arguments) { print('Hello, Isolated World!'); }",
-            const <String> ['Hello, Isolated World!']),
-        const ProgramResult(
-            "main(arguments) { print(arguments); }",
-            const <String> ['[]']),
-    ],
+    const EncodedResult(
+        const [
+            "main(arguments) { print(",
+            const [
+                "'Hello, Isolated World!'",
+                "arguments"
+            ],
+            "); }",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['Hello, Isolated World!']),
+            const ProgramExpectation(
+                const <String>['[]']),
+        ]),
 
-    // Test that a stored closure changes behavior when updated.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that a stored closure changes behavior when updated.
+
 var closure;
 
 foo(a, [b = 'b']) {
+""",
+            const [
+                r"""
   print('$a $b');
-}
-
-main() {
-  if (closure == null) {
-    print('[closure] is null.');
-    closure = foo;
-  }
-  closure('a');
-  closure('a', 'c');
-}
 """,
-            const <String> ['[closure] is null.', 'a b', 'a c']),
-        const ProgramResult(
-            r"""
-var closure;
-
-foo(a, [b = 'b']) {
+                r"""
   print('$b $a');
+""",
+            ],
+            r"""
 }
 
 main() {
@@ -114,45 +124,62 @@
   closure('a');
   closure('a', 'c');
 }
-""",
-            const <String> ['b a', 'c a']),
-    ],
+"""],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['[closure] is null.', 'a b', 'a c']),
+            const ProgramExpectation(
+                const <String>['b a', 'c a']),
+        ]),
 
-    // Test modifying a static method works.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             """
+// Test modifying a static method works.
+
 class C {
   static m() {
-    print('v1');
+""",
+            const [
+                r"""
+  print('v1');
+""",
+                r"""
+  print('v2');
+""",
+            ],
+            """
   }
 }
 main() {
   C.m();
 }
 """,
-            const <String> ['v1']),
-        const ProgramResult(
-            """
-class C {
-  static m() {
-    print('v2');
-  }
-}
-main() {
-  C.m();
-}
-""",
-            const <String> ['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test modifying an instance method works.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             """
+// Test modifying an instance method works.
+
 class C {
   m() {
-    print('v1');
+""",
+            const [
+                r"""
+  print('v1');
+""",
+                r"""
+  print('v2');
+""",
+            ],
+            """
   }
 }
 var instance;
@@ -164,33 +191,32 @@
   instance.m();
 }
 """,
-            const <String> ['instance is null', 'v1']),
-        const ProgramResult(
-            """
-class C {
-  m() {
-    print('v2');
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-            const <String> ['v2']),
-    ],
 
-    // Test that a stored instance tearoff changes behavior when updated.
-    const <ProgramResult>[
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
             """
+// Test that a stored instance tearoff changes behavior when updated.
+
 class C {
   m() {
-    print('v1');
+""",
+            const [
+                r"""
+  print('v1');
+""",
+                r"""
+  print('v2');
+""",
+            ],
+                """
   }
 }
 var closure;
@@ -202,34 +228,32 @@
   closure();
 }
 """,
-            const <String> ['closure is null', 'v1']),
-        const ProgramResult(
-            """
-class C {
-  m() {
-    print('v2');
-  }
-}
-var closure;
-main() {
-  if (closure == null) {
-    print('closure is null');
-    closure = new C().m;
-  }
-  closure();
-}
-""",
-            const <String> ['v2']),
-    ],
 
-    // Test that deleting an instance method works.
-    const <ProgramResult>[
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['closure is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
             """
+// Test that deleting an instance method works.
+
 class C {
+""",
+            const [
+                """
   m() {
     print('v1');
   }
+""",
+                """
+""",
+            ],
+            """
 }
 var instance;
 main() {
@@ -244,41 +268,37 @@
   }
 }
 """,
-            const <String> ['instance is null', 'v1']),
-        const ProgramResult(
-            """
-class C {
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  try {
-    instance.m();
-  } catch (e) {
-    print('threw');
-  }
-}
-""",
-            const <String> ['threw']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['threw']),
+        ]),
 
-    // Test that deleting an instance method works, even when accessed through
-    // super.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             """
+// Test that deleting an instance method works, even when accessed through
+// super.
+
 class A {
   m() {
     print('v2');
   }
 }
 class B extends A {
+""",
+            const [
+                """
   m() {
     print('v1');
   }
+""",
+                """
+""",
+            ],
+            """
 }
 class C extends B {
   m() {
@@ -294,60 +314,30 @@
   instance.m();
 }
 """,
-            const <String> ['instance is null', 'v1']),
-        const ProgramResult(
-            """
-class A {
-  m() {
-    print('v2');
-  }
-}
-class B extends A {
-}
-class C extends B {
-  m() {
-    super.m();
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-            const <String> ['v2']),
-    ],
 
-    // Test that deleting a top-level method works.
-    const <ProgramResult>[
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
             """
+// Test that deleting a top-level method works.
+
+""",
+            const [
+                """
 toplevel() {
   print('v1');
 }
-class C {
-  m() {
-    try {
-      toplevel();
-    } catch (e) {
-      print('threw');
-    }
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
 """,
-            const <String> ['instance is null', 'v1']),
-        const ProgramResult(
+                """
+""",
+            ],
             """
 class C {
   m() {
@@ -367,17 +357,31 @@
   instance.m();
 }
 """,
-            const <String> ['threw']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['threw']),
+        ]),
 
-    // Test that deleting a static method works.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             """
+// Test that deleting a static method works.
+
 class B {
+""",
+            const [
+                """
   static staticMethod() {
     print('v1');
   }
+""",
+                """
+""",
+            ],
+                """
 }
 class C {
   m() {
@@ -404,43 +408,19 @@
   instance.m();
 }
 """,
-            const <String> ['instance is null', 'v1']),
-        const ProgramResult(
-            """
-class B {
-}
-class C {
-  m() {
-    try {
-      B.staticMethod();
-    } catch (e) {
-      print('threw');
-    }
-    try {
-      // Ensure that noSuchMethod support is compiled. This test is not about
-      // adding new classes.
-      B.missingMethod();
-      print('bad');
-    } catch (e) {
-    }
-  }
-}
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
-""",
-            const <String> ['threw']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['threw']),
+        ]),
 
-    // Test that a newly instantiated class is handled.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             """
+// Test that a newly instantiated class is handled.
+
 class A {
   m() {
     print('Called A.m');
@@ -458,64 +438,61 @@
   if (instance == null) {
     print('instance is null');
     instance = new A();
-  }
-  instance.m();
-}
 """,
-            const <String>['instance is null', 'Called A.m']),
-        const ProgramResult(
-            """
-class A {
-  m() {
-    print('Called A.m');
-  }
-}
-
-class B {
-  m() {
-    print('Called B.m');
-  }
-}
-
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
+            const [
+                """
+""",
+                """
   } else {
     instance = new B();
+""",
+            ],
+            """
   }
   instance.m();
 }
 """,
-            const <String>['Called B.m']),
-    ],
 
-    // Test that source maps don't throw exceptions.
-    const <ProgramResult>[
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'Called A.m']),
+            const ProgramExpectation(
+                const <String>['Called B.m']),
+        ]),
+
+    const EncodedResult(
+        const [
             """
+// Test that source maps don't throw exceptions.
+
 main() {
   print('a');
-}
 """,
-            const <String>['a']),
-
-        const ProgramResult(
-            """
-main() {
-  print('a');
+            const [
+                """
+""",
+                """
   print('b');
   print('c');
+""",
+            ],
+            """
 }
 """,
-            const <String>['a', 'b', 'c']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['a']),
+            const ProgramExpectation(
+                const <String>['a', 'b', 'c']),
+        ]),
 
-    // Test that a newly instantiated class is handled.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that a newly instantiated class is handled.
+
 class A {
   get name => 'A.m';
 
@@ -533,43 +510,33 @@
   if (instance == null) {
     print('instance is null');
     instance = new A();
-  }
-  instance.m();
-}
 """,
-            const <String>['instance is null', 'Called A.m']),
-        const ProgramResult(
-            r"""
-class A {
-  get name => 'A.m';
-
-  m() {
-    print('Called $name');
-  }
-}
-
-class B extends A {
-  get name => 'B.m';
-}
-
-var instance;
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
+            const [
+                r"""
+""",
+                r"""
   } else {
     instance = new B();
+""",
+            ],
+            r"""
   }
   instance.m();
 }
 """,
-            const <String>['Called B.m']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'Called A.m']),
+            const ProgramExpectation(
+                const <String>['Called B.m']),
+        ]),
 
-    // Test that fields of a newly instantiated class are handled.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that fields of a newly instantiated class are handled.
+
 class A {
   var x;
   A(this.x);
@@ -583,51 +550,41 @@
   }
 }
 main() {
-  foo();
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
-            r"""
-class A {
-  var x;
-  A(this.x);
-}
-var instance;
-foo() {
-  if (instance != null) {
-    print(instance.x);
-  } else {
-    print('v1');
-  }
-}
-main() {
+            const [
+                r"""
+""",
+                r"""
   instance = new A('v2');
+""",
+            ],
+            r"""
   foo();
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that top-level functions can be added.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
-main() {
-  try {
-    foo();
-  } catch(e) {
-    print('threw');
-  }
-}
+// Test that top-level functions can be added.
+
 """,
-            const <String>['threw']),
-        const ProgramResult(
-            r"""
+            const [
+                "",
+                r"""
 foo() {
   print('v2');
 }
-
+""",
+            ],
+            r"""
 main() {
   try {
     foo();
@@ -636,31 +593,30 @@
   }
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['threw']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that static methods can be added.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
-class C {
-}
+// Test that static methods can be added.
 
-main() {
-  try {
-    C.foo();
-  } catch(e) {
-    print('threw');
-  }
-}
+class C {
 """,
-            const <String>['threw']),
-        const ProgramResult(
-            r"""
-class C {
+            const [
+                "",
+                r"""
   static foo() {
     print('v2');
   }
+""",
+            ],
+            r"""
 }
 
 main() {
@@ -671,38 +627,31 @@
   }
 }
 """,
-            const <String>['v2']),
-    ],
 
-    // Test that instance methods can be added.
-    const <ProgramResult>[
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['threw']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
             r"""
+// Test that instance methods can be added.
+
 class C {
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-
-  try {
-    instance.foo();
-  } catch(e) {
-    print('threw');
-  }
-}
 """,
-            const <String>['instance is null', 'threw']),
-        const ProgramResult(
-            r"""
-class C {
+            const [
+                "",
+                r"""
   foo() {
     print('v2');
   }
+""",
+            ],
+            r"""
 }
 
 var instance;
@@ -720,55 +669,63 @@
   }
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'threw']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that top-level functions can have signature changed.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that top-level functions can have signature changed.
+
+""",
+            const [
+                r"""
 foo() {
   print('v1');
-}
-
-main() {
-  foo();
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
-            r"""
+                r"""
 void foo() {
   print('v2');
+""",
+            ],
+            r"""
 }
 
 main() {
   foo();
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that static methods can have signature changed.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that static methods can have signature changed.
+
 class C {
+""",
+            const [
+                r"""
   static foo() {
     print('v1');
-  }
-}
-
-main() {
-  C.foo();
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
-            r"""
-class C {
+                r"""
   static void foo() {
     print('v2');
+""",
+            ],
+            r"""
   }
 }
 
@@ -776,16 +733,32 @@
   C.foo();
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that instance methods can have signature changed.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that instance methods can have signature changed.
+
 class C {
+""",
+            const [
+                r"""
   foo() {
     print('v1');
+""",
+                r"""
+  void foo() {
+    print('v2');
+""",
+            ],
+            r"""
   }
 }
 
@@ -800,71 +773,65 @@
   instance.foo();
 }
 """,
-            const <String>['instance is null', 'v1']),
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
             r"""
+// Test that adding a class is supported.
+
+""",
+            const [
+                "",
+                r"""
 class C {
   void foo() {
     print('v2');
   }
 }
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-
-  instance.foo();
-}
 """,
-            const <String>['v2']),
-    ],
-
-    // Test that adding a class is supported.
-    const <ProgramResult>[
-        const ProgramResult(
+            ],
             r"""
 main() {
+""",
+            const [
+                r"""
   print('v1');
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
-            r"""
-class C {
-  void foo() {
-    print('v2');
-  }
-}
-
-main() {
+                r"""
   new C().foo();
+""",
+            ],
+            r"""
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that removing a class is supported, using constructor.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that removing a class is supported, using constructor.
+
+""",
+            const [
+                r"""
 class C {
 }
-
-main() {
-  try {
-    new C();
-    print('v1');
-  } catch (e) {
-    print('v2');
-  }
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
+                ""
+            ],
             r"""
 main() {
   try {
@@ -875,29 +842,30 @@
   }
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that removing a class is supported, using a static method.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that removing a class is supported, using a static method.
+
+""",
+            const [
+                r"""
 class C {
   static m() {
     print('v1');
   }
 }
-
-main() {
-  try {
-    C.m();
-  } catch (e) {
-    print('v2');
-  }
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
+                "",
+            ],
             r"""
 main() {
   try {
@@ -907,13 +875,19 @@
   }
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that changing the supertype of a class.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that changing the supertype of a class.
+
 class A {
   m() {
     print('v2');
@@ -924,36 +898,16 @@
     print('v1');
   }
 }
+""",
+            const [
+                r"""
 class C extends B {
-  m() {
-    super.m();
-  }
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
-  instance.m();
-}
 """,
-            const <String>['instance is null', 'v1']),
-        const ProgramResult(
-            r"""
-class A {
-  m() {
-    print('v2');
-  }
-}
-class B extends A {
-  m() {
-    print('v1');
-  }
-}
+                r"""
 class C extends A {
+""",
+            ],
+            r"""
   m() {
     super.m();
   }
@@ -969,14 +923,28 @@
   instance.m();
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test adding a field to a class works.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test adding a field to a class works.
+
 class A {
+""",
+            const [
+                "",
+                r"""
+  var x;
+""",
+            ],
+            r"""
 }
 
 var instance;
@@ -998,41 +966,28 @@
   }
 }
 """,
-            const <String>['instance is null', 'setter threw', 'getter threw']),
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'setter threw', 'getter threw']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
             r"""
+// Test removing a field from a class works.
+
 class A {
-  var x;
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
-  }
-  try {
-    instance.x = 'v2';
-  } catch(e) {
-    print('setter threw');
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('getter threw');
-  }
-}
 """,
-            const <String>['v2']),
-    ],
-
-    // Test removing a field from a class works.
-    const <ProgramResult>[
-        const ProgramResult(
-            r"""
-class A {
+            const [
+                r"""
   var x;
+""",
+                "",
+            ],
+            r"""
 }
 
 var instance;
@@ -1054,38 +1009,19 @@
   }
 }
 """,
-            const <String>['instance is null', 'v1']),
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['setter threw', 'getter threw']),
+        ]),
+
+    const EncodedResult(
+        const [
             r"""
-class A {
-}
+// Test that named arguments can be called.
 
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new A();
-  }
-  try {
-    instance.x = 'v1';
-  } catch(e) {
-    print('setter threw');
-  }
-  try {
-    print(instance.x);
-  } catch (e) {
-    print('getter threw');
-  }
-}
-""",
-            const <String>['setter threw', 'getter threw']),
-    ],
-
-    // Test that named arguments can be called.
-    const <ProgramResult>[
-        const ProgramResult(
-            r"""
 class C {
   foo({a, named: 'v1', x}) {
     print(named);
@@ -1099,35 +1035,31 @@
     print('instance is null');
     instance = new C();
   }
+""",
+            const [
+                r"""
   instance.foo();
-}
 """,
-            const <String>['instance is null', 'v1']),
-        const ProgramResult(
-            r"""
-class C {
-  foo({a, named: 'v1', x}) {
-    print(named);
-  }
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
+                r"""
   instance.foo(named: 'v2');
+""",
+            ],
+            r"""
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test than named arguments can be called.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test than named arguments can be called.
+
 class C {
   foo({a, named: 'v2', x}) {
     print(named);
@@ -1141,35 +1073,31 @@
     print('instance is null');
     instance = new C();
   }
+""",
+            const [
+                r"""
   instance.foo(named: 'v1');
-}
 """,
-            const <String>['instance is null', 'v1']),
-        const ProgramResult(
-            r"""
-class C {
-  foo({a, named: 'v2', x}) {
-    print(named);
-  }
-}
-
-var instance;
-
-main() {
-  if (instance == null) {
-    print('instance is null');
-    instance = new C();
-  }
+                r"""
   instance.foo();
+""",
+            ],
+            r"""
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['instance is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that an instance tear-off with named parameters can be called.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that an instance tear-off with named parameters can be called.
+
 class C {
   foo({a, named: 'v1', x}) {
     print(named);
@@ -1183,57 +1111,41 @@
     print('closure is null');
     closure = new C().foo;
   }
+""",
+            const [
+                r"""
   closure();
-}
 """,
-            const <String>['closure is null', 'v1']),
-        const ProgramResult(
-            r"""
-class C {
-  foo({a, named: 'v1', x}) {
-    print(named);
-  }
-}
-
-var closure;
-
-main() {
-  if (closure == null) {
-    print('closure is null');
-    closure = new C().foo;
-  }
+                r"""
   closure(named: 'v2');
+""",
+            ],
+            r"""
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['closure is null', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-/*
-    // Test that a lazy static is supported.
-    // TODO(ahe): This test doesn't pass yet.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that a lazy static is supported.
+
 var normal;
 
+""",
+            const [
+                r"""
 foo() {
   print(normal);
 }
-
-main() {
-  if (normal == null) {
-    normal = 'v1';
-  } else {
-    normal = '';
-  }
-  foo();
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
-            r"""
-var normal;
-
+                r"""
 var lazy = bar();
 
 foo() {
@@ -1245,6 +1157,9 @@
   return 'lazy';
 }
 
+""",
+            ],
+            r"""
 main() {
   if (normal == null) {
     normal = 'v1';
@@ -1254,15 +1169,18 @@
   foo();
 }
 """,
-            const <String>['v2', 'lazy']),
-    ],
-*/
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2', 'lazy']),
+        ]),
 
-    // Test that superclasses of directly instantiated classes are also
-    // emitted.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that superclasses of directly instantiated classes are also emitted.
 class A {
 }
 
@@ -1270,46 +1188,467 @@
 }
 
 main() {
-  print('v1');
-}
 """,
-            const <String>['v1']),
-        const ProgramResult(
-            r"""
-class A {
-}
-
-class B extends A {
-}
-
-main() {
+            const [
+                r"""
+  print('v1');
+""",
+                r"""
   new B();
   print('v2');
+""",
+            ],
+            r"""
 }
 """,
-            const <String>['v2']),
-    ],
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
 
-    // Test that interceptor classes are handled correctly.
-    const <ProgramResult>[
-        const ProgramResult(
+    const EncodedResult(
+        const [
             r"""
+// Test that interceptor classes are handled correctly.
+
 main() {
-  // TODO(ahe): Remove next line when new constants are handled correctly.
-  [].map(null);
+""",
+            const [
+                r"""
   print('v1');
+""",
+                r"""
+  ['v2'].forEach(print);
+""",
+            ],
+            r"""
 }
 """,
-            const <String>['v1']),
-        const ProgramResult(
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test that newly instantiated superclasses are handled correctly when there
+// is more than one change.
+
+class A {
+  foo() {
+    print('Called foo');
+  }
+
+  bar() {
+    print('Called bar');
+  }
+}
+
+class B extends A {
+}
+
+main() {
+""",
+            const [
+                r"""
+  new B().foo();
+""",
+                r"""
+  new B().foo();
+""",
+            r"""
+  new A().bar();
+""",
+            ],
+            r"""
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['Called foo']),
+            const ProgramExpectation(
+                const <String>['Called foo']),
+            const ProgramExpectation(
+                const <String>['Called bar']),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test that newly instantiated subclasses are handled correctly when there is
+// more than one change.
+
+class A {
+  foo() {
+    print('Called foo');
+  }
+
+  bar() {
+    print('Called bar');
+  }
+}
+
+class B extends A {
+}
+
+main() {
+""",
+            const [
+                r"""
+  new A().foo();
+""",
+                r"""
+  new A().foo();
+""",
+            r"""
+  new B().bar();
+""",
+            ],
+            r"""
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['Called foo']),
+            const ProgramExpectation(
+                const <String>['Called foo']),
+            const ProgramExpectation(
+                const <String>['Called bar']),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test that constants are handled correctly.
+
+class C {
+  final String value;
+  const C(this.value);
+}
+
+main() {
+""",
+            const [
+                r"""
+  print(const C('v1').value);
+""",
+                r"""
+  print(const C('v2').value);
+""",
+            ],
+            r"""
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['v1']),
+            const ProgramExpectation(
+                const <String>['v2']),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test that an instance field can be added to a compound declaration.
+
+class C {
+""",
+            const [
+                r"""
+  int x;
+""",
+                r"""
+  int x, y;
+""",
+            ],
+                r"""
+}
+
+var instance;
+
+main() {
+  if (instance == null) {
+    print('[instance] is null');
+    instance = new C();
+    instance.x = 'v1';
+  } else {
+    instance.y = 'v2';
+  }
+  try {
+    print(instance.x);
+  } catch (e) {
+    print('[instance.x] threw');
+  }
+  try {
+    print(instance.y);
+  } catch (e) {
+    print('[instance.y] threw');
+  }
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>[
+                    '[instance] is null', 'v1', '[instance.y] threw']),
+            const ProgramExpectation(
+                const <String>['v1', 'v2'],
+                // TODO(ahe): Shouldn't throw.
+                compileUpdatesShouldThrow: true),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test that an instance field can be removed from a compound declaration.
+
+class C {
+""",
+            const [
+                r"""
+  int x, y;
+""",
+                r"""
+  int x;
+""",
+            ],
+                r"""
+}
+
+var instance;
+
+main() {
+  if (instance == null) {
+    print('[instance] is null');
+    instance = new C();
+    instance.x = 'v1';
+    instance.y = 'v2';
+  }
+  try {
+    print(instance.x);
+  } catch (e) {
+    print('[instance.x] threw');
+  }
+  try {
+    print(instance.y);
+  } catch (e) {
+    print('[instance.y] threw');
+  }
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['[instance] is null', 'v1', 'v2']),
+            const ProgramExpectation(
+                const <String>['v1', '[instance.y] threw'],
+                // TODO(ahe): Shouldn't throw.
+                compileUpdatesShouldThrow: true),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test that a static field can be made an instance field.
+
+class C {
+""",
+
+            const [
+                r"""
+  static int x;
+""",
+                r"""
+  int x;
+""",
+            ],
+                r"""
+}
+
+var instance;
+
+main() {
+  if (instance == null) {
+    print('[instance] is null');
+    instance = new C();
+    C.x = 'v1';
+  } else {
+    instance.x = 'v2';
+  }
+  try {
+    print(C.x);
+  } catch (e) {
+    print('[C.x] threw');
+  }
+  try {
+    print(instance.x);
+  } catch (e) {
+    print('[instance.x] threw');
+  }
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['[instance] is null', 'v1', '[instance.x] threw']),
+            const ProgramExpectation(
+                const <String>['[C.x] threw', 'v2'],
+                // TODO(ahe): Shouldn't throw.
+                compileUpdatesShouldThrow: true),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test that instance field can be made static.
+
+class C {
+""",
+            const [
+                r"""
+  int x;
+""",
+                r"""
+  static int x;
+""",
+            ],
+            r"""
+}
+
+var instance;
+
+main() {
+  if (instance == null) {
+    print('[instance] is null');
+    instance = new C();
+    instance.x = 'v1';
+  } else {
+    C.x = 'v2';
+  }
+  try {
+    print(C.x);
+  } catch (e) {
+    print('[C.x] threw');
+  }
+  try {
+    print(instance.x);
+  } catch (e) {
+    print('[instance.x] threw');
+  }
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['[instance] is null', '[C.x] threw', 'v1']),
+            const ProgramExpectation(
+                const <String>['v2', '[instance.x] threw'],
+                // TODO(ahe): Shouldn't throw.
+                compileUpdatesShouldThrow: true),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test compound constants.
+
+class A {
+  final value;
+  const A(this.value);
+
+  toString() => 'A($value)';
+}
+
+class B {
+  final value;
+  const B(this.value);
+
+  toString() => 'B($value)';
+}
+
+main() {
+""",
+            const [
+                r"""
+  print(const A('v1'));
+  print(const B('v1'));
+""",
+                r"""
+  print(const B(const A('v2')));
+  print(const A(const B('v2')));
+""",
+            ],
+            r"""
+}
+""",
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['A(v1)', 'B(v1)']),
+            const ProgramExpectation(
+                const <String>['B(A(v2))', 'A(B(v2))']),
+        ]),
+
+    const EncodedResult(
+        const [
+            r"""
+// Test constants of new classes.
+
+class A {
+  final value;
+  const A(this.value);
+
+  toString() => 'A($value)';
+}
+""",
+            const [
+                "",
+                r"""
+class B {
+  final value;
+  const B(this.value);
+
+  toString() => 'B($value)';
+}
+
+""",
+            ],
             r"""
 main() {
-  // TODO(ahe): Use forEach(print) when closures are computed correctly.
-  ['v2'].forEach((e) { print(e); });
+""",
+
+            const [
+                r"""
+  print(const A('v1'));
+""",
+                r"""
+  print(const A('v2'));
+  print(const B('v2'));
+  print(const B(const A('v2')));
+  print(const A(const B('v2')));
+""",
+            ],
+            r"""
 }
 """,
-            const <String>['v2']),
-    ],
+
+        ],
+        const <ProgramExpectation>[
+            const ProgramExpectation(
+                const <String>['A(v1)']),
+            const ProgramExpectation(
+                const <String>['A(v2)', 'B(v2)', 'B(A(v2))', 'A(B(v2))']),
+        ]),
 ];
 
 void main() {
@@ -1317,22 +1656,42 @@
 
   document.head.append(lineNumberStyle());
 
+  summary = new SpanElement();
+  document.body.append(new HeadingElement.h1()
+      ..appendText("Incremental compiler tests")
+      ..append(summary));
+
   String query = window.location.search;
   int skip = 0;
   if (query != null && query.length > 1) {
     query = query.substring(1);
-    String skipParam = Uri.splitQueryString(window.location.search)['skip'];
-    if (skipParam != null) {
-      skip = int.parse(skipParam);
+    String skipParameter = Uri.splitQueryString(window.location.search)['skip'];
+    if (skipParameter != null) {
+      skip = int.parse(skipParameter);
     }
+    String verboseParameter =
+        Uri.splitQueryString(window.location.search)['verbose'];
+    verboseStatus = verboseParameter != null;
   }
+  testCount += skip;
 
-  return asyncTest(() => Future.forEach(tests.skip(skip), compileAndRun));
+  return asyncTest(() => Future.forEach(tests.skip(skip), compileAndRun)
+      .then(updateSummary));
 }
 
+SpanElement summary;
+
 int testCount = 1;
 
-Future compileAndRun(List<ProgramResult> programs) {
+bool verboseStatus = false;
+
+void updateSummary(_) {
+  summary.text = " (${testCount - 1}/${tests.length})";
+}
+
+Future compileAndRun(EncodedResult encodedResult) {
+  updateSummary(null);
+  List<ProgramResult> programs = encodedResult.decode();
   var status = new DivElement();
   document.body.append(status);
 
@@ -1374,7 +1733,24 @@
           inputProvider.cachedSources[uri] = new Future.value(program.code);
           Future future = test.incrementalCompiler.compileUpdates(
               {test.scriptUri: uri}, logVerbose: logger, logTime: logger);
+          future = future.catchError((error, trace) {
+            String statusMessage;
+            Future result;
+            if (program.compileUpdatesShouldThrow) {
+              statusMessage = "Expected error in compileUpdates.";
+              result = null;
+            } else {
+              statusMessage = "Unexpected error in compileUpdates.";
+              result = new Future.error(error, trace);
+            }
+            status.append(new HeadingElement.h3()..appendText(statusMessage));
+            return result;
+          });
           return future.then((String update) {
+            if (program.compileUpdatesShouldThrow) {
+              Expect.isNull(update);
+              return null;
+            }
             print({'update': update});
             iframe.contentWindow.postMessage(['apply-update', update], '*');
 
@@ -1394,7 +1770,7 @@
 
     // Remove the iframe and status to work around a bug in test.dart
     // (https://code.google.com/p/dart/issues/detail?id=21691).
-    status.remove();
+    if (!verboseStatus) status.remove();
     iframe.remove();
   });
 }
@@ -1463,10 +1839,9 @@
   return result;
 }
 
-
 StyleElement lineNumberStyle() {
   StyleElement style = new StyleElement()..appendText('''
-h2 {
+h2, h3 {
   color: black;
 }
 
diff --git a/tests/try/web/program_result.dart b/tests/try/web/program_result.dart
index 3ac4400..2bd3100 100644
--- a/tests/try/web/program_result.dart
+++ b/tests/try/web/program_result.dart
@@ -4,14 +4,58 @@
 
 library trydart.test.program_result;
 
+import '../poi/source_update.dart';
+
 class ProgramResult {
   final String code;
 
   final List<String> messages;
 
-  const ProgramResult(this.code, this.messages);
+  final bool compileUpdatesShouldThrow;
+
+  const ProgramResult(
+      this.code, this.messages, {this.compileUpdatesShouldThrow: false});
 
   List<String> messagesWith(String extra) {
     return new List<String>.from(messages)..add(extra);
   }
 }
+
+class ProgramExpectation {
+  final List<String> messages;
+
+  final bool compileUpdatesShouldThrow;
+
+  const ProgramExpectation(
+      this.messages, {this.compileUpdatesShouldThrow: false});
+
+  ProgramResult toResult(String code) {
+    return new ProgramResult(
+        code, messages, compileUpdatesShouldThrow: compileUpdatesShouldThrow);
+  }
+}
+
+class EncodedResult {
+  final List updates;
+
+  final List<ProgramExpectation> expectations;
+
+  const EncodedResult(this.updates, this.expectations);
+
+  List<ProgramResult> decode() {
+    if (updates.length == 1) {
+      throw new StateError("Trivial diff, no reason to use decode.");
+    }
+    List<String> sources = expandUpdates(updates);
+    if (sources.length != expectations.length) {
+      throw new StateError(
+          "Number of sources and expectations differ "
+          "(${sources.length} sources, ${expectations.length} expectations).");
+    }
+    List<ProgramResult> result = new List<ProgramResult>(sources.length);
+    for (int i = 0; i < sources.length; i++) {
+      result[i] = expectations[i].toResult(sources[i]);
+    }
+    return result;
+  }
+}
diff --git a/tools/VERSION b/tools/VERSION
index ff84985..75026b0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 9
 PATCH 0
-PRERELEASE 1
+PRERELEASE 2
 PRERELEASE_PATCH 0
diff --git a/tools/apps/update_homebrew/bin/update_homebrew.dart b/tools/apps/update_homebrew/bin/update_homebrew.dart
index 28b82cb..17d6e62 100644
--- a/tools/apps/update_homebrew/bin/update_homebrew.dart
+++ b/tools/apps/update_homebrew/bin/update_homebrew.dart
@@ -19,7 +19,8 @@
 
 final SDK_FILES = ['sdk/dartsdk-macos-x64-release.zip',
                    'sdk/dartsdk-macos-ia32-release.zip' ];
-final DARTIUM_FILES = ['dartium/dartium-macos-ia32-release.zip' ];
+final DARTIUM_FILES = ['dartium/dartium-macos-ia32-release.zip',
+                       'dartium/content_shell-macos-ia32-release.zip'];
 final FILES = []..addAll(SDK_FILES)..addAll(DARTIUM_FILES);
 
 
@@ -106,6 +107,7 @@
                    String stableVersion) {
   final urlBase = 'https://storage.googleapis.com/dart-archive/channels';
   final dartiumFile = 'dartium/dartium-macos-ia32-release.zip';
+  final contentShellFile = 'dartium/content_shell-macos-ia32-release.zip';
 
   return '''
 require 'formula'
@@ -121,18 +123,35 @@
     version '$devVersion'
     url '$urlBase/dev/release/${revisions['dev']}/$dartiumFile'
     sha256 '${hashes['dev'][dartiumFile]}'
+
+    resource 'content_shell' do
+      url '$urlBase/dev/release/${revisions['dev']}/$contentShellFile'
+      version '$devVersion'
+      sha256 '${hashes['dev'][contentShellFile]}'
+    end
+  end
+
+  resource 'content_shell' do
+    url '$urlBase/stable/release/${revisions['stable']}/$contentShellFile'
+    version '$stableVersion'
+    sha256 '${hashes['stable'][contentShellFile]}'
   end
 
   def shim_script target
     <<-EOS.undent
       #!/bin/bash
-      open "#{prefix}/#{target}" "\$@"
+      "#{prefix}/#{target}" "\$@"
     EOS
   end
 
   def install
+    dartium_binary = 'Chromium.app/Contents/MacOS/Chromium'
     prefix.install Dir['*']
-    (bin+"dartium").write shim_script "Chromium.app"
+    (bin+"dartium").write shim_script dartium_binary
+
+    content_shell_binary = 'Content Shell.app/Contents/MacOS/Content Shell'
+    prefix.install resource('content_shell')
+    (bin+"content_shell").write shim_script content_shell_binary
   end
 
   def caveats; <<-EOS.undent
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 04f51e1..0fe41b0 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -253,19 +253,17 @@
 $!STREAM_GETTER_SIGNATURES
 }
 
-// TODO(jacobr): this is an inefficient implementation but it is hard to see
-// a better option given that we cannot quite force NodeList to be an
-// ElementList as there are valid cases where a NodeList JavaScript object
-// contains Node objects that are not Elements.
-class _FrozenElementList<T extends Element> extends ListBase<T>
-    implements ElementList<T>, NodeListWrapper {
+// Wrapper over an immutable NodeList to make it implement ElementList.
+//
+// Clients are {`Document`, `DocumentFragment`}.`querySelectorAll` which are
+// declared to return `ElementList`.  This provides all the static analysis
+// benefit so there is no need for this class have a constrained type parameter.
+//
+class _FrozenElementList extends ListBase
+    implements ElementList, NodeListWrapper {
   final List<Node> _nodeList;
-  // The subset of _nodeList that are Elements.
-  List<Element> _elementList;
 
-  _FrozenElementList._wrap(this._nodeList) {
-    _elementList = _nodeList.where((e) => e is Element).toList();
-  }
+  _FrozenElementList._wrap(this._nodeList);
 
   int get length => _nodeList.length;
 
@@ -293,22 +291,22 @@
 
   Element get single => _nodeList.single;
 
-  CssClassSet get classes => new _MultiElementCssClassSet(_elementList);
+  CssClassSet get classes => new _MultiElementCssClassSet(this);
 
   CssStyleDeclarationBase get style =>
-      new _CssStyleDeclarationSet(_elementList);
+      new _CssStyleDeclarationSet(this);
 
   void set classes(Iterable<String> value) {
-    _elementList.forEach((e) => e.classes = value);
+    _nodeList.forEach((e) => e.classes = value);
   }
 
-  CssRect get contentEdge => new _ContentCssListRect(_elementList);
+  CssRect get contentEdge => new _ContentCssListRect(this);
 
-  CssRect get paddingEdge => _elementList.first.paddingEdge;
+  CssRect get paddingEdge => this.first.paddingEdge;
 
-  CssRect get borderEdge => _elementList.first.borderEdge;
+  CssRect get borderEdge => this.first.borderEdge;
 
-  CssRect get marginEdge => _elementList.first.marginEdge;
+  CssRect get marginEdge => this.first.marginEdge;
 
   List<Node> get rawList => _nodeList;
 
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index e1652ff8..68013f6 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -293,6 +293,8 @@
                 url];
     return parts.map(escapeCommandLineArgument).join(' ');
   }
+
+  int get maxNumRetries => 4;
 }
 
 class BrowserHtmlTestCommand extends BrowserTestCommand {